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.
18 #include <asm/lv1call.h>
20 #define GELIC_BUS_ID 1
21 #define GELIC_DEVICE_ID 0
22 #define GELIC_DEBUG_PORT 18194
23 #define GELIC_MAX_MESSAGE_SIZE 1000
25 #define GELIC_LV1_GET_MAC_ADDRESS 1
26 #define GELIC_LV1_GET_VLAN_ID 4
27 #define GELIC_LV1_VLAN_TX_ETHERNET_0 2
29 #define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
30 #define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
32 #define GELIC_DESCR_TX_DMA_IKE 0x00080000
33 #define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
34 #define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
36 #define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
37 GELIC_DESCR_TX_DMA_IKE | \
38 GELIC_DESCR_TX_DMA_NO_CHKSUM)
43 /* as defined by the hardware */
46 __be32 next_descr_addr
;
47 __be32 dmac_cmd_status
;
49 __be32 valid_size
; /* all zeroes for tx */
51 __be32 data_error
; /* all zeroes for tx */
52 } __attribute__((aligned(32)));
55 struct gelic_descr descr
;
90 static __iomem
struct ethhdr
*h_eth
;
91 static __iomem
struct vlantag
*h_vlan
;
92 static __iomem
struct iphdr
*h_ip
;
93 static __iomem
struct udphdr
*h_udp
;
95 static __iomem
char *pmsg
;
96 static __iomem
char *pmsgc
;
98 static __iomem
struct debug_block dbg
__attribute__((aligned(32)));
100 static int header_size
;
102 static void map_dma_mem(int bus_id
, int dev_id
, void *start
, size_t len
,
106 u64 real_addr
= ((u64
)start
) & 0x0fffffffffffffffUL
;
107 u64 real_end
= real_addr
+ len
;
108 u64 map_start
= real_addr
& ~0xfff;
109 u64 map_end
= (real_end
+ 0xfff) & ~0xfff;
112 u64 flags
= 0xf800000000000000UL
;
114 result
= lv1_allocate_device_dma_region(bus_id
, dev_id
,
115 map_end
- map_start
, 12, 0,
120 result
= lv1_map_device_dma_region(bus_id
, dev_id
, map_start
,
121 bus_addr
, map_end
- map_start
,
126 *real_bus_addr
= bus_addr
+ real_addr
- map_start
;
129 static int unmap_dma_mem(int bus_id
, int dev_id
, u64 bus_addr
, size_t len
)
134 real_bus_addr
= bus_addr
& ~0xfff;
135 len
+= bus_addr
- real_bus_addr
;
136 len
= (len
+ 0xfff) & ~0xfff;
138 result
= lv1_unmap_device_dma_region(bus_id
, dev_id
, real_bus_addr
,
143 return lv1_free_device_dma_region(bus_id
, dev_id
, real_bus_addr
);
146 static void gelic_debug_init(void)
153 result
= lv1_open_device(GELIC_BUS_ID
, GELIC_DEVICE_ID
, 0);
157 map_dma_mem(GELIC_BUS_ID
, GELIC_DEVICE_ID
, &dbg
, sizeof(dbg
),
160 memset(&dbg
, 0, sizeof(dbg
));
162 dbg
.descr
.buf_addr
= bus_addr
+ offsetof(struct debug_block
, pkt
);
166 result
= lv1_net_control(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
167 GELIC_LV1_GET_MAC_ADDRESS
, 0, 0, 0,
174 h_eth
= (struct ethhdr
*)dbg
.pkt
;
176 memset(&h_eth
->dest
, 0xff, 6);
177 memcpy(&h_eth
->src
, &mac
, 6);
179 header_size
= sizeof(struct ethhdr
);
181 result
= lv1_net_control(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
182 GELIC_LV1_GET_VLAN_ID
,
183 GELIC_LV1_VLAN_TX_ETHERNET_0
, 0, 0,
186 h_eth
->type
= 0x8100;
188 header_size
+= sizeof(struct vlantag
);
189 h_vlan
= (struct vlantag
*)(h_eth
+ 1);
190 h_vlan
->vlan
= vlan_id
;
191 h_vlan
->subtype
= 0x0800;
192 h_ip
= (struct iphdr
*)(h_vlan
+ 1);
194 h_eth
->type
= 0x0800;
195 h_ip
= (struct iphdr
*)(h_eth
+ 1);
198 header_size
+= sizeof(struct iphdr
);
199 h_ip
->ver_len
= 0x45;
202 h_ip
->src
= 0x00000000;
203 h_ip
->dest
= 0xffffffff;
205 header_size
+= sizeof(struct udphdr
);
206 h_udp
= (struct udphdr
*)(h_ip
+ 1);
207 h_udp
->src
= GELIC_DEBUG_PORT
;
208 h_udp
->dest
= GELIC_DEBUG_PORT
;
210 pmsgc
= pmsg
= (char *)(h_udp
+ 1);
213 static void gelic_debug_shutdown(void)
216 unmap_dma_mem(GELIC_BUS_ID
, GELIC_DEVICE_ID
,
217 bus_addr
, sizeof(dbg
));
218 lv1_close_device(GELIC_BUS_ID
, GELIC_DEVICE_ID
);
221 static void gelic_sendbuf(int msgsize
)
227 dbg
.descr
.buf_size
= header_size
+ msgsize
;
228 h_ip
->total_length
= msgsize
+ sizeof(struct udphdr
) +
229 sizeof(struct iphdr
);
230 h_udp
->len
= msgsize
+ sizeof(struct udphdr
);
235 for (i
= 0; i
< 5; i
++)
237 h_ip
->checksum
= ~(sum
+ (sum
>> 16));
239 dbg
.descr
.dmac_cmd_status
= GELIC_DESCR_DMA_CMD_NO_CHKSUM
|
240 GELIC_DESCR_TX_DMA_FRAME_TAIL
;
241 dbg
.descr
.result_size
= 0;
242 dbg
.descr
.data_status
= 0;
246 lv1_net_start_tx_dma(GELIC_BUS_ID
, GELIC_DEVICE_ID
, bus_addr
, 0);
248 while ((dbg
.descr
.dmac_cmd_status
& GELIC_DESCR_DMA_STAT_MASK
) ==
249 GELIC_DESCR_DMA_CARDOWNED
)
253 static void ps3gelic_udbg_putc(char ch
)
256 if (ch
== '\n' || (pmsgc
-pmsg
) >= GELIC_MAX_MESSAGE_SIZE
) {
257 gelic_sendbuf(pmsgc
-pmsg
);
262 void __init
udbg_init_ps3gelic(void)
265 udbg_putc
= ps3gelic_udbg_putc
;
268 void udbg_shutdown_ps3gelic(void)
271 gelic_debug_shutdown();
273 EXPORT_SYMBOL(udbg_shutdown_ps3gelic
);