1*61046927SAndroid Build Coastguard Worker/* 2*61046927SAndroid Build Coastguard Worker * Copyright 2023 Asahi Lina 3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT 4*61046927SAndroid Build Coastguard Worker */ 5*61046927SAndroid Build Coastguard Worker#include "helper.h" 6*61046927SAndroid Build Coastguard Worker#include "libagx.h" 7*61046927SAndroid Build Coastguard Worker 8*61046927SAndroid Build Coastguard Worker#define DB_NEXT 32 9*61046927SAndroid Build Coastguard Worker#define DB_ACK 48 10*61046927SAndroid Build Coastguard Worker#define DB_NACK 49 11*61046927SAndroid Build Coastguard Worker 12*61046927SAndroid Build Coastguard Workerenum helper_op { 13*61046927SAndroid Build Coastguard Worker OP_STACK_ALLOC = 0, 14*61046927SAndroid Build Coastguard Worker OP_STACK_FREE = 1, 15*61046927SAndroid Build Coastguard Worker OP_THREADGROUP_ALLOC = 4, 16*61046927SAndroid Build Coastguard Worker OP_THREADGROUP_FREE = 5, 17*61046927SAndroid Build Coastguard Worker OP_END = 15, 18*61046927SAndroid Build Coastguard Worker}; 19*61046927SAndroid Build Coastguard Worker 20*61046927SAndroid Build Coastguard Workervoid 21*61046927SAndroid Build Coastguard Workerlibagx_helper(void) 22*61046927SAndroid Build Coastguard Worker{ 23*61046927SAndroid Build Coastguard Worker uint64_t arg = 24*61046927SAndroid Build Coastguard Worker nir_load_helper_arg_lo_agx() | (((uint64_t)nir_load_helper_arg_hi_agx()) << 32); 25*61046927SAndroid Build Coastguard Worker 26*61046927SAndroid Build Coastguard Worker global struct agx_helper_header *hdr = 27*61046927SAndroid Build Coastguard Worker (global struct agx_helper_header *)arg; 28*61046927SAndroid Build Coastguard Worker 29*61046927SAndroid Build Coastguard Worker uint32_t core_index = nir_load_core_id_agx(); 30*61046927SAndroid Build Coastguard Worker uint32_t subgroups = hdr->subgroups; 31*61046927SAndroid Build Coastguard Worker global struct agx_helper_core *core = &hdr->cores[core_index]; 32*61046927SAndroid Build Coastguard Worker 33*61046927SAndroid Build Coastguard Worker while (1) { 34*61046927SAndroid Build Coastguard Worker nir_doorbell_agx(DB_NEXT); 35*61046927SAndroid Build Coastguard Worker uint32_t op = nir_load_helper_op_id_agx(); 36*61046927SAndroid Build Coastguard Worker uint32_t arg = nir_load_helper_arg_lo_agx(); 37*61046927SAndroid Build Coastguard Worker 38*61046927SAndroid Build Coastguard Worker switch (op) { 39*61046927SAndroid Build Coastguard Worker case OP_STACK_ALLOC: { 40*61046927SAndroid Build Coastguard Worker uint32_t idx = core->alloc_cur; 41*61046927SAndroid Build Coastguard Worker if (idx >= subgroups) { 42*61046927SAndroid Build Coastguard Worker core->alloc_failed++; 43*61046927SAndroid Build Coastguard Worker nir_doorbell_agx(DB_NACK); 44*61046927SAndroid Build Coastguard Worker break; 45*61046927SAndroid Build Coastguard Worker } 46*61046927SAndroid Build Coastguard Worker core->alloc_max = max(core->alloc_max, ++core->alloc_cur); 47*61046927SAndroid Build Coastguard Worker core->alloc_count[arg]++; 48*61046927SAndroid Build Coastguard Worker 49*61046927SAndroid Build Coastguard Worker nir_stack_map_agx(0, core->blocklist[idx].blocks[0]); 50*61046927SAndroid Build Coastguard Worker nir_stack_map_agx(1, core->blocklist[idx].blocks[1]); 51*61046927SAndroid Build Coastguard Worker nir_stack_map_agx(2, core->blocklist[idx].blocks[2]); 52*61046927SAndroid Build Coastguard Worker nir_stack_map_agx(3, core->blocklist[idx].blocks[3]); 53*61046927SAndroid Build Coastguard Worker nir_doorbell_agx(DB_ACK); 54*61046927SAndroid Build Coastguard Worker break; 55*61046927SAndroid Build Coastguard Worker } 56*61046927SAndroid Build Coastguard Worker 57*61046927SAndroid Build Coastguard Worker case OP_STACK_FREE: { 58*61046927SAndroid Build Coastguard Worker if (!core->alloc_cur) { // underflow 59*61046927SAndroid Build Coastguard Worker nir_doorbell_agx(DB_NACK); 60*61046927SAndroid Build Coastguard Worker break; 61*61046927SAndroid Build Coastguard Worker } 62*61046927SAndroid Build Coastguard Worker uint32_t idx = --core->alloc_cur; 63*61046927SAndroid Build Coastguard Worker core->blocklist[idx].blocks[0] = nir_stack_unmap_agx(0); 64*61046927SAndroid Build Coastguard Worker core->blocklist[idx].blocks[1] = nir_stack_unmap_agx(1); 65*61046927SAndroid Build Coastguard Worker core->blocklist[idx].blocks[2] = nir_stack_unmap_agx(2); 66*61046927SAndroid Build Coastguard Worker core->blocklist[idx].blocks[3] = nir_stack_unmap_agx(3); 67*61046927SAndroid Build Coastguard Worker nir_doorbell_agx(DB_ACK); 68*61046927SAndroid Build Coastguard Worker break; 69*61046927SAndroid Build Coastguard Worker } 70*61046927SAndroid Build Coastguard Worker 71*61046927SAndroid Build Coastguard Worker // TODO: Implement threadgroup allocs (for compute preemption) 72*61046927SAndroid Build Coastguard Worker case OP_THREADGROUP_ALLOC: { 73*61046927SAndroid Build Coastguard Worker nir_doorbell_agx(DB_NACK); 74*61046927SAndroid Build Coastguard Worker break; 75*61046927SAndroid Build Coastguard Worker } 76*61046927SAndroid Build Coastguard Worker 77*61046927SAndroid Build Coastguard Worker case OP_THREADGROUP_FREE: { 78*61046927SAndroid Build Coastguard Worker nir_doorbell_agx(DB_NACK); 79*61046927SAndroid Build Coastguard Worker break; 80*61046927SAndroid Build Coastguard Worker } 81*61046927SAndroid Build Coastguard Worker 82*61046927SAndroid Build Coastguard Worker case OP_END: { 83*61046927SAndroid Build Coastguard Worker nir_fence_helper_exit_agx(); 84*61046927SAndroid Build Coastguard Worker return; 85*61046927SAndroid Build Coastguard Worker } 86*61046927SAndroid Build Coastguard Worker 87*61046927SAndroid Build Coastguard Worker default: 88*61046927SAndroid Build Coastguard Worker *(global uint32_t *)(0xdead0000 | (op << 8)) = 0; 89*61046927SAndroid Build Coastguard Worker nir_fence_helper_exit_agx(); 90*61046927SAndroid Build Coastguard Worker return; 91*61046927SAndroid Build Coastguard Worker } 92*61046927SAndroid Build Coastguard Worker } 93*61046927SAndroid Build Coastguard Worker} 94