2 * udbg debug output routine via GELIC UDP broadcasts
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2006, 2007 Sony Corporation
6 * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
7 * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
16 #include <linux/if_ether.h>
17 #include <linux/etherdevice.h>
18 #include <linux/if_vlan.h>
20 #include <linux/udp.h>
24 #include <asm/lv1call.h>
26 #define GELIC_BUS_ID 1
27 #define GELIC_DEVICE_ID 0
28 #define GELIC_DEBUG_PORT 18194
29 #define GELIC_MAX_MESSAGE_SIZE 1000
31 #define GELIC_LV1_GET_MAC_ADDRESS 1
32 #define GELIC_LV1_GET_VLAN_ID 4
33 #define GELIC_LV1_VLAN_TX_ETHERNET_0 2
35 #define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
36 #define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
38 #define GELIC_DESCR_TX_DMA_IKE 0x00080000
39 #define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
40 #define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
42 #define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
43 GELIC_DESCR_TX_DMA_IKE | \
44 GELIC_DESCR_TX_DMA_NO_CHKSUM)
49 /* as defined by the hardware */
52 __be32 next_descr_addr
;
53 __be32 dmac_cmd_status
;
55 __be32 valid_size
; /* all zeroes for tx */
57 __be32 data_error
; /* all zeroes for tx */
58 } __attribute__((aligned(32)));
61 struct gelic_descr descr
;
65 static __iomem
struct ethhdr
*h_eth
;
66 static __iomem
struct vlan_hdr
*h_vlan
;
67 static __iomem
struct iphdr
*h_ip
;
68 static __iomem
struct udphdr
*h_udp
;
70 static __iomem
char *pmsg
;
71 static __iomem
char *pmsgc
;
73 static __iomem
struct debug_block dbg
__attribute__((aligned(32)));
75 static int header_size
;
77 static void map_dma_mem(int bus_id
, int dev_id
, void *start
, size_t len
,
81 u64 real_addr
= ((u64
)start
) & 0x0fffffffffffffffUL
;
82 u64 real_end
= real_addr
+ len
;
83 u64 map_start
= real_addr
& ~0xfff;
84 u64 map_end
= (real_end
+ 0xfff) & ~0xfff;
87 u64 flags
= 0xf800000000000000UL
;
89 result
= lv1_allocate_device_dma_region(bus_id
, dev_id
,
90 map_end
- map_start
, 12, 0,
95 result
= lv1_map_device_dma_region(bus_id
, dev_id
, map_start
,
96 bus_addr
, map_end
- map_start
,
101 *real_bus_addr
= bus_addr
+ real_addr
- map_start
;
104 static int unmap_dma_mem(int bus_id
, int dev_id
, u64 bus_addr
, size_t len
)
109 real_bus_addr
= bus_addr
& ~0xfff;
110 len
+= bus_addr
- real_bus_addr
;
111 len
= (len
+ 0xfff) & ~0xfff;
113 result
= lv1_unmap_device_dma_region(bus_id
, dev_id
, real_bus_addr
,
118 return lv1_free_device_dma_region(bus_id
, dev_id
, real_bus_addr
);
121 static void gelic_debug_init(void)
128 result
= lv1_open_device(GELIC_BUS_ID
, GELIC_DEVICE_ID
, 0);
132 map_dma_mem(GELIC_BUS_ID
, GELIC_DEVICE_ID
, &dbg
, sizeof(dbg
),
135 memset(&dbg
, 0, sizeof(dbg
));
137 dbg
.descr
.buf_addr
= bus_addr
+ offsetof(struct debug_block
, pkt
);
141 result
= lv1_net_control(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
142 GELIC_LV1_GET_MAC_ADDRESS
, 0, 0, 0,
149 h_eth
= (struct ethhdr
*)dbg
.pkt
;
151 eth_broadcast_addr(h_eth
->h_dest
);
152 memcpy(&h_eth
->h_source
, &mac
, ETH_ALEN
);
154 header_size
= sizeof(struct ethhdr
);
156 result
= lv1_net_control(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
157 GELIC_LV1_GET_VLAN_ID
,
158 GELIC_LV1_VLAN_TX_ETHERNET_0
, 0, 0,
161 h_eth
->h_proto
= ETH_P_8021Q
;
163 header_size
+= sizeof(struct vlan_hdr
);
164 h_vlan
= (struct vlan_hdr
*)(h_eth
+ 1);
165 h_vlan
->h_vlan_TCI
= vlan_id
;
166 h_vlan
->h_vlan_encapsulated_proto
= ETH_P_IP
;
167 h_ip
= (struct iphdr
*)(h_vlan
+ 1);
169 h_eth
->h_proto
= 0x0800;
170 h_ip
= (struct iphdr
*)(h_eth
+ 1);
173 header_size
+= sizeof(struct iphdr
);
177 h_ip
->protocol
= 0x11;
178 h_ip
->saddr
= 0x00000000;
179 h_ip
->daddr
= 0xffffffff;
181 header_size
+= sizeof(struct udphdr
);
182 h_udp
= (struct udphdr
*)(h_ip
+ 1);
183 h_udp
->source
= GELIC_DEBUG_PORT
;
184 h_udp
->dest
= GELIC_DEBUG_PORT
;
186 pmsgc
= pmsg
= (char *)(h_udp
+ 1);
189 static void gelic_debug_shutdown(void)
192 unmap_dma_mem(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
193 bus_addr
, sizeof(dbg
));
194 lv1_close_device(GELIC_BUS_ID
, GELIC_DEVICE_ID
);
197 static void gelic_sendbuf(int msgsize
)
203 dbg
.descr
.buf_size
= header_size
+ msgsize
;
204 h_ip
->tot_len
= msgsize
+ sizeof(struct udphdr
) +
205 sizeof(struct iphdr
);
206 h_udp
->len
= msgsize
+ sizeof(struct udphdr
);
211 for (i
= 0; i
< 5; i
++)
213 h_ip
->check
= ~(sum
+ (sum
>> 16));
215 dbg
.descr
.dmac_cmd_status
= GELIC_DESCR_DMA_CMD_NO_CHKSUM
|
216 GELIC_DESCR_TX_DMA_FRAME_TAIL
;
217 dbg
.descr
.result_size
= 0;
218 dbg
.descr
.data_status
= 0;
222 lv1_net_start_tx_dma(GELIC_BUS_ID
, GELIC_DEVICE_ID
, bus_addr
, 0);
224 while ((dbg
.descr
.dmac_cmd_status
& GELIC_DESCR_DMA_STAT_MASK
) ==
225 GELIC_DESCR_DMA_CARDOWNED
)
229 static void ps3gelic_udbg_putc(char ch
)
232 if (ch
== '\n' || (pmsgc
-pmsg
) >= GELIC_MAX_MESSAGE_SIZE
) {
233 gelic_sendbuf(pmsgc
-pmsg
);
238 void __init
udbg_init_ps3gelic(void)
241 udbg_putc
= ps3gelic_udbg_putc
;
244 void udbg_shutdown_ps3gelic(void)
247 gelic_debug_shutdown();
249 EXPORT_SYMBOL(udbg_shutdown_ps3gelic
);