Skip to content

Commit

Permalink
soc: intel_adsp: cavs: add simple IMR functionality
Browse files Browse the repository at this point in the history
Add simple mechanism to load the image from IMR memory. Basically we are
only setting a flag in power off for the next boot to jump to existing
image in IMR.

Signed-off-by: Jaska Uimonen <[email protected]>
Jaska Uimonen authored and fabiobaltieri committed Jun 20, 2023
1 parent a13157f commit a8b28f1
Showing 4 changed files with 64 additions and 0 deletions.
7 changes: 7 additions & 0 deletions dts/xtensa/intel/intel_adsp_cavs25.dtsi
Original file line number Diff line number Diff line change
@@ -97,6 +97,13 @@
wovcro-supported;
};

IMR1: memory@0xb0000000 {
compatible = "intel,adsp-imr";
reg = <0xB0000000 DT_SIZE_M(16)>;
block-size = <0x1000>;
zephyr,memory-region = "IMR1";
};

soc {
shim: shim@71f00 {
compatible = "intel,adsp-shim";
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Copyright (c) 2023 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_SOC_INTEL_ADSP_TGL_IMR_LAYOUT_H_
#define ZEPHYR_SOC_INTEL_ADSP_TGL_IMR_LAYOUT_H_

/* These structs and macros are from the ROM code header
* on cAVS platforms, please keep them immutable.
*
* The ROM structs and code is lifted from:
* https://github.com/thesofproject/sof
* 6c0db22c65 - platform: cavs: configure resume from IMR
*/

/*
* A magic that tells ROM to jump to imr_restore_vector instead of normal boot
*/
#define ADSP_IMR_MAGIC_VALUE 0x02468ACE

struct imr_header {
uint32_t adsp_imr_magic;
uint32_t structure_version;
uint32_t structure_size;
uint32_t imr_state;
uint32_t imr_size;
void (*imr_restore_vector)(void);
};

struct imr_state {
struct imr_header header;
uint8_t reserved[0x1000 - sizeof(struct imr_header)];
};

struct imr_layout {
uint8_t css_reserved[0x1000];
struct imr_state imr_state;
};

#endif /* ZEPHYR_SOC_INTEL_ADSP_TGL_IMR_LAYOUT_H_ */
Original file line number Diff line number Diff line change
@@ -29,6 +29,9 @@
#define HPSRAM_SEGMENTS (HPSRAM_EBB_COUNT + EBB_SEG_SIZE - 1) / EBB_SEG_SIZE
#define HPSRAM_MEMMASK(idx) ((1ULL << (HPSRAM_EBB_COUNT - EBB_SEG_SIZE * idx)) - 1)

/* L3 region (IMR), located in host memory */
#define L3_MEM_BASE_ADDR (DT_REG_ADDR(DT_NODELABEL(imr1)))

/* The rimage tool produces two blob addresses we need to find: one is
* our bootloader code block which starts at its entry point, the
* other is the "manifest" containing the HP-SRAM data to unpack,
15 changes: 15 additions & 0 deletions soc/xtensa/intel_adsp/cavs/power.c
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
#include <adsp_memory.h>
#include <adsp_shim.h>
#include <adsp_clk.h>
#include <adsp_imr_layout.h>
#include <cavs-idc.h>
#include "soc.h"

@@ -47,6 +48,11 @@ LOG_MODULE_REGISTER(soc);

#define ALL_USED_INT_LEVELS_MASK (L2_INTERRUPT_MASK | L3_INTERRUPT_MASK)

/*
* @biref FW entry point called by ROM during normal boot flow
*/
extern void rom_entry(void);

struct core_state {
uint32_t intenable;
};
@@ -82,6 +88,15 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id)
sys_cache_data_flush_and_invd_all();
if (cpu == 0) {
uint32_t hpsram_mask[HPSRAM_SEGMENTS];

struct imr_header hdr = {
.adsp_imr_magic = ADSP_IMR_MAGIC_VALUE,
.imr_restore_vector = rom_entry,
};
struct imr_layout *imr_layout =
arch_xtensa_uncached_ptr((struct imr_layout *)L3_MEM_BASE_ADDR);
imr_layout->imr_state.header = hdr;

/* turn off all HPSRAM banks - get a full bitmap */
for (int i = 0; i < HPSRAM_SEGMENTS; i++)
hpsram_mask[i] = HPSRAM_MEMMASK(i);

0 comments on commit a8b28f1

Please sign in to comment.