Commit graph

133 commits

Author SHA1 Message Date
Chad Karaginides f8b9faff24 arch: arm64: Added ISBs after SCTLR Modifications
Per the ARMv8 architecture document, modification of the system control
register is a context-changing operation. Context-changing operations are
only guaranteed to be seen after a context synchronization event.
An ISB is a context synchronization event.  One has been placed after
each SCTLR modification. Issue was found running full speed on target.

Signed-off-by: Chad Karaginides <quic_chadk@quicinc.com>
2023-05-25 16:33:03 -04:00
Nicolas Pitre 8e9872a7c8 arm64: prevent possible deadlock on SMP with FPU sharing
Let's consider CPU1 waiting on a spinlock already taken by CPU2.

It is possible for CPU2 to invoke the FPU and trigger an FPU exception
when the FPU context for CPU2 is not live on that CPU. If the FPU context
for the thread on CPU2 is still held in CPU1's FPU then an IPI is sent
to CPU1 asking to flush its FPU to memory.

But if CPU1 is spinning on a lock already taken by CPU2, it won't see
the pending IPI as IRQs are disabled. CPU2 won't get its FPU state
restored and won't complete the required work to release the lock.

Let's prevent this deadlock scenario by looking for pending FPU IPI from
the spinlock loop using the arch_spin_relax() hook.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-05-25 08:25:11 +00:00
Carlo Caione 6f3a13d974 barriers: Move __ISB() to the new API
Remove the arch-specific ARM-centric __ISB() macro and use the new
barrier API instead.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-05-24 13:13:57 -04:00
Carlo Caione cb11b2e84b barriers: Move __DSB() to the new API
Remove the arch-specific ARM-centric __DSB() macro and use the new
barrier API instead.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-05-24 13:13:57 -04:00
Carlo Caione 2fa807bcd1 barriers: Move __DMB() to the new API
Remove the arch-specific ARM-centric __DMB() macro and use the new
barrier API instead.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-05-24 13:13:57 -04:00
Carlo Caione c2ec3d49cd arm64: cache: Enable full inlining of the cache ops
Move all the cache functions to a standalone header to allow for the
inlining of these functions.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-04-20 14:56:09 -04:00
Peter Mitsis 1e250b37df arch: arm64: Remove unused absolute symbols
Removes ARM64 specific unused absolute symbols that are defined
via the GEN_ABSOLUTE_SYM() macro.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
2023-04-18 10:51:28 -04:00
Gerard Marull-Paretas a5fd0d184a init: remove the need for a dummy device pointer in SYS_INIT functions
The init infrastructure, found in `init.h`, is currently used by:

- `SYS_INIT`: to call functions before `main`
- `DEVICE_*`: to initialize devices

They are all sorted according to an initialization level + a priority.
`SYS_INIT` calls are really orthogonal to devices, however, the required
function signature requires a `const struct device *dev` as a first
argument. The only reason for that is because the same init machinery is
used by devices, so we have something like:

```c
struct init_entry {
	int (*init)(const struct device *dev);
	/* only set by DEVICE_*, otherwise NULL */
	const struct device *dev;
}
```

As a result, we end up with such weird/ugly pattern:

```c
static int my_init(const struct device *dev)
{
	/* always NULL! add ARG_UNUSED to avoid compiler warning */
	ARG_UNUSED(dev);
	...
}
```

This is really a result of poor internals isolation. This patch proposes
a to make init entries more flexible so that they can accept sytem
initialization calls like this:

```c
static int my_init(void)
{
	...
}
```

This is achieved using a union:

```c
union init_function {
	/* for SYS_INIT, used when init_entry.dev == NULL */
	int (*sys)(void);
	/* for DEVICE*, used when init_entry.dev != NULL */
	int (*dev)(const struct device *dev);
};

struct init_entry {
	/* stores init function (either for SYS_INIT or DEVICE*)
	union init_function init_fn;
	/* stores device pointer for DEVICE*, NULL for SYS_INIT. Allows
	 * to know which union entry to call.
	 */
	const struct device *dev;
}
```

This solution **does not increase ROM usage**, and allows to offer clean
public APIs for both SYS_INIT and DEVICE*. Note that however, init
machinery keeps a coupling with devices.

**NOTE**: This is a breaking change! All `SYS_INIT` functions will need
to be converted to the new signature. See the script offered in the
following commit.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

init: convert SYS_INIT functions to the new signature

Conversion scripted using scripts/utils/migrate_sys_init.py.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

manifest: update projects for SYS_INIT changes

