probes: serve ADRENO_GUEST_BACKLIGHT in SNAP_EDP_BACKLIGHT monitors
-DSNAP_EDP_BACKLIGHT=1 links compat/edp-backlight.c (probes/run.py OPTIONAL), keeps its state in one zeroed monitor arena page (setup.c; excluded from transaction publication like the other monitor-only pages), and dispatches the call from the 0xad16 HVC path. The call is admitted like ADRENO_GUEST_STOP: EL1, and the HVC word in the loaded AuxKC's bytes; otherwise EDP_BL_E_ORIGIN. MMIO goes through q1n1's EL2 identity map with a DSB after each access. Every call is recorded as EV_EDP_BACKLIGHT (60). Default off. With the org2 desktop run's 122 flags the monitor is byte-identical with the define absent or 0 (sha256 0d8b9ec3..., the qualification's monitor_sha256) and 458,536 bytes with it (216 bytes under the 448 KiB code budget). Hardware: not run.
This commit is contained in:
1 parent
7da9adf573
commit
30a815744d
8 files changed
+82
-1
No files matched your search
+2
-1
@@ -128,7 +128,8 @@ MULTI = {'pauth-address': ['probes/pauth-address.S','compat/pauth-native.S'],
|
||||
'compat/adreno.c', 'compat/adreno-fill.c', 'compat/adreno-ib.c', 'compat/irq-forward.c', 'compat/ans.c', 'compat/ans-window.c', 'compat/nvme-host.c', 'compat/early-stop.c', 'compat/a16-thermal.c', 'probes/memory.S']}
|
||||
# Units linked only when their opt-in define is in FLAGS, after MULTI's, so a build without the define links exactly
|
||||
# the objects it always did and its ELF stays byte-identical.
|
||||
OPTIONAL = {'xnuboot': (('-DSNAP_ADRENO_COHERENT=1', 'compat/adreno-coherent.c'),)}
|
||||
OPTIONAL = {'xnuboot': (('-DSNAP_ADRENO_COHERENT=1', 'compat/adreno-coherent.c'),
|
||||
('-DSNAP_EDP_BACKLIGHT=1', 'compat/edp-backlight.c'))}
|
||||
|
||||
|
||||
def optional_sources(name, flags):
|
||||
|
||||
@@ -870,6 +870,15 @@ struct guest_net_state {
|
||||
#define GUEST_NET_POLL2 4u /* q1n1 Q1N1_CALL_POLL2 */
|
||||
#define GUEST_NET_CALL_E_OP UINT64_C(0xffffffffffffffff) /* Q1N1_CALL_E_OP: an older q1n1 */
|
||||
#endif
|
||||
/* SNAP_EDP_BACKLIGHT (compat/edp-backlight.h, agents/brightness): ADRENO_GUEST_BACKLIGHT sets the panel's DPCD
|
||||
* brightness over the eDP controller's AUX channel for the kext's AdrenoBacklight, admitted like ADRENO_GUEST_STOP.
|
||||
* Its state is one zeroed monitor page (setup.c). Off, the code is absent and compat/edp-backlight.c is not linked. */
|
||||
#ifndef SNAP_EDP_BACKLIGHT
|
||||
#define SNAP_EDP_BACKLIGHT 0
|
||||
#endif
|
||||
#if SNAP_EDP_BACKLIGHT
|
||||
#include "../compat/edp-backlight.h"
|
||||
#endif
|
||||
#include "../compat/fast-vector.h"
|
||||
_Static_assert(FAST_EXIT_CLASSES==FAST_TRAP_CLASSES-1+FAST_CROSS_CLASSES &&
|
||||
FAST_EXIT_CROSS_SLOT(1)==FAST_TRAP_CLASSES-1,
|
||||
|
||||
@@ -455,6 +455,11 @@ struct context {
|
||||
* monitor arena pages taken at setup (owner 0, never released). */
|
||||
struct guest_net_state *guest_net;
|
||||
#endif
|
||||
#if SNAP_EDP_BACKLIGHT
|
||||
/* compat/edp-backlight.h: ADRENO_GUEST_BACKLIGHT's state, one monitor
|
||||
* arena page taken at setup (owner 0, never released). */
|
||||
struct edp_backlight_state *edp_backlight;
|
||||
#endif
|
||||
#if SNAP_FAST_EL0_SYSREG || SNAP_SERVICE_SUBCLASS
|
||||
/* Appended only under these opt-in defines, inside the page before the
|
||||
* table arena (asserted below), so define-free layout readers keep every
|
||||
|
||||
@@ -576,6 +576,10 @@ static int txn_publish_exclude(void *ctx,uint64_t page)
|
||||
#if SNAP_GUEST_NET
|
||||
/* The guest-network state, stored the same way (compat/guest-net-link.h). */
|
||||
if(page>=(uint64_t)c->guest_net && page-(uint64_t)c->guest_net<GUEST_NET_STATE_PAGES*4096)return 1;
|
||||
#endif
|
||||
#if SNAP_EDP_BACKLIGHT
|
||||
/* ADRENO_GUEST_BACKLIGHT's state page, stored the same way (compat/edp-backlight.h). */
|
||||
if(page==(uint64_t)c->edp_backlight)return 1;
|
||||
#endif
|
||||
for(unsigned cpu=0;cpu<GUEST_CPU_COUNT;cpu++)
|
||||
for(uint64_t g=0;g<c->vcpus[cpu].guard_count;g++)
|
||||
|
||||
@@ -652,3 +652,46 @@ static void guest_net_hvc(struct context *c, uint64_t *frame, uint64_t elr, uint
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SNAP_EDP_BACKLIGHT
|
||||
/* compat/edp-backlight.c reaches the eDP controller and dispcc through these, physical addresses in q1n1's EL2
|
||||
* identity map (Device memory, as the thermal guard's reads). The engine admits only its allow-list
|
||||
* (edp_bl_mmio_read_ok/edp_bl_mmio_write_ok, proven by tools/test-edp-backlight.c); the barrier orders each access
|
||||
* before the next, as the controller's FIFO protocol needs. */
|
||||
static int edp_backlight_read(void *ctx, uint64_t pa, uint32_t *value)
|
||||
{
|
||||
(void)ctx;
|
||||
*value = *(const volatile uint32_t *)pa;
|
||||
__asm__ volatile("dsb sy" ::: "memory");
|
||||
return 0;
|
||||
}
|
||||
static int edp_backlight_write(void *ctx, uint64_t pa, uint32_t value)
|
||||
{
|
||||
(void)ctx;
|
||||
*(volatile uint32_t *)pa = value;
|
||||
__asm__ volatile("dsb sy" ::: "memory");
|
||||
return 0;
|
||||
}
|
||||
static uint64_t edp_backlight_clock(void *ctx) {(void)ctx; return service_profile_clock();}
|
||||
|
||||
/* ADRENO_GUEST_BACKLIGHT (compat/edp-backlight.h): admitted from EL1 for the HVC the loaded AuxKC's own bytes hold
|
||||
* (early_stop_guest_caller, as ADRENO_GUEST_STOP). Under the service lock: one AUX transaction at a time, each
|
||||
* bounded by hz / EDP_BL_AUX_BUDGET_DIV. */
|
||||
static void edp_backlight_hvc(struct context *c, uint64_t *frame, uint64_t elr, uint64_t spsr)
|
||||
{
|
||||
const struct params *p = c->params;
|
||||
const struct edp_backlight_io io = {c, edp_backlight_read, edp_backlight_write, edp_backlight_clock,
|
||||
p->clock_host_hz};
|
||||
uint64_t hvc = elr - 4, pa = guest_pa(hvc), r[4] = {frame[0], frame[1], frame[2], frame[3]};
|
||||
uint32_t word = 0;
|
||||
if (pa && p->auxkc.pa_end > p->auxkc.pa_base + 4 && pa >= p->auxkc.pa_base && pa <= p->auxkc.pa_end - 4)
|
||||
word = *(volatile uint32_t *)pa;
|
||||
if (early_stop_guest_caller(&p->auxkc, hvc, pa, word, spsr)) {
|
||||
r[0] = (uint64_t)(int64_t)EDP_BL_E_ORIGIN;
|
||||
r[1] = r[2] = r[3] = 0;
|
||||
} else
|
||||
edp_backlight_call(c->edp_backlight, &io, r);
|
||||
record(c, EV_EDP_BACKLIGHT, hvc, frame[1] << 32 | (uint32_t)frame[2], r[0] << 32 | (uint32_t)r[3], r[1]);
|
||||
for (unsigned n = 0; n < 4; n++) frame[n] = r[n];
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -217,6 +217,11 @@ struct event {
|
||||
* control's PMU passes << 16, c = stale[0] << 32 | stale[1] (the controls'
|
||||
* stale words, each at most 1,024); probes/run.py decodes it */
|
||||
#endif
|
||||
#if SNAP_EDP_BACKLIGHT
|
||||
#define EV_EDP_BACKLIGHT 60 /* ADRENO_GUEST_BACKLIGHT (compat/edp-backlight.h): a = sub-op << 32 | (u32)level asked,
|
||||
* b = (u32)result << 32 | the panel's level after the call, c = the reply's x1 (ABI |
|
||||
* state << 8 | detail << 16 | DPCD 0x700..0x703 << 24 | mode << 56); pc = the HVC */
|
||||
#endif
|
||||
#define EV_HANDOFF 7 /* a field of the handoff was read: a = offset */
|
||||
#define EV_WATCHDOG 6 /* the guest ran too long and was taken back */
|
||||
#define EV_DISPATCH_CMD 8 /* a call that is not an endpoint call:
|
||||
|
||||
@@ -90,6 +90,14 @@ int xnuboot_setup(uint64_t work, uint64_t size, uint64_t params, uint64_t out,
|
||||
for (uint64_t n = 0; n < GUEST_NET_STATE_PAGES * 4096 / 8; n++) ((volatile uint64_t *)c->guest_net)[n] = 0;
|
||||
__asm__ volatile("" ::: "memory");
|
||||
c->next_table += GUEST_NET_STATE_PAGES * 4096;
|
||||
#endif
|
||||
#if SNAP_EDP_BACKLIGHT
|
||||
/* compat/edp-backlight.h: one page, zeroed (EDP_BL_STATE_UNPROBED), probed by the first guest call. */
|
||||
if (c->next_table + 4096 > c->work_end) return 1;
|
||||
c->edp_backlight = (struct edp_backlight_state *)c->next_table;
|
||||
for (uint64_t n = 0; n < 4096 / 8; n++) ((volatile uint64_t *)c->edp_backlight)[n] = 0;
|
||||
__asm__ volatile("" ::: "memory");
|
||||
c->next_table += 4096;
|
||||
#endif
|
||||
if(c->params->early_stop.flags & EARLY_STOP_F_THERMAL) {
|
||||
if(c->next_table>c->work_end || c->work_end-c->next_table<4096)return 1;
|
||||
|
||||
@@ -578,6 +578,12 @@ static int xnuboot_trap_locked(uint64_t *frame, uint64_t esr, uint64_t *elr)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if SNAP_EDP_BACKLIGHT
|
||||
if (frame[0] == ADRENO_GUEST_BACKLIGHT) {
|
||||
edp_backlight_hvc(c, frame, *elr, physical_spsr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if SNAP_ADRENO_IB_ASYNC
|
||||
if (frame[0] == ADRENO_GUEST_IB_POLL) {
|
||||
gpu_ib_poll_hvc(c, frame, *elr);
|
||||
|
||||
Reference in new issue
Block a user