<< Back to Codezero API Reference
/* User-level thread control block */ struct utcb { u32 mr[MR_TOTAL]; /* MRs that are mapped to real registers */ u32 saved_tag; /* Saved tag field for stacked ipcs */ u32 saved_sender; /* Saved sender field for stacked ipcs */ u32 mr_rest[MR_REST]; /* Complete the utcb for up to 64 words */ };
/* For obtaining the UTCB address */ static inline struct utcb *l4_get_utcb() { /* * By double dereferencing, we get the private TLS (aka UTCB). First * reference is to the KIP's utcb offset, second is to the utcb itself, * to which the KIP's utcb reference had been updated during context * switch. */ return *kip_utcb_ref; } /* Functions to read/write utcb registers */ /* Reads the message register at the given offset */ static inline unsigned int read_mr(int offset) { if (offset < MR_TOTAL) return l4_get_utcb()->mr[offset]; else return l4_get_utcb()->mr_rest[offset - MR_TOTAL]; } /* Writes the given value at the given message register offset */ static inline void write_mr(unsigned int offset, unsigned int val) { if (offset < MR_TOTAL) l4_get_utcb()->mr[offset] = val; else l4_get_utcb()->mr_rest[offset - MR_TOTAL] = val; }
The below functions are defined for stacked ipc where a new IPC is initiated before finishing the first one. In order to achieve this, important IPC context is saved onto the UTCB in the designated IPC context fields. The saved context includes information such as the sender id and sender tag. Please refer to the L4_IPC system call reference page for further information.
/* * If we're about to do another ipc, this saves the last ipc's * parameters such as the sender and tag information. * Any previously saved data in save slots are destroyed. */ static inline void l4_save_ipcregs(void) { l4_get_utcb()->saved_sender = l4_get_sender(); l4_get_utcb()->saved_tag = l4_get_tag(); } static inline void l4_restore_ipcregs(void) { l4_set_tag(l4_get_utcb()->saved_tag); l4_set_sender(l4_get_utcb()->saved_sender); }