Update modules with updated SYS_INIT calls:

- hal_ti
- lvgl
- sof
- TraceRecorderSource

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

tests: devicetree: devices: adjust test

Adjust test according to the recently introduced SYS_INIT
infrastructure.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

tests: kernel: threads: adjust SYS_INIT call

Adjust to the new signature: int (*init_fn)(void);

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2023-04-12 14:28:07 +00:00
Jaxson Han e416c5f1bd arch: arm64: Update current stack limit on every context switch
Update current stack limit on every context switch, including switching
to irq stack and switching back to thread stack.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Jaxson Han 00adc0b493 arch: arm64: Enable safe exception stack
This commit mainly enable the safe exception stack including the stack
switch. Init the safe exception stack by calling
z_arm64_safe_exception_stack during the boot stage on every core. Also,
tweaks several files to properly switch the mode with different cases.

1) The same as before, when executing in userspace, SP_EL0 holds the
user stack and SP_EL1 holds the privileged stack, using EL1h mode.

2) When entering exception from EL0 then SP_EL0 will be saved in the
_esf_t structure. SP_EL1 will be the current SP, then retrieves the safe
exception stack to SP_EL0, making sure the always pointing to safe
exception stack as long as the system running in kernel space.

3) When exiting exception from EL1 to EL0 then SP_EL0 will be restored
from the stack value previously saved in the _esf_t structure. Still at
EL1h mode.

4) Either entering or exiting exception from EL1 to EL1, SP_EL0 will
keep holding the safe exception stack unchanged as memtioned above.

5) Do a quick stack check every time entering the exception from EL1 to
EL1. If check fail, set SP_EL1 to safe exception stack, and then handle
the fatal error.

Overall, the exception from user mode will be handled with kernel stack
at the assumption that it is impossible the stackoverflow happens at the
entry of exception from EL0 to EL1. However the exception from kernel
mode will be firstly checked with the safe exception stack to see if the
kernel stack overflows, because the exception might be triggered by
stack invalid accessing.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Jaxson Han 463b1c9396 arch: arm64: Add safe exception stack init function
Add safe exception stack init function which does several things:
1) setting current cpu safe exception stack pointer to its corresponding
stack top.
2) init sp_el0 with the above safe exception stack.
That makes sure the sp_el0 points to per-cpu safe_stack in the kernel
space.
3) init the current_stack_limit and corrupted_sp with 0

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Jaxson Han 3a5fa0498f arch: arm64: Add stack_limit to thread_arch_t
Add stack_limit to thread_arch_t to store the thread's stack limit.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Jaxson Han 61b8b34b27 arch: arm64: Add the sp variable in _esf_t
As the preparation for enabling safe exception stack, add a variable in
_esf_t to save the user stack held by sp_el0 at the point of the
exception happening from EL0. The newly added variable in _esf_t is
named sp from which the user stack will be restored when exceptions eret
to EL0.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Jaxson Han 7040c55438 arch: arm64: Add stack check relevant variables to _cpu_arch_t
Add three per-cpu variables for the convenience of quickly accessing.

