Amiga Unix — 68040 · 68060

Manual pages › Devices and drivers (7)

zz9ksvc(7)

the service channel of a ZZ9000-family board's second ARM core

Package: zz9ksvc46, added for amigaux.

zz9ksvc - the service channel of a ZZ9000-family board's second ARM core

/dev/zz9ksvc0
/dev/zz9ksvc1
#include <sys/zz9ksvc.h>

A Z3660, and a ZZ9000 with a firmware that has the services runtime, can do work on the board's second ARM core for a program on the Amiga: decompression first, more services later. The program hands it buffers in the board's memory and requests, and waits for the replies. Each board is a unit, and /dev/zz9ksvcN is the channel to unit N.

When the board, its bootstrap block or its runtime is missing, the open fails with ENXIO: the program then does the work itself.

Every open is a client of its own, and the kernel stands between the clients and the board:

  • a client names its buffers by handles, 0 to 15, never by an address;
  • the kernel builds each request it passes on: it gives the request its number, lets through only the requests it knows, and puts the board's own handle in place of each handle the client names, after checking the buffer is that client's and the bytes used lie inside it;
  • no address from a client reaches the board, and no board address reaches a client.

Each client may hold 16 buffers and 8 MiB of buffers in all, and have 4 requests in flight.

The driver is the loadable module zz9ksvc, of the demand class: it loads at the first open, and stays only while a board with a runtime is there. The board driver (the Z3660's z3660rtg, a ZZ9000's) finds the board and gives it to zz9ksvc through the small module zz9kbus.

fills a struct zzs_info: the unit, the board's id, the runtime's ABI version and capability bits, the ring sizes, this client's limits and the bytes of buffers it holds.
allocates a buffer of za_length bytes, rounded up to whole pages, and gives its handle and, unless ZZS_ALLOC_CARDONLY is asked, the cookie that maps it. ENOSPC when the client has no handle or quota left.
frees the buffer whose handle is the argument. EBUSY while a request in flight uses it. A buffer that was ever mapped is held until the channel is closed (see Mapping a buffer): its handle and its bytes stay taken until then.
passes on a request: the opcode and up to 48 bytes of payload in the runtime's own layout, with each buffer named by its handle. It gives the request's number. EINVAL for a request the kernel does not pass on or a range outside its buffer, EBADF for a handle that is not one of this client's buffers, EPERM for a request only root may make, EAGAIN when 4 are in flight or the rings are full.
waits for the request zw_id, at most zw_ms milliseconds (10 seconds when 0), and gives the runtime's status and reply. A signal ends the wait with EINTR, and the request can be waited for again. ETIMEDOUT when the time runs out (see Timeouts).
(root) fills a struct zzs_stats with the channel's counts.
(root) forgets everything the runtime held, after it was restarted: requests in flight fail with EIO, and buffers must be freed and allocated again.

mmap(2) with MAP_SHARED, the buffer's cookie as the offset (plus a page-aligned offset into the buffer) and a length within it maps that buffer of the board's memory. Nothing else on the board can be mapped. A cookie stops working when its buffer is freed.

A mapping outlives the cookie, so the board's memory under a mapped buffer is not given to anyone else while the client may still reach it: a freed buffer that was mapped is given back only when the channel is closed and its last mapping is gone. A program that maps buffers should munmap(2) them, reuse them, and free them when it is done; when every handle is held, ZZSIOC_ALLOC gives ENOSPC until the channel is closed and opened again. After ZZSIOC_RESET, an allocation the restarted runtime places under another client's mapping gives EAGAIN.

The runtime cannot cancel work it has taken. When a wait times out, the buffers the request uses are quarantined: the runtime may still write them, so they are not freed or handed out again until its reply comes or the runtime is reset. The same happens to a client's buffers when it closes, or is killed, with requests in flight. At most 32 buffers are quarantined at a time; a request that could take the count past that gives EAGAIN.

The kernel looks for replies at every clock tick while requests are in flight, and not at all otherwise.

/dev/zz9ksvc0, /dev/zz9ksvc1
character major 55, minors 0 and 1, mode 0666.
/etc/conf/mod.d/zz9ksvc
the module; /etc/conf/mod.d/zz9kbus the board registry it uses.

The runtime's requests and replies are those of the ZZ9000 SDK version 2 (BlitterStudio zz9000-firmware); the module carries its headers. The module is GPL-3.0-or-later; the interface between board drivers and it, zz9kbus, is MIT.

mmap(2), munmap(2)

1 November 2026 zz9ksvc