-
Notifications
You must be signed in to change notification settings - Fork 8k
intel_adsp: Introduce debug slot manager #97105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
bdd628a
b70ee21
7a17e7f
c19fc77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* Copyright (c) 2025 Intel Corporation. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <adsp_memory.h> | ||
#include <adsp_debug_window.h> | ||
#include <zephyr/cache.h> | ||
|
||
#include <zephyr/logging/log.h> | ||
LOG_MODULE_REGISTER(debug_window, CONFIG_SOC_LOG_LEVEL); | ||
|
||
struct adsp_debug_window { | ||
struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT]; | ||
uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET - | ||
ADSP_DW_DESC_COUNT * sizeof(struct adsp_dw_desc)]; | ||
uint8_t partial_page0[ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET]; | ||
uint8_t slots[ADSP_DW_SLOT_COUNT][ADSP_DW_SLOT_SIZE]; | ||
} __packed; | ||
|
||
#define WIN2_MBASE DT_REG_ADDR(DT_PHANDLE(DT_NODELABEL(mem_window2), memory)) | ||
#define WIN2_SLOTS ((HP_SRAM_WIN2_SIZE / ADSP_DW_PAGE_SIZE) - 1) | ||
#define ADSP_DW_FULL_SLOTS MIN(WIN2_SLOTS, ADSP_DW_SLOT_COUNT) | ||
|
||
#define ADSP_DW ((volatile struct adsp_debug_window *) \ | ||
(sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *) \ | ||
(WIN2_MBASE + WIN2_OFFSET)))) | ||
|
||
static int adsp_dw_find_slot(uint32_t type, bool prefer_partial) | ||
{ | ||
int i; | ||
|
||
if (prefer_partial) { | ||
if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == type) { | ||
return ADSP_DW_SLOT_COUNT; | ||
} | ||
} | ||
|
||
for (i = 0; i < ADSP_DW_FULL_SLOTS; i++) { | ||
if (ADSP_DW->descs[i].type == type) { | ||
return i; | ||
} | ||
} | ||
|
||
if (!prefer_partial) { | ||
if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == type) { | ||
return ADSP_DW_SLOT_COUNT; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do I understand it correctly, that this function only returns a valid slot index if it already has the desired type? If so, then why the preference? We should never have 2 slots with the same type, so shouldn't matter what the preference is. Just search them all. I don't see a need for that parameter here at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but why would we want another function when we can use this? When looking for occupied slot with a given type, yes the preference does not matter, but we eventually still need to check the full slots and the partial anyways. |
||
|
||
return -ENOENT; | ||
} | ||
|
||
volatile void *adsp_dw_request_slot(struct adsp_dw_desc *dw_desc, size_t *slot_size) | ||
{ | ||
int slot_idx; | ||
|
||
if (!dw_desc->type) { | ||
return NULL; | ||
} | ||
|
||
/* Check if a slot have been allocated for this type */ | ||
slot_idx = adsp_dw_find_slot(dw_desc->type, !!slot_size); | ||
if (slot_idx < 0) { | ||
/* Look for an empty slot */ | ||
slot_idx = adsp_dw_find_slot(ADSP_DW_SLOT_UNUSED, !!slot_size); | ||
if (slot_idx < 0) { | ||
LOG_INF("No available slot for %#x", dw_desc->type); | ||
return NULL; | ||
} | ||
} | ||
|
||
ADSP_DW->descs[slot_idx].resource_id = dw_desc->resource_id; | ||
ADSP_DW->descs[slot_idx].type = dw_desc->type; | ||
ADSP_DW->descs[slot_idx].vma = dw_desc->vma; | ||
|
||
if (slot_size) { | ||
*slot_size = ADSP_DW_SLOT_SIZE; | ||
} | ||
|
||
if (slot_idx == ADSP_DW_SLOT_COUNT) { | ||
if (slot_size) { | ||
*slot_size -= ADSP_DW_PAGE0_SLOT_OFFSET; | ||
} | ||
|
||
LOG_DBG("Allocating partial page0 to be used for %#x", dw_desc->type); | ||
|
||
return ADSP_DW->partial_page0; | ||
} | ||
|
||
LOG_DBG("Allocating debug slot %d to be used for %#x", slot_idx, dw_desc->type); | ||
|
||
return ADSP_DW->slots[slot_idx]; | ||
} | ||
|
||
volatile void *adsp_dw_seize_slot(uint32_t slot_index, struct adsp_dw_desc *dw_desc, | ||
size_t *slot_size) | ||
{ | ||
if ((slot_index >= ADSP_DW_FULL_SLOTS && slot_index != ADSP_DW_SLOT_COUNT) || | ||
!dw_desc->type) { | ||
return NULL; | ||
} | ||
|
||
if (slot_index < ADSP_DW_FULL_SLOTS) { | ||
if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) { | ||
LOG_INF("Overtaking debug slot %d, used by %#x for %#x", slot_index, | ||
ADSP_DW->descs[slot_index].type, dw_desc->type); | ||
} | ||
|
||
if (slot_size) { | ||
*slot_size = ADSP_DW_SLOT_SIZE; | ||
} | ||
|
||
ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id; | ||
ADSP_DW->descs[slot_index].type = dw_desc->type; | ||
ADSP_DW->descs[slot_index].vma = dw_desc->vma; | ||
|
||
return ADSP_DW->slots[slot_index]; | ||
} | ||
|
||
/* The caller is not prepared to handle partial debug slot */ | ||
if (!slot_size) { | ||
return NULL; | ||
} | ||
|
||
if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) { | ||
LOG_INF("Overtaking partial page0, used by %#x for %#x", | ||
ADSP_DW->descs[slot_index].type, dw_desc->type); | ||
} | ||
|
||
*slot_size = ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET; | ||
|
||
ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id; | ||
ADSP_DW->descs[slot_index].type = dw_desc->type; | ||
ADSP_DW->descs[slot_index].vma = dw_desc->vma; | ||
|
||
return ADSP_DW->partial_page0; | ||
} | ||
|
||
void adsp_dw_release_slot(uint32_t type) | ||
{ | ||
int slot_idx; | ||
|
||
slot_idx = adsp_dw_find_slot(type, true); | ||
|
||
if (slot_idx < 0) { | ||
return; | ||
} | ||
|
||
if (slot_idx == ADSP_DW_SLOT_COUNT) { | ||
LOG_DBG("Releasing partial page0 used by %#x", type); | ||
} else { | ||
LOG_DBG("Releasing debug slot %d used by %#x", slot_idx, type); | ||
} | ||
|
||
ADSP_DW->descs[slot_idx].resource_id = 0; | ||
ADSP_DW->descs[slot_idx].type = ADSP_DW_SLOT_UNUSED; | ||
ADSP_DW->descs[slot_idx].vma = 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
confused - you already have this structure in adsp_debug_window.h?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is only there if the
CONF_INTEL_ADSP_DEBUG_SLOT_MANAGER
is not enabled.No one should have any knowledge on how the debug window is partitioned, they just ask for a slot and use the slot which is assigned to them, that's all they need to know.
In other words: when the slot manager is enabled I want to make sure that no one can side step and hack into the system.