]>
Commit | Line | Data |
---|---|---|
6d533105 VI |
1 | /* |
2 | * hl_gw.c -- Hostlink gateway, low-level hostlink functions. | |
3 | * | |
4 | * Copyright (c) 2024 Synopsys Inc. | |
5 | * | |
6 | * The authors hereby grant permission to use, copy, modify, distribute, | |
7 | * and license this software and its documentation for any purpose, provided | |
8 | * that existing copyright notices are retained in all copies and that this | |
9 | * notice is included verbatim in any distributions. No written agreement, | |
10 | * license, or royalty fee is required for any of the authorized uses. | |
11 | * Modifications to this software may be copyrighted by their authors | |
12 | * and need not follow the licensing terms described here, provided that | |
13 | * the new terms are clearly indicated on the first page of each file where | |
14 | * they apply. | |
15 | * | |
16 | */ | |
17 | ||
18 | #include "hl_gw.h" | |
19 | ||
20 | #define HL_VERSION 1 | |
21 | ||
22 | ||
23 | /* | |
24 | * Maximum message size without service information, | |
25 | * see also HL_PAYLOAD_RESERVED. | |
26 | */ | |
27 | #ifndef HL_IOCHUNK | |
28 | #define HL_IOCHUNK 1024 | |
29 | #endif | |
30 | ||
31 | /* | |
32 | * Each syscall argument have 4 bytes of service information in hostlink | |
33 | * protocol (2 bytes for type and 2 for size). Here we reserve space for | |
34 | * 32 arguments. | |
35 | */ | |
36 | #define HL_PAYLOAD_RESERVED (32 * 4) | |
37 | ||
38 | /* "No message here" mark. */ | |
39 | #define HL_NOADDRESS 0xFFFFFFFF | |
40 | ||
41 | /* Hostlink gateway structure. */ | |
42 | struct _hl_hdr { | |
43 | uint32_t version; /* Current version is 1. */ | |
44 | uint32_t target2host_addr; /* Packet address from target to host. */ | |
45 | uint32_t host2target_addr; /* Packet address from host to target. */ | |
46 | uint32_t buf_addr; /* Address for host to write answer. */ | |
47 | uint32_t payload_size; /* Buffer size without packet header. */ | |
48 | uint32_t options; /* For future use. */ | |
49 | uint32_t break_to_mon_addr; /* For future use. */ | |
50 | } __uncached __packed; | |
51 | ||
52 | /* Hostlink packet header. */ | |
53 | struct _hl_pkt_hdr { | |
54 | uint32_t packet_id; /* Packet id. Always set to 1 here. */ | |
55 | uint32_t total_size; /* Size of packet including header. */ | |
56 | uint32_t priority; /* For future use. */ | |
57 | uint32_t type; /* For future use. */ | |
58 | uint32_t checksum; /* For future use. */ | |
59 | } __uncached __packed; | |
60 | ||
61 | /* Main hostlink structure. */ | |
62 | struct _hl { | |
63 | volatile struct _hl_hdr hdr; /* General hostlink information. */ | |
64 | /* Start of the hostlink buffer. */ | |
65 | volatile struct _hl_pkt_hdr pkt_hdr; | |
66 | volatile char payload[HL_IOCHUNK + HL_PAYLOAD_RESERVED]; | |
67 | } __aligned (HL_MAX_DCACHE_LINE) __uncached __packed; | |
68 | ||
69 | ||
70 | /* | |
71 | * Main structure. Do not rename because simulator will look for the | |
72 | * '__HOSTLINK__' symbol. | |
73 | */ | |
74 | volatile struct _hl __HOSTLINK__ = { | |
75 | .hdr = { | |
76 | .version = 1 , | |
77 | .target2host_addr = HL_NOADDRESS | |
78 | } | |
79 | }; | |
80 | ||
81 | /* Get hostlink payload pointer. */ | |
82 | volatile __uncached void * | |
83 | _hl_payload (void) | |
84 | { | |
85 | return (volatile __uncached void *) &__HOSTLINK__.payload[0]; | |
86 | } | |
87 | ||
88 | /* Get hostlink payload size (iochunk + reserved space). */ | |
89 | static uint32_t | |
90 | _hl_payload_size (void) | |
91 | { | |
92 | return sizeof (__HOSTLINK__.payload); | |
93 | } | |
94 | ||
95 | /* Get used space size in the payload. */ | |
96 | static uint32_t | |
97 | _hl_payload_used (volatile __uncached void *p) | |
98 | { | |
99 | return (volatile __uncached char *) p | |
100 | - (volatile __uncached char *) _hl_payload (); | |
101 | } | |
102 | ||
103 | /* Fill hostlink packet header. */ | |
104 | static void | |
105 | _hl_pkt_init (volatile __uncached struct _hl_pkt_hdr *pkt, int size) | |
106 | { | |
107 | pkt->packet_id = 1; | |
108 | pkt->total_size = ALIGN (size, 4) + sizeof (*pkt); | |
109 | pkt->priority = 0; | |
110 | pkt->type = 0; | |
111 | pkt->checksum = 0; | |
112 | } | |
113 | ||
114 | /* Get hostlink iochunk size. */ | |
115 | uint32_t | |
116 | _hl_iochunk_size (void) | |
117 | { | |
118 | return HL_IOCHUNK; | |
119 | } | |
120 | ||
121 | /* Get free space size in the payload. */ | |
122 | uint32_t | |
123 | _hl_payload_left (volatile __uncached void *p) | |
124 | { | |
125 | return _hl_payload_size () - _hl_payload_used (p); | |
126 | } | |
127 | ||
128 | /* Send hostlink packet to the host. */ | |
129 | void | |
130 | _hl_send (volatile __uncached void *p) | |
131 | { | |
132 | volatile __uncached struct _hl_hdr *hdr = &__HOSTLINK__.hdr; | |
133 | volatile __uncached struct _hl_pkt_hdr *pkt_hdr = &__HOSTLINK__.pkt_hdr; | |
134 | ||
135 | _hl_pkt_init (pkt_hdr, _hl_payload_used (p)); | |
136 | ||
137 | hdr->buf_addr = (uint32_t) pkt_hdr; | |
138 | hdr->payload_size = _hl_payload_size (); | |
139 | hdr->host2target_addr = HL_NOADDRESS; | |
140 | hdr->version = HL_VERSION; | |
141 | hdr->options = 0; | |
142 | hdr->break_to_mon_addr = 0; | |
143 | ||
144 | /* This tells the debugger we have a command. | |
145 | * It is responsibility of debugger to set this back to HL_NOADDRESS | |
146 | * after receiving the packet. | |
147 | * Please note that we don't wait here because some implementations | |
148 | * use _hl_blockedPeek() function as a signal that we send a messege. | |
149 | */ | |
150 | hdr->target2host_addr = hdr->buf_addr; | |
151 | } | |
152 | ||
153 | /* | |
154 | * Wait for host response and return pointer to hostlink payload. | |
155 | * Symbol _hl_blockedPeek() is used by the simulator as message signal. | |
156 | */ | |
157 | volatile __uncached char * __noinline | |
158 | _hl_blockedPeek (void) | |
159 | { | |
160 | while (__HOSTLINK__.hdr.host2target_addr == HL_NOADDRESS) | |
161 | { | |
162 | /* TODO: Timeout. */ | |
163 | } | |
164 | ||
165 | return _hl_payload (); | |
166 | } | |
167 | ||
168 | /* Get message from host. */ | |
169 | volatile __uncached char * | |
170 | _hl_recv (void) | |
171 | { | |
172 | return _hl_blockedPeek (); | |
173 | } | |
174 | ||
175 | /* Mark hostlink buffer as "No message here". */ | |
176 | void | |
177 | _hl_delete (void) | |
178 | { | |
179 | __HOSTLINK__.hdr.target2host_addr = HL_NOADDRESS; | |
180 | } |