1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * udbg debug output routine via GELIC UDP broadcasts
5 * Copyright (C) 2007 Sony Computer Entertainment Inc.
6 * Copyright 2006, 2007 Sony Corporation
7 * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
8 * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
11 #include <linux/if_ether.h>
12 #include <linux/etherdevice.h>
13 #include <linux/if_vlan.h>
15 #include <linux/udp.h>
19 #include <asm/lv1call.h>
21 #define GELIC_BUS_ID 1
22 #define GELIC_DEVICE_ID 0
23 #define GELIC_DEBUG_PORT 18194
24 #define GELIC_MAX_MESSAGE_SIZE 1000
26 #define GELIC_LV1_GET_MAC_ADDRESS 1
27 #define GELIC_LV1_GET_VLAN_ID 4
28 #define GELIC_LV1_VLAN_TX_ETHERNET_0 2
30 #define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
31 #define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
33 #define GELIC_DESCR_TX_DMA_IKE 0x00080000
34 #define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
35 #define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
37 #define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
38 GELIC_DESCR_TX_DMA_IKE | \
39 GELIC_DESCR_TX_DMA_NO_CHKSUM)
44 /* as defined by the hardware */
47 __be32 next_descr_addr
;
48 __be32 dmac_cmd_status
;
50 __be32 valid_size
; /* all zeroes for tx */
52 __be32 data_error
; /* all zeroes for tx */
53 } __attribute__((aligned(32)));
56 struct gelic_descr descr
;
60 static __iomem
struct ethhdr
*h_eth
;
61 static __iomem
struct vlan_hdr
*h_vlan
;
62 static __iomem
struct iphdr
*h_ip
;
63 static __iomem
struct udphdr
*h_udp
;
65 static __iomem
char *pmsg
;
66 static __iomem
char *pmsgc
;
68 static __iomem
struct debug_block dbg
__attribute__((aligned(32)));
70 static int header_size
;
72 static void map_dma_mem(int bus_id
, int dev_id
, void *start
, size_t len
,
76 u64 real_addr
= ((u64
)start
) & 0x0fffffffffffffffUL
;
77 u64 real_end
= real_addr
+ len
;
78 u64 map_start
= real_addr
& ~0xfff;
79 u64 map_end
= (real_end
+ 0xfff) & ~0xfff;
82 u64 flags
= 0xf800000000000000UL
;
84 result
= lv1_allocate_device_dma_region(bus_id
, dev_id
,
85 map_end
- map_start
, 12, 0,
90 result
= lv1_map_device_dma_region(bus_id
, dev_id
, map_start
,
91 bus_addr
, map_end
- map_start
,
96 *real_bus_addr
= bus_addr
+ real_addr
- map_start
;
99 static int unmap_dma_mem(int bus_id
, int dev_id
, u64 bus_addr
, size_t len
)
104 real_bus_addr
= bus_addr
& ~0xfff;
105 len
+= bus_addr
- real_bus_addr
;
106 len
= (len
+ 0xfff) & ~0xfff;
108 result
= lv1_unmap_device_dma_region(bus_id
, dev_id
, real_bus_addr
,
113 return lv1_free_device_dma_region(bus_id
, dev_id
, real_bus_addr
);
116 static void gelic_debug_init(void)
123 result
= lv1_open_device(GELIC_BUS_ID
, GELIC_DEVICE_ID
, 0);
127 map_dma_mem(GELIC_BUS_ID
, GELIC_DEVICE_ID
, &dbg
, sizeof(dbg
),
130 memset(&dbg
, 0, sizeof(dbg
));
132 dbg
.descr
.buf_addr
= bus_addr
+ offsetof(struct debug_block
, pkt
);
136 result
= lv1_net_control(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
137 GELIC_LV1_GET_MAC_ADDRESS
, 0, 0, 0,
144 h_eth
= (struct ethhdr
*)dbg
.pkt
;
146 eth_broadcast_addr(h_eth
->h_dest
);
147 memcpy(&h_eth
->h_source
, &mac
, ETH_ALEN
);
149 header_size
= sizeof(struct ethhdr
);
151 result
= lv1_net_control(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
152 GELIC_LV1_GET_VLAN_ID
,
153 GELIC_LV1_VLAN_TX_ETHERNET_0
, 0, 0,
156 h_eth
->h_proto
= ETH_P_8021Q
;
158 header_size
+= sizeof(struct vlan_hdr
);
159 h_vlan
= (struct vlan_hdr
*)(h_eth
+ 1);
160 h_vlan
->h_vlan_TCI
= vlan_id
;
161 h_vlan
->h_vlan_encapsulated_proto
= ETH_P_IP
;
162 h_ip
= (struct iphdr
*)(h_vlan
+ 1);
164 h_eth
->h_proto
= 0x0800;
165 h_ip
= (struct iphdr
*)(h_eth
+ 1);
168 header_size
+= sizeof(struct iphdr
);
172 h_ip
->protocol
= 0x11;
173 h_ip
->saddr
= 0x00000000;
174 h_ip
->daddr
= 0xffffffff;
176 header_size
+= sizeof(struct udphdr
);
177 h_udp
= (struct udphdr
*)(h_ip
+ 1);
178 h_udp
->source
= GELIC_DEBUG_PORT
;
179 h_udp
->dest
= GELIC_DEBUG_PORT
;
181 pmsgc
= pmsg
= (char *)(h_udp
+ 1);
184 static void gelic_debug_shutdown(void)
187 unmap_dma_mem(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
188 bus_addr
, sizeof(dbg
));
189 lv1_close_device(GELIC_BUS_ID
, GELIC_DEVICE_ID
);
192 static void gelic_sendbuf(int msgsize
)
198 dbg
.descr
.buf_size
= header_size
+ msgsize
;
199 h_ip
->tot_len
= msgsize
+ sizeof(struct udphdr
) +
200 sizeof(struct iphdr
);
201 h_udp
->len
= msgsize
+ sizeof(struct udphdr
);
206 for (i
= 0; i
< 5; i
++)
208 h_ip
->check
= ~(sum
+ (sum
>> 16));
210 dbg
.descr
.dmac_cmd_status
= GELIC_DESCR_DMA_CMD_NO_CHKSUM
|
211 GELIC_DESCR_TX_DMA_FRAME_TAIL
;
212 dbg
.descr
.result_size
= 0;
213 dbg
.descr
.data_status
= 0;
217 lv1_net_start_tx_dma(GELIC_BUS_ID
, GELIC_DEVICE_ID
, bus_addr
, 0);
219 while ((dbg
.descr
.dmac_cmd_status
& GELIC_DESCR_DMA_STAT_MASK
) ==
220 GELIC_DESCR_DMA_CARDOWNED
)
224 static void ps3gelic_udbg_putc(char ch
)
227 if (ch
== '\n' || (pmsgc
-pmsg
) >= GELIC_MAX_MESSAGE_SIZE
) {
228 gelic_sendbuf(pmsgc
-pmsg
);
233 void __init
udbg_init_ps3gelic(void)
236 udbg_putc
= ps3gelic_udbg_putc
;
239 void udbg_shutdown_ps3gelic(void)
242 gelic_debug_shutdown();
244 EXPORT_SYMBOL(udbg_shutdown_ps3gelic
);