Changes for 4.5.0 snapshot
[newlib-cygwin.git] / libgloss / arc / hl / hl_gw.c
blob4a8f8780f46bfcdf40c527bb3615091483f45ce9
1 /*
2 * hl_gw.c -- Hostlink gateway, low-level hostlink functions.
4 * Copyright (c) 2024 Synopsys Inc.
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.
18 #include <stdint.h>
19 #include "hl_gw.h"
21 #define HL_VERSION 1
25 * Maximum message size without service information,
26 * see also HL_PAYLOAD_RESERVED.
28 #ifndef HL_IOCHUNK
29 #define HL_IOCHUNK 1024
30 #endif
33 * Each syscall argument have 4 bytes of service information in hostlink
34 * protocol (2 bytes for type and 2 for size). Here we reserve space for
35 * 32 arguments.
37 #define HL_PAYLOAD_RESERVED (32 * 4)
39 /* "No message here" mark. */
40 #define HL_NOADDRESS 0xFFFFFFFF
42 /* Hostlink gateway structure. */
43 struct _hl_hdr {
44 uint32_t version; /* Current version is 1. */
45 uint32_t target2host_addr; /* Packet address from target to host. */
46 uint32_t host2target_addr; /* Packet address from host to target. */
47 uint32_t buf_addr; /* Address for host to write answer. */
48 uint32_t payload_size; /* Buffer size without packet header. */
49 uint32_t options; /* For future use. */
50 uint32_t break_to_mon_addr; /* For future use. */
51 } __uncached __packed;
53 /* Hostlink packet header. */
54 struct _hl_pkt_hdr {
55 uint32_t packet_id; /* Packet id. Always set to 1 here. */
56 uint32_t total_size; /* Size of packet including header. */
57 uint32_t priority; /* For future use. */
58 uint32_t type; /* For future use. */
59 uint32_t checksum; /* For future use. */
60 } __uncached __packed;
62 /* Main hostlink structure. */
63 struct _hl {
64 volatile struct _hl_hdr hdr; /* General hostlink information. */
65 /* Start of the hostlink buffer. */
66 volatile struct _hl_pkt_hdr pkt_hdr;
67 volatile char payload[HL_IOCHUNK + HL_PAYLOAD_RESERVED];
68 } __aligned (HL_MAX_DCACHE_LINE) __uncached __packed;
72 * Main structure. Do not rename because simulator will look for the
73 * '__HOSTLINK__' symbol.
75 volatile struct _hl __HOSTLINK__ = {
76 .hdr = {
77 .version = 1 ,
78 .target2host_addr = HL_NOADDRESS
82 /* Get hostlink payload pointer. */
83 volatile __uncached void *
84 _hl_payload (void)
86 return (volatile __uncached void *) &__HOSTLINK__.payload[0];
89 /* Get hostlink payload size (iochunk + reserved space). */
90 static uint32_t
91 _hl_payload_size (void)
93 return sizeof (__HOSTLINK__.payload);
96 /* Get used space size in the payload. */
97 static uint32_t
98 _hl_payload_used (volatile __uncached void *p)
100 return (volatile __uncached char *) p
101 - (volatile __uncached char *) _hl_payload ();
104 /* Fill hostlink packet header. */
105 static void
106 _hl_pkt_init (volatile __uncached struct _hl_pkt_hdr *pkt, int size)
108 pkt->packet_id = 1;
109 pkt->total_size = ALIGN (size, 4) + sizeof (*pkt);
110 pkt->priority = 0;
111 pkt->type = 0;
112 pkt->checksum = 0;
115 /* Get hostlink iochunk size. */
116 uint32_t
117 _hl_iochunk_size (void)
119 return HL_IOCHUNK;
122 /* Get free space size in the payload. */
123 uint32_t
124 _hl_payload_left (volatile __uncached void *p)
126 return _hl_payload_size () - _hl_payload_used (p);
129 /* Send hostlink packet to the host. */
130 void
131 _hl_send (volatile __uncached void *p)
133 volatile __uncached struct _hl_hdr *hdr = &__HOSTLINK__.hdr;
134 volatile __uncached struct _hl_pkt_hdr *pkt_hdr = &__HOSTLINK__.pkt_hdr;
136 _hl_pkt_init (pkt_hdr, _hl_payload_used (p));
138 #if defined (__ARC64__)
140 * Here we pass only low 4 bytes of the packet address (pkt_hdr).
141 * The high part of the address is obtained from __HOSTLINK__ address.
143 hdr->buf_addr = (uintptr_t) pkt_hdr & 0xFFFFFFFF;
144 #else
145 hdr->buf_addr = (uint32_t) pkt_hdr;
146 #endif
147 hdr->payload_size = _hl_payload_size ();
148 hdr->host2target_addr = HL_NOADDRESS;
149 hdr->version = HL_VERSION;
150 hdr->options = 0;
151 hdr->break_to_mon_addr = 0;
153 /* This tells the debugger we have a command.
154 * It is responsibility of debugger to set this back to HL_NOADDRESS
155 * after receiving the packet.
156 * Please note that we don't wait here because some implementations
157 * use _hl_blockedPeek() function as a signal that we send a messege.
159 hdr->target2host_addr = hdr->buf_addr;
163 * Wait for host response and return pointer to hostlink payload.
164 * Symbol _hl_blockedPeek() is used by the simulator as message signal.
166 volatile __uncached char * __noinline
167 _hl_blockedPeek (void)
169 while (__HOSTLINK__.hdr.host2target_addr == HL_NOADDRESS)
171 /* TODO: Timeout. */
174 return _hl_payload ();
177 /* Get message from host. */
178 volatile __uncached char *
179 _hl_recv (void)
181 return _hl_blockedPeek ();
184 /* Mark hostlink buffer as "No message here". */
185 void
186 _hl_delete (void)
188 __HOSTLINK__.hdr.target2host_addr = HL_NOADDRESS;