I think I found the API provided by the Zico/Mzrm firmware.
As mentioned
previously, the main ARM core uses a messaging-based method to communicate with Zico.
Messages have an ID. This is recognizable on the ARM side code, and, as it turns out, on the Xtensa side too.
The 0xbff0xxxx area is used on both sides for communication. My guess is that the data doesn't necessarily has to fit there, multiple megabytes from RAM are assigned for display related data (which are visible from both cores).
Here is an excerpt from the Xtensa side (sx280) that shows how message IDs are associated with message handler functions.
...
80a2c1d0: movi a11, 226
80a2c1d3: bgeu a11, a3, loc_80a2c23a ; branch if a3 <= 226
80a2c1d6: l32i.n a15, a1, 0
80a2c1d8: movi.n a10, 8
80a2c1da: l32i.n a11, a7, 0
80a2c1dc: l32r a12, 0x80a29400 ; *"ID Error[%d] -- msg:0x%08x"
80a2c1df: mov.n a13, a2
80a2c1e1: mov.n a14, a3
80a2c1e3: l32r a8, 0x80a1d4e8 ; (loc_bff209f0)
80a2c1e6: callx8 a8
...
loc_80a2c23a
80a2c23a: l32r a8, 0x80a29404 ; (0x80a001d0) ; table of msg handler function pointers
80a2c23d: addx4 a8, a3, a8 ; calculate offset (a3 = a8 + a3 * 4)
80a2c240: l32i.n a8, a8, 0 ; load function pointer
80a2c242: callx8 a8 ; execute it
...
The ID -> name association list is attached to my previous post due to size limitation. I have extracted the function pointers starting from 0x80a001d0, and used a script to extract the debug strings (which appear to be function names) from the disassembly of the 0x80a00000 area.
The 0xbff20000 area is Xtensa code, the 0xbff00000 area has only data. RAM starting at 0xd80000 is used for Xtensa variables. Pointers to 0x41xxxxxx and 0x42xxxxxx addresses can be found in Xtensa-related data, my guess is that those parts of RAM are dedicated to overlay related stuff.
Update disassembler script is attached (it has not become "wiser", but it now has options that can aid disassembly).
The other script can be used to get the names of the message handler functions.