#include <jailhouse/types.h>
-static inline void outb(u8 v, u16 port)
-{
- asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
-}
+/**
+ * @ingroup IO
+ * @defgroup PIO x86 I/O Accessors
+ * @{
+ */
+/**
+ * Read 8 (b), 16(w) or 32-bit (l) value from a port.
+ * @param port Port number.
+ *
+ * @return Read value.
+ * @{
+ */
static inline u8 inb(u16 port)
{
u8 v;
return v;
}
-static inline void outw(u16 value, u16 port)
-{
- asm volatile("outw %w0,%w1" : : "a" (value), "Nd" (port));
-}
-
static inline u16 inw(u16 port)
{
u16 v;
return v;
}
-static inline void outl(u32 value, u16 port)
-{
- asm volatile("outl %0,%1" : : "a" (value), "Nd" (port));
-}
-
static inline u32 inl(u16 port)
{
u32 v;
asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
return v;
}
+/** @} */
+
+/**
+ * Write 8 (b), 16(w) or 32-bit (l) value to a port.
+ * @param value Value to write
+ * @param port Port number.
+ * @{
+ */
+static inline void outb(u8 value, u16 port)
+{
+ asm volatile("outb %0,%1" : : "a" (value), "dN" (port));
+}
+
+static inline void outw(u16 value, u16 port)
+{
+ asm volatile("outw %w0,%w1" : : "a" (value), "Nd" (port));
+}
+
+static inline void outl(u32 value, u16 port)
+{
+ asm volatile("outl %0,%1" : : "a" (value), "Nd" (port));
+}
+/** @} */
+
+/** @} */
#include <jailhouse/paging.h>
+/**
+ * @defgroup IO I/O Access Subsystem
+ *
+ * This subsystem provides accessors to I/O and supports the interpretation of
+ * intercepted I/O accesses of cells.
+ *
+ * @{
+ */
+
+/** Information about interpreted MMIO access. */
struct mmio_access {
+ /** Length of the MMIO access instruction, 0 for invalid or unsupported
+ * access. */
unsigned int inst_len;
+ /** Size of the access. */
unsigned int size;
+ /** Architecture-specific number of the register that holds the output
+ * value or should receive the input. */
unsigned int reg;
};
+/**
+ * Define MMIO read accessor.
+ * @param size Access size.
+ */
#define DEFINE_MMIO_READ(size) \
static inline u##size mmio_read##size(void *address) \
{ \
return *(volatile u##size *)address; \
}
+
+/**
+ * Read 8, 16, 32 or 64-bit value from a memory-mapped I/O register.
+ * @param address Virtual address of the register.
+ *
+ * @return Read value.
+ * @{
+ */
DEFINE_MMIO_READ(8)
DEFINE_MMIO_READ(16)
DEFINE_MMIO_READ(32)
DEFINE_MMIO_READ(64)
+/** @} */
+/**
+ * Define MMIO write accessor.
+ * @param size Access size.
+ */
#define DEFINE_MMIO_WRITE(size) \
static inline void mmio_write##size(void *address, u##size value) \
{ \
*(volatile u##size *)address = value; \
}
+
+/**
+ * Write 8, 16, 32 or 64-bit value to a memory-mapped I/O register.
+ * @param address Virtual address of the register.
+ * @param value Value to write.
+ * @{
+ */
DEFINE_MMIO_WRITE(8)
DEFINE_MMIO_WRITE(16)
DEFINE_MMIO_WRITE(32)
DEFINE_MMIO_WRITE(64)
-
-struct mmio_access mmio_parse(unsigned long pc,
- const struct guest_paging_structures *pg_structs,
- bool is_write);
+/** @} */
/**
- * mmio_read32_field() - Read value of 32-bit register field
- * @addr: Register address.
- * @mask: Bit mask. Shifted value must be provided which describes both
- * starting bit position (1st non-zero bit) and length of the field.
+ * Read value from 32 or 64-bit MMIO register field.
+ * @param address Virtual address of the register.
+ * @param mask Bitmask to defining the field. Only successive bits
+ * must be set.
*
- * Return: Field value of register.
+ * @return Field value of register, shifted so that the first non-zero bit in
+ * @c mask becomes bit 0.
+ * @{
*/
-static inline u32 mmio_read32_field(void *addr, u32 mask)
+static inline u32 mmio_read32_field(void *address, u32 mask)
{
- return (mmio_read32(addr) & mask) >> (__builtin_ffs(mask) - 1);
+ return (mmio_read32(address) & mask) >> (__builtin_ffs(mask) - 1);
}
+static inline u64 mmio_read64_field(void *address, u64 mask)
+{
+ return (mmio_read64(address) & mask) >> (__builtin_ffsl(mask) - 1);
+}
+/** @} */
+
/**
- * mmio_write32_field() - Write value of 32-bit register field
- * @addr: Register address.
- * @mask: Bit mask. See mmio_read32_field() for more details.
- * @value: Register field value (must be the same length as mask).
+ * Write value to 32 or 64-bit MMIO register field.
+ * @param address Virtual address of the register.
+ * @param mask Bitmask to defining the field. Only successive bits
+ * must be set.
+ * @param value Register field value.
*
- * Update field value of 32-bit register, leaving all other fields unmodified.
-
- * Return: None.
+ * This updates only the field value of the register, leaving all other
+ * register bits unmodified. Thus, it performs a read-modify-write cycle.
+ * @{
*/
-static inline void mmio_write32_field(void *addr, u32 mask, u32 value)
+static inline void mmio_write32_field(void *address, u32 mask, u32 value)
{
- mmio_write32(addr, (mmio_read32(addr) & ~mask) |
+ mmio_write32(address, (mmio_read32(address) & ~mask) |
((value << (__builtin_ffs(mask) - 1)) & mask));
}
-/**
- * mmio_read64_field() - Read value of 64-bit register field.
- * See mmio_read32_field() for more details.
- */
-static inline u64 mmio_read64_field(void *addr, u64 mask)
+static inline void mmio_write64_field(void *address, u64 mask, u64 value)
{
- return (mmio_read64(addr) & mask) >> (__builtin_ffsl(mask) - 1);
+ mmio_write64(address, (mmio_read64(address) & ~mask) |
+ ((value << (__builtin_ffsl(mask) - 1)) & mask));
}
+/** @} */
/**
- * mmio_write64_field() - Write value of 64-bit register field.
- * See mmio_write32_field() for more details.
+ * Parse an intercepted MMIO access of a cell CPU.
+ * @param pc Program counter of the access instruction.
+ * @param pg_structs Currently active guest (cell) paging structures.
+ * @param is_write True if write access, false for read.
+ *
+ * @return MMIO access information. mmio_access::inst_len is 0 on invalid or
+ * unsupported access.
*/
-static inline void mmio_write64_field(void *addr, u64 mask, u64 value)
-{
- mmio_write64(addr, (mmio_read64(addr) & ~mask) |
- ((value << (__builtin_ffsl(mask) - 1)) & mask));
-}
+struct mmio_access mmio_parse(unsigned long pc,
+ const struct guest_paging_structures *pg_structs,
+ bool is_write);
+/** @} */
#endif /* !_JAILHOUSE_MMIO_H */