iBoot/drivers/thunderbolt/tbt_xd_packet.h

109 lines
3.3 KiB
C

/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef TBT_XD_PACKET_H
#define TBT_XD_PACKET_H
#include <debug.h>
#include "tbt_protocol.h"
// Sets the length of field of an xdomain packet. The length is given
// in bytes, but must be a multiple of 4
static inline void tbt_xd_packet_set_len(uint8_t *packet, uint8_t len)
{
ASSERT((len & 0x3) == 0);
// length (in dwords) is in bits 0-5 of the DWORD 2
// clients include the length of the header when calling, but
// the spec doesn't include the header length, so subtract 12
packet[11] = (len - 12) >> 2;
}
// Sets the sequence number field of an xdomain packet. The sequence
// number must be a 2-bit number
static inline void tbt_xd_packet_set_seq(uint8_t *packet, uint8_t seq)
{
ASSERT((seq & ~0x3U) == 0);
// sequence number is in bits 27-28 of the DWORD 2
packet[8] = seq << 3;
}
// Gets the sequence number field of an xdomain packet
static inline uint8_t tbt_xd_packet_get_seq(const uint8_t *packet)
{
// sequence number is in bits 27-28 of the DWORD 2
return (packet[8] >> 3) & 0x3;
}
/* Sets the protocol UUID of the given xdomain request or response packet to the
* given UUID in Thunderbolt network byte order
*/
static inline void tbt_xd_packet_set_protocol_uuid(uint8_t *packet, const uint8_t *uuid)
{
memcpy(packet + TBT_XD_REQUEST_PROTOCOL_UUID_OFFSET, uuid, 16);
}
/* Compares the protocol UUID of the given xdomain request or response packet to the
* given UUID in Thunderbolt network byte order
*/
static inline int tbt_xd_packet_compare_protocol_uuid(const uint8_t *packet, const uint8_t *uuid)
{
return memcmp(packet + TBT_XD_REQUEST_PROTOCOL_UUID_OFFSET, uuid, 16);
}
static inline uint32_t tbt_xd_packet_get_type(const uint8_t *packet)
{
uint32_t packet_type;
memcpy(&packet_type, packet + TBT_XD_REQUEST_PACKET_TYPE_OFFSET, sizeof(packet_type));
return ntohl(packet_type);
}
static inline void tbt_xd_packet_set_type(uint8_t *packet, uint32_t packet_type)
{
packet_type = htonl(packet_type);
memcpy(packet + TBT_XD_REQUEST_PACKET_TYPE_OFFSET, &packet_type, sizeof(packet_type));
}
static inline void tbt_xd_packet_get_payload(const uint8_t *packet, void *buffer, size_t offset, size_t bytes)
{
ASSERT(offset + bytes >= offset);
ASSERT(offset < TBT_XD_REQUEST_MAX_PAYLOAD);
ASSERT(offset + bytes <= TBT_XD_REQUEST_MAX_PAYLOAD);
memcpy(buffer, packet + TBT_XD_REQUEST_HEADER_LEN + offset, bytes);
}
static inline void tbt_xd_packet_set_payload(uint8_t *packet, const void *buffer, size_t offset, size_t bytes)
{
ASSERT(offset + bytes >= offset);
ASSERT(offset < TBT_XD_REQUEST_MAX_PAYLOAD);
ASSERT(offset + bytes <= TBT_XD_REQUEST_MAX_PAYLOAD);
memcpy(packet + TBT_XD_REQUEST_HEADER_LEN + offset, buffer, bytes);
}
static inline uint32_t tbt_xd_packet_get_payload_dword(const uint8_t *packet, size_t offset)
{
uint32_t dword;
tbt_xd_packet_get_payload(packet, &dword, offset, sizeof(dword));
return ntohl(dword);
}
static inline void tbt_xd_packet_set_payload_dword(uint8_t *packet, uint32_t dword, size_t offset)
{
dword = htonl(dword);
tbt_xd_packet_set_payload(packet, &dword, offset, sizeof(dword));
}
#endif