2 * Copyright (c) 2015 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
21 #ifndef __FIREHOSE_BUFFER_PRIVATE__
22 #define __FIREHOSE_BUFFER_PRIVATE__
29 #include <os/base_private.h>
30 #include <dispatch/dispatch.h>
33 #define OS_FIREHOSE_SPI_VERSION 20160318
37 * SPI intended for logd only
38 * Layout of structs is subject to change without notice
41 #define FIREHOSE_BUFFER_CHUNK_SIZE 4096ul
42 #define FIREHOSE_BUFFER_LIBTRACE_HEADER_SIZE 2048ul
43 #define FIREHOSE_BUFFER_KERNEL_CHUNK_COUNT 16
46 uint64_t fbc_atomic_pos
;
47 #define FIREHOSE_BUFFER_POS_ENTRY_OFFS_INC (1ULL << 0)
48 #define FIREHOSE_BUFFER_POS_PRIVATE_OFFS_INC (1ULL << 16)
49 #define FIREHOSE_BUFFER_POS_REFCNT_INC (1ULL << 32)
50 #define FIREHOSE_BUFFER_POS_FULL_BIT (1ULL << 56)
51 #define FIREHOSE_BUFFER_POS_USABLE_FOR_STREAM(pos, stream) \
52 ((((pos).fbc_atomic_pos >> 48) & 0x1ff) == (uint16_t)stream)
54 uint16_t fbc_next_entry_offs
;
55 uint16_t fbc_private_offs
;
59 uint8_t fbc_flag_full
: 1;
60 uint8_t fbc_flag_io
: 1;
61 uint8_t _fbc_flag_unused
: 6;
63 } firehose_buffer_pos_u
;
65 typedef struct firehose_buffer_chunk_s
{
67 firehose_buffer_pos_u
volatile fbc_pos
;
68 uint64_t fbc_timestamp
;
69 uint8_t fbc_data
[FIREHOSE_BUFFER_CHUNK_SIZE
70 - sizeof(firehose_buffer_pos_u
)
72 } __attribute__((aligned(8))) *firehose_buffer_chunk_t
;
74 typedef struct firehose_buffer_range_s
{
75 uint16_t fbr_offset
; // offset from the start of the buffer
77 } *firehose_buffer_range_t
;
81 // implemented by the kernel
82 extern void __firehose_buffer_push_to_logd(firehose_buffer_t fb
, bool for_io
);
83 extern void __firehose_critical_region_enter(void);
84 extern void __firehose_critical_region_leave(void);
85 extern void __firehose_allocate(vm_offset_t
*addr
, vm_size_t size
);
87 // exported for the kernel
89 __firehose_buffer_tracepoint_reserve(uint64_t stamp
, firehose_stream_t stream
,
90 uint16_t pubsize
, uint16_t privsize
, uint8_t **privptr
);
93 __firehose_buffer_tracepoint_reserve_with_chunk(firehose_buffer_chunk_t fbc
,
94 uint64_t stamp
, firehose_stream_t stream
,
95 uint16_t pubsize
, uint16_t privsize
, uint8_t **privptr
);
98 __firehose_buffer_tracepoint_flush(firehose_tracepoint_t vat
,
99 firehose_tracepoint_id_u vatid
);
102 __firehose_buffer_tracepoint_flush_chunk(firehose_buffer_chunk_t fbc
,
103 firehose_tracepoint_t vat
, firehose_tracepoint_id_u vatid
);
106 __firehose_buffer_create(size_t *size
);
109 __firehose_merge_updates(firehose_push_reply_t update
);
113 #define __firehose_critical_region_enter()
114 #define __firehose_critical_region_leave()
117 const uint32_t _firehose_spi_version
;
120 static inline const uint8_t *
121 _firehose_tracepoint_reader_init(firehose_buffer_chunk_t fbc
,
122 const uint8_t **endptr
)
124 const uint8_t *start
= fbc
->fbc_data
;
125 const uint8_t *end
= fbc
->fbc_start
+ fbc
->fbc_pos
.fbc_next_entry_offs
;
127 if (end
> fbc
->fbc_start
+ FIREHOSE_BUFFER_CHUNK_SIZE
) {
135 static inline firehose_tracepoint_t
136 _firehose_tracepoint_reader_next(const uint8_t **ptr
, const uint8_t *end
)
138 const uint16_t ft_size
= offsetof(struct firehose_tracepoint_s
, ft_data
);
139 firehose_tracepoint_t ft
;
142 ft
= (firehose_tracepoint_t
)*ptr
;
143 if (ft
->ft_data
>= end
) {
147 if (!ft
->ft_length
) {
148 // tracepoint write didn't even start
151 if (ft
->ft_length
> end
- ft
->ft_data
) {
155 *ptr
+= roundup(ft_size
+ ft
->ft_length
, 8);
156 // test whether write of the tracepoint was finished
157 } while (os_unlikely(ft
->ft_id
.ftid_value
== 0));
162 #define firehose_tracepoint_foreach(ft, fbc) \
163 for (const uint8_t *end, *p = _firehose_tracepoint_reader_init(fbc, &end); \
164 ((ft) = _firehose_tracepoint_reader_next(&p, end)); )
168 firehose_buffer_range_validate(firehose_buffer_chunk_t fbc
,
169 firehose_tracepoint_t ft
, firehose_buffer_range_t range
)
171 if (range
->fbr_offset
+ range
->fbr_length
> FIREHOSE_BUFFER_CHUNK_SIZE
) {
174 if (fbc
->fbc_start
+ range
->fbr_offset
< ft
->ft_data
+ ft
->ft_length
) {
182 #endif // OS_FIREHOSE_SPI
184 #endif // __FIREHOSE_BUFFER_PRIVATE__