The safe_exception_stack stores the top of safe exception stack pointer.
The current_stack_limit stores the current thread's priv stack limit.
The corrputed_sp stores the priv sp or irq sp for the stack overflow
case, or 0 for the normal case.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Jaxson Han d8d74b1320 arch: arm64: Add el label for vector entry macro
Add a new label el for z_arm64_enter_exc to indicate which el the
exception comes from.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Jaxson Han 6c40abb99f arch: arm64: Introduce safe exception stack
Introduce two configs to prepare to enable the safe exception stack for
the kernel space. This is the preparation for enabling hardware stack
guard. Also define the safe exception stack for kernel exception stack
check.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2023-03-14 10:49:22 +01:00
Nicolas Pitre bcef633316 arch/arm64/mmu: arch_mem_map() should not overwrite existing mappings
If so this is most certainly a bug. arch_mem_unmap() should be
used before mapping the same area again.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-03-13 09:15:37 +01:00
Nicolas Pitre 364d7527c1 arch/arm64/mmu: minor addition to debugging code
Display table allocations and whether or not mappings
can be overwritten.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-03-13 09:15:37 +01:00
Nicolas Pitre abb50e1605 arch/arm64/mmu: fix table discarding code
First, we have commit 7d27bd0b85 ("arch: arm64: Disable infinite
recursion warning for `discard_table`") that blindly shut up a compiler
warning that did actually highlighted a real bug. Revert that and fix
the bug properly. And yes, mea culpa for having been the first to
approve that commit, or even creating the bug in the first place.

Then let's add proper table usage cound handling for discard_table() to
work properly and avoid leaking table pages.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-03-07 08:33:05 +01:00
Henri Xavier 45af717a66 arch/arm64: Implement ASID support in ARM64 MMU
Improves context-switch performance.

TLB invalidation and the nG bit are used conservatively. This could
be improved in future work.

Tested with tests/benchmarks/sched_userspace:

BEFORE:
```
Swapping  2 threads: 161562583 cyc & 1000000 rounds ->   1615 ns per ctx
Swapping  8 threads: 161569289 cyc & 1000000 rounds ->   1615 ns per ctx
Swapping 16 threads: 161649163 cyc & 1000000 rounds ->   1616 ns per ctx
Swapping 32 threads: 163487880 cyc & 1000000 rounds ->   1634 ns per ctx
```

AFTER:
```
Swapping  2 threads: 18129207 cyc & 1000000 rounds ->    181 ns per ctx
Swapping  8 threads: 49702891 cyc & 1000000 rounds ->    497 ns per ctx
Swapping 16 threads: 55898650 cyc & 1000000 rounds ->    558 ns per ctx
Swapping 32 threads: 58059704 cyc & 1000000 rounds ->    580 ns per ctx
```

Signed-off-by: Henri Xavier <datacomos@huawei.com>
2022-12-13 17:21:11 +09:00
Carlo Caione 385f06e6a1 arm64: cache: Rework cache API
And use the new API.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-12-01 13:40:56 -05:00
Carlo Caione 189cd1f4a2 cache: Rework cache API
The cache operations must be quick, optimized and possibly inlined. The
current API is clunky, functions are not inlined and passing parameters
around that are basically always known at compile time.

In this patch we rework the cache functions to allow us to get rid of
useless parameters and make inlining easier.

In particular this changeset is doing three things:

1. `CONFIG_HAS_ARCH_CACHE` is now `CONFIG_ARCH_CACHE` and
   `CONFIG_HAS_EXTERNAL_CACHE` is now `CONFIG_EXTERNAL_CACHE`

2. The cache API has been reworked.

3. Comments are added.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-12-01 13:40:56 -05:00
Henri Xavier b54ba9877f arm64: implement arch_system_halt
When PSCI is enabled, implement `arch_system_halt` using
PSCI_SHUTDOWN.

Signed-off-by: Henri Xavier <datacomos@huawei.com>
2022-11-23 11:37:08 +01:00
Henri Xavier 55df3852bf arm64: Add comment that arch_curr_cpu and get_cpu must be synced
The is code duplication as one is in C, and the other is an assembly
macro. As there is no easy way to find out about this duplication,
adding a comment seems the best way to go.

Signed-off-by: Henri Xavier <datacomos@huawei.com>
2022-11-02 16:08:00 -05:00
Kumar Gala d60c62e457 arch: arm64: Convert to CONFIG_MP_MAX_NUM_CPUS
Convert CONFIG_MP_NUM_CPUS to CONFIG_MP_MAX_NUM_CPUS as we work on
phasing out CONFIG_MP_NUM_CPUS.

Signed-off-by: Kumar Gala <kumar.gala@intel.com>
2022-10-25 10:52:34 +02:00
Kumar Gala a1195ae39b smp: Move for loops to use arch_num_cpus instead of CONFIG_MP_NUM_CPUS
Change for loops of the form:

for (i = 0; i < CONFIG_MP_NUM_CPUS; i++)
   ...

to

unsigned int num_cpus = arch_num_cpus();
for (i = 0; i < num_cpus; i++)
   ...

We do the call outside of the for loop so that it only happens once,
rather than on every iteration.

Signed-off-by: Kumar Gala <kumar.gala@intel.com>
2022-10-21 13:14:58 +02:00
Kumar Gala fc95ec98dd smp: Convert #if to use CONFIG_MP_MAX_NUM_CPUS
Convert CONFIG_MP_NUM_CPUS to CONFIG_MP_MAX_NUM_CPUS as we work on
phasing out CONFIG_MP_NUM_CPUS.

Signed-off-by: Kumar Gala <kumar.gala@intel.com>
2022-10-20 22:04:10 +09:00
Gerard Marull-Paretas 178bdc4afc include: add missing zephyr/irq.h include
Change automated searching for files using "IRQ_CONNECT()" API not
including <zephyr/irq.h>.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-10-17 22:57:39 +09:00
Stephanos Ioannidis 2689590e67 arch: arm64: Disable ldp/stp Qn for consecutive 32-byte loads/stores
GCC may generate ldp/stp instructions with the Advanced SIMD Qn
registers for consecutive 32-byte loads and stores.

This commit disables this GCC behaviour because saving and restoring
the Advanced SIMD context is very expensive, and it is preferable to
keep it turned off by not emitting these instructions for better
context switching performance.

Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
2022-09-23 12:10:25 +02:00
Huifeng Zhang 3d81d7f23f arch: arm64: fix the wrong way to send ipi interrupt
On GICv3, when we send an IPI interrupt, aff3, aff2 and aff1 should
be assigned a value corespond to a PE for which interrupt will be
generated. target_list only corresponds to aff0.

On real hardware, aff3, aff2, aff1 and aff0 should be treated as a
whole to determine a PE.

Signed-off-by: Huifeng Zhang <Huifeng.Zhang@arm.com>
2022-09-09 16:36:37 +00:00
Huifeng Zhang 3ef14cae5e arch: arm64: init VMPIDR_EL2 in z_arm64_el2_init
VMPIDR_EL2 is assigned the value returned by EL2 reads of MPIDR_EL1

MPIDR_EL1 is the register holding the Multiprocessor ID which is to
identify different cores. Because of the virtualization requirements
for AArch64, MPIDR_EL1 should be virtualized (the different virtualized
cores can run on the same physical core). Thus the value of MPIDR_EL1
should be switched when the VM is switched. Setting the VMPIDR_EL2 is
the way to change the value returned by EL1 reads of MPIDR_EL1. Even
without virtualization, we still need to set VMPIDR_EL2 during booting
at EL2 or EL3. Otherwise, all cores' IDs are zero at the EL1 stage
which will break the SMP system.

Signed-off-by: Huifeng Zhang <Huifeng.Zhang@arm.com>
2022-09-09 16:36:37 +00:00
Gerard Marull-Paretas 5954ea1c65 arch: arm64: core: smp: use DT_FOREACH_CHILD_STATUS_OKAY_SEP
Avoid auxiliary macros by using DT_FOREACH_CHILD_STATUS_OKAY_SEP.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-08-30 16:19:57 +02:00
Carlo Caione 4806e1087e cache: Fix cache API calling from userspace
When a cache API function is called from userspace, this results on
ARM64 in an OOPS (bad syscall error). This is due to at least two
different factors:

- the location of the cache handlers is preventing the linker to
  actually find the handlers
- specifically for ARM64 and ARC some cache handling functions are not
  implemented (when userspace is not used the compiler simply optimizes
  out these calls)

Fix the problem by:

- moving the userspace cache handlers to a their logical and proper
  location (in the drivers directory)
- adding the missing handlers for ARM64 and ARC

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-08-23 10:14:17 +02:00
Carlo Caione 31d65d63f6 arch: arm64: Fix cache-related Kconfig symbols
Switch to the new cache-related Kconfig symbols.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-08-18 11:30:49 +00:00
Fabio Baltieri 55b243e124 test,arch: fix few odd suffix include paths
Fix some more legacy include paths found in files with unusual suffixes.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
2022-07-18 14:44:47 -04:00
Jamie Iles dbc6f6a882 arch: arm64: initialize IRQ stack for CONFIG_INIT_STACKS
When CONFIG_INIT_STACKS is enabled all stacks should be filled with 0xaa
so that the thread analyzer can measure stack utilization, but the IRQ
stack was not filled and so `kernel stacks` on the shell would show that
the stack had been fully used and inferring an IRQ stack overflow
regardless of the IRQ stack size.

Fill the IRQ stack before it gets used so that we can have precise usage
reports.

Signed-off-by: Jamie Iles <quic_jiles@quicinc.com>
Signed-off-by: Dave Aldridge <quic_daldridg@quicinc.com>
2022-07-08 19:59:24 +00:00
Anas Nashif 516625ed6a arch: arm64: add mising braces to single line if statements
Following zephyr's style guideline, all if statements, including single
line statements shall have braces.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2022-07-06 11:00:45 -04:00
Keith Packard f2ae48e621 arch/arm64: Enable 'large' code model for large targets
Targets with text or data addresses above the 4GB boundary may need to use
the large code model to ensure relocations in the linker work correctly.

Signed-off-by: Keith Packard <keithp@keithp.com>
2022-07-04 15:42:53 +00:00
Eugene Cohen d903333422 arch: arm64: enable single thread support config
Enable single-threaded support for the arm64 archtecture.

This mode of execution is supported on an soc under
development and is validated regularly.

Signed-off-by: Eugene Cohen <quic_egmc@quicinc.com>
2022-06-29 10:27:55 +02:00
Eugene Cohen 1f93ece43d arch: arm64: program TG[1] in mmu init
In performing a double check of Zephyr arm64 MMU config
against edk2, a different in the programming of the
Translation Control Register (TCR) was found.  TCR.TG[1]
should be set to address Cortex-A57 erratum 822227:

"Using unsupported 16K translation granules might cause
Cortex-A57 to incorrectly trigger a domain fault"

Signed-off-by: Eugene Cohen <quic_egmc@quicinc.com>
2022-06-29 10:27:33 +02:00
Eugene Cohen b84ab912af arch: arm64: define A55 core
Define a CPU_CORTEX_A55 configuration and align the gcc
cpu type accordingly when selected.

Signed-off-by: Eugene Cohen <quic_egmc@quicinc.com>
2022-06-29 10:27:19 +02:00
Eugene Cohen 434e748cbb arch: arm64: add WAIT_AT_RESET_VECTOR config
On platforms where reset vector catch is not possible
it is useful to have a compile-time option to spin
at the reset vector allowing a debugger to be attached
and then to manually resume execution.

Define a config option for arm64 to spin at the
reset vectdor so a debugger can be attached.

Signed-off-by: Eugene Cohen <quic_egmc@quicinc.com>
2022-06-28 12:29:17 +02:00
Stephanos Ioannidis 7d27bd0b85 arch: arm64: Disable infinite recursion warning for discard_table
This commit selectively disables the infinite recursion warning
(`-Winfinite-recursion`), which may be reported by GCC 12 and above,
for the `disable_table` function because no actual infinite recursion
will occur under normal circumstances.

Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
2022-06-16 16:02:23 -04:00
Carlo Caione 4d7d784d1e arm64: mmu: Support userspace memory mapping
arch_mem_map() on ARM64 is currently not supporting the K_MEM_PERM_USER
parameter so we cannot allocate userspace accessible memory using the
memory helpers. Fix this.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-06-10 09:48:23 +02:00
Gerard Marull-Paretas 96397b021e arch: arm64: smp: remove redundant soc.h include
<soc.h> has been traditionally been used as a proxy to HAL headers,
register definitions, etc. Nowadays, <soc.h> is anarchy. It serves a
different purpose depending on the SoC. In some cases it includes HALs,
in some others it works as a header sink/proxy (for no good reason), as
a register definition when there's no HAL... To make things worse, it is
being included in code that is, in theory, non-SoC specific.

This patch is part of a series intended to improve the situation by
removing <soc.h> usage when not needed, and by eventually removing it.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-06-05 14:48:40 +02:00
Gerard Marull-Paretas f465bd22c9 arch: arm64: mpu: remove unnecessary include
<soc.h> was not required.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-06-05 14:48:40 +02:00
Jaxson Han 04caf70bfe arm64: smp: Fix the wrong secondary core stack size
The init stack of the secondary core should use KERNEL_STACK_BUFFER + sz
Using Z_THREAD_STACK_BUFFER will calculate the wrong stack size.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2022-05-17 11:45:16 +09:00
Jaxson Han 933a8f9d12 arch: arm64: Fix coherence issue of SMP boot code
The current SMP boot code doesn't consider that the cores can boot at
the same time. Possibly, more than one core can boot into primary core
boot sequence. Fix it by using the atomic operation to make sure only
one core act as the primary core.

Correspondingly, sgi_raise_ipi should transfer CPU id to mpidr.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2022-05-17 11:45:16 +09:00
Jaxson Han 2f6087ba67 arch: arm64: Fix arm mpu SMP issues
Only primary core do the dynamic_areas_init.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
2022-05-17 11:45:16 +09:00
Eugene Cohen 816229128d arch/arm64: update gicv3 sre enablement
Fix writing of ICC_SRE_EL3 to or-in bits to align
with original intent to read-modify-write this
register.

Also disable FIQ and IRQ bypass so interrupt delivery
occurs through GIC.  Platforms may choose to override
this behavior in z_arm64_el3_plat_init implementations.

Remove ICC_SRE_EL3 config from viper and qemu since
this is now handled in the arm64 arch core.

Signed-off-by: Eugene Cohen <quic_egmc@quicinc.com>
2022-05-10 09:13:20 +02:00