xref: /openbmc/linux/drivers/ps3/ps3-lpm.c (revision a1e58bbd)
1 /*
2  * PS3 Logical Performance Monitor.
3  *
4  *  Copyright (C) 2007 Sony Computer Entertainment Inc.
5  *  Copyright 2007 Sony Corp.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; version 2 of the License.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/interrupt.h>
24 #include <linux/uaccess.h>
25 #include <asm/ps3.h>
26 #include <asm/lv1call.h>
27 #include <asm/cell-pmu.h>
28 
29 
30 /* BOOKMARK tag macros */
31 #define PS3_PM_BOOKMARK_START                    0x8000000000000000ULL
32 #define PS3_PM_BOOKMARK_STOP                     0x4000000000000000ULL
33 #define PS3_PM_BOOKMARK_TAG_KERNEL               0x1000000000000000ULL
34 #define PS3_PM_BOOKMARK_TAG_USER                 0x3000000000000000ULL
35 #define PS3_PM_BOOKMARK_TAG_MASK_HI              0xF000000000000000ULL
36 #define PS3_PM_BOOKMARK_TAG_MASK_LO              0x0F00000000000000ULL
37 
38 /* CBE PM CONTROL register macros */
39 #define PS3_PM_CONTROL_PPU_TH0_BOOKMARK          0x00001000
40 #define PS3_PM_CONTROL_PPU_TH1_BOOKMARK          0x00000800
41 #define PS3_PM_CONTROL_PPU_COUNT_MODE_MASK       0x000C0000
42 #define PS3_PM_CONTROL_PPU_COUNT_MODE_PROBLEM    0x00080000
43 #define PS3_WRITE_PM_MASK                        0xFFFFFFFFFFFFFFFFULL
44 
45 /* CBE PM START STOP register macros */
46 #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START 0x02000000
47 #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START 0x01000000
48 #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP  0x00020000
49 #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP  0x00010000
50 #define PS3_PM_START_STOP_START_MASK             0xFF000000
51 #define PS3_PM_START_STOP_STOP_MASK              0x00FF0000
52 
53 /* CBE PM COUNTER register macres */
54 #define PS3_PM_COUNTER_MASK_HI                   0xFFFFFFFF00000000ULL
55 #define PS3_PM_COUNTER_MASK_LO                   0x00000000FFFFFFFFULL
56 
57 /* BASE SIGNAL GROUP NUMBER macros */
58 #define PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER  0
59 #define PM_ISLAND2_SIGNAL_GROUP_NUMBER1      6
60 #define PM_ISLAND2_SIGNAL_GROUP_NUMBER2      7
61 #define PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER  7
62 #define PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER  15
63 #define PM_SPU_TRIGGER_SIGNAL_GROUP_NUMBER   17
64 #define PM_SPU_EVENT_SIGNAL_GROUP_NUMBER     18
65 #define PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER  18
66 #define PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER  24
67 #define PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER  49
68 #define PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER  52
69 #define PM_SIG_GROUP_SPU                     41
70 #define PM_SIG_GROUP_SPU_TRIGGER             42
71 #define PM_SIG_GROUP_SPU_EVENT               43
72 #define PM_SIG_GROUP_MFC_MAX                 60
73 
74 /**
75  * struct ps3_lpm_shadow_regs - Performance monitor shadow registers.
76  *
77  * @pm_control: Shadow of the processor's pm_control register.
78  * @pm_start_stop: Shadow of the processor's pm_start_stop register.
79  * @group_control: Shadow of the processor's group_control register.
80  * @debug_bus_control: Shadow of the processor's debug_bus_control register.
81  *
82  * The logical performance monitor provides a write-only interface to
83  * these processor registers.  These shadow variables cache the processor
84  * register values for reading.
85  *
86  * The initial value of the shadow registers at lpm creation is
87  * PS3_LPM_SHADOW_REG_INIT.
88  */
89 
90 struct ps3_lpm_shadow_regs {
91 	u64 pm_control;
92 	u64 pm_start_stop;
93 	u64 group_control;
94 	u64 debug_bus_control;
95 };
96 
97 #define PS3_LPM_SHADOW_REG_INIT 0xFFFFFFFF00000000ULL
98 
99 /**
100  * struct ps3_lpm_priv - Private lpm device data.
101  *
102  * @open: An atomic variable indicating the lpm driver has been opened.
103  * @rights: The lpm rigths granted by the system policy module.  A logical
104  *  OR of enum ps3_lpm_rights.
105  * @node_id: The node id of a BE prosessor whose performance monitor this
106  *  lpar has the right to use.
107  * @pu_id: The lv1 id of the logical PU.
108  * @lpm_id: The lv1 id of this lpm instance.
109  * @outlet_id: The outlet created by lv1 for this lpm instance.
110  * @tb_count: The number of bytes of data held in the lv1 trace buffer.
111  * @tb_cache: Kernel buffer to receive the data from the lv1 trace buffer.
112  *  Must be 128 byte aligned.
113  * @tb_cache_size: Size of the kernel @tb_cache buffer.  Must be 128 byte
114  *  aligned.
115  * @tb_cache_internal: An unaligned buffer allocated by this driver to be
116  *  used for the trace buffer cache when ps3_lpm_open() is called with a
117  *  NULL tb_cache argument.  Otherwise unused.
118  * @shadow: Processor register shadow of type struct ps3_lpm_shadow_regs.
119  * @sbd: The struct ps3_system_bus_device attached to this driver.
120  *
121  * The trace buffer is a buffer allocated and used internally to the lv1
122  * hypervisor to collect trace data.  The trace buffer cache is a guest
123  * buffer that accepts the trace data from the trace buffer.
124  */
125 
126 struct ps3_lpm_priv {
127 	atomic_t open;
128 	u64 rights;
129 	u64 node_id;
130 	u64 pu_id;
131 	u64 lpm_id;
132 	u64 outlet_id;
133 	u64 tb_count;
134 	void *tb_cache;
135 	u64 tb_cache_size;
136 	void *tb_cache_internal;
137 	struct ps3_lpm_shadow_regs shadow;
138 	struct ps3_system_bus_device *sbd;
139 };
140 
141 enum {
142 	PS3_LPM_DEFAULT_TB_CACHE_SIZE = 0x4000,
143 };
144 
145 /**
146  * lpm_priv - Static instance of the lpm data.
147  *
148  * Since the exported routines don't support the notion of a device
149  * instance we need to hold the instance in this static variable
150  * and then only allow at most one instance at a time to be created.
151  */
152 
153 static struct ps3_lpm_priv *lpm_priv;
154 
155 static struct device *sbd_core(void)
156 {
157 	BUG_ON(!lpm_priv || !lpm_priv->sbd);
158 	return &lpm_priv->sbd->core;
159 }
160 
161 /**
162  * use_start_stop_bookmark - Enable the PPU bookmark trace.
163  *
164  * And it enables PPU bookmark triggers ONLY if the other triggers are not set.
165  * The start/stop bookmarks are inserted at ps3_enable_pm() and ps3_disable_pm()
166  * to start/stop LPM.
167  *
168  * Used to get good quality of the performance counter.
169  */
170 
171 enum {use_start_stop_bookmark = 1,};
172 
173 void ps3_set_bookmark(u64 bookmark)
174 {
175 	/*
176 	 * As per the PPE book IV, to avoid bookmark loss there must
177 	 * not be a traced branch within 10 cycles of setting the
178 	 * SPRN_BKMK register.  The actual text is unclear if 'within'
179 	 * includes cycles before the call.
180 	 */
181 
182 	asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
183 	mtspr(SPRN_BKMK, bookmark);
184 	asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
185 }
186 EXPORT_SYMBOL_GPL(ps3_set_bookmark);
187 
188 void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id)
189 {
190 	u64 bookmark;
191 
192 	bookmark = (get_tb() & 0x00000000FFFFFFFFULL) |
193 		PS3_PM_BOOKMARK_TAG_KERNEL;
194 	bookmark = ((tag << 56) & PS3_PM_BOOKMARK_TAG_MASK_LO) |
195 		(incident << 48) | (th_id << 32) | bookmark;
196 	ps3_set_bookmark(bookmark);
197 }
198 EXPORT_SYMBOL_GPL(ps3_set_pm_bookmark);
199 
200 /**
201  * ps3_read_phys_ctr - Read physical counter registers.
202  *
203  * Each physical counter can act as one 32 bit counter or as two 16 bit
204  * counters.
205  */
206 
207 u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr)
208 {
209 	int result;
210 	u64 counter0415;
211 	u64 counter2637;
212 
213 	if (phys_ctr >= NR_PHYS_CTRS) {
214 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
215 			__LINE__, phys_ctr);
216 		return 0;
217 	}
218 
219 	result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415,
220 				     &counter2637);
221 	if (result) {
222 		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
223 			"phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr,
224 			ps3_result(result));
225 		return 0;
226 	}
227 
228 	switch (phys_ctr) {
229 	case 0:
230 		return counter0415 >> 32;
231 	case 1:
232 		return counter0415 & PS3_PM_COUNTER_MASK_LO;
233 	case 2:
234 		return counter2637 >> 32;
235 	case 3:
236 		return counter2637 & PS3_PM_COUNTER_MASK_LO;
237 	default:
238 		BUG();
239 	}
240 	return 0;
241 }
242 EXPORT_SYMBOL_GPL(ps3_read_phys_ctr);
243 
244 /**
245  * ps3_write_phys_ctr - Write physical counter registers.
246  *
247  * Each physical counter can act as one 32 bit counter or as two 16 bit
248  * counters.
249  */
250 
251 void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
252 {
253 	u64 counter0415;
254 	u64 counter0415_mask;
255 	u64 counter2637;
256 	u64 counter2637_mask;
257 	int result;
258 
259 	if (phys_ctr >= NR_PHYS_CTRS) {
260 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
261 			__LINE__, phys_ctr);
262 		return;
263 	}
264 
265 	switch (phys_ctr) {
266 	case 0:
267 		counter0415 = (u64)val << 32;
268 		counter0415_mask = PS3_PM_COUNTER_MASK_HI;
269 		counter2637 = 0x0;
270 		counter2637_mask = 0x0;
271 		break;
272 	case 1:
273 		counter0415 = (u64)val;
274 		counter0415_mask = PS3_PM_COUNTER_MASK_LO;
275 		counter2637 = 0x0;
276 		counter2637_mask = 0x0;
277 		break;
278 	case 2:
279 		counter0415 = 0x0;
280 		counter0415_mask = 0x0;
281 		counter2637 = (u64)val << 32;
282 		counter2637_mask = PS3_PM_COUNTER_MASK_HI;
283 		break;
284 	case 3:
285 		counter0415 = 0x0;
286 		counter0415_mask = 0x0;
287 		counter2637 = (u64)val;
288 		counter2637_mask = PS3_PM_COUNTER_MASK_LO;
289 		break;
290 	default:
291 		BUG();
292 	}
293 
294 	result = lv1_set_lpm_counter(lpm_priv->lpm_id,
295 				     counter0415, counter0415_mask,
296 				     counter2637, counter2637_mask,
297 				     &counter0415, &counter2637);
298 	if (result)
299 		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
300 			"phys_ctr %u, val %u, %s\n", __func__, __LINE__,
301 			phys_ctr, val, ps3_result(result));
302 }
303 EXPORT_SYMBOL_GPL(ps3_write_phys_ctr);
304 
305 /**
306  * ps3_read_ctr - Read counter.
307  *
308  * Read 16 or 32 bits depending on the current size of the counter.
309  * Counters 4, 5, 6 & 7 are always 16 bit.
310  */
311 
312 u32 ps3_read_ctr(u32 cpu, u32 ctr)
313 {
314 	u32 val;
315 	u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
316 
317 	val = ps3_read_phys_ctr(cpu, phys_ctr);
318 
319 	if (ps3_get_ctr_size(cpu, phys_ctr) == 16)
320 		val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff);
321 
322 	return val;
323 }
324 EXPORT_SYMBOL_GPL(ps3_read_ctr);
325 
326 /**
327  * ps3_write_ctr - Write counter.
328  *
329  * Write 16 or 32 bits depending on the current size of the counter.
330  * Counters 4, 5, 6 & 7 are always 16 bit.
331  */
332 
333 void ps3_write_ctr(u32 cpu, u32 ctr, u32 val)
334 {
335 	u32 phys_ctr;
336 	u32 phys_val;
337 
338 	phys_ctr = ctr & (NR_PHYS_CTRS - 1);
339 
340 	if (ps3_get_ctr_size(cpu, phys_ctr) == 16) {
341 		phys_val = ps3_read_phys_ctr(cpu, phys_ctr);
342 
343 		if (ctr < NR_PHYS_CTRS)
344 			val = (val << 16) | (phys_val & 0xffff);
345 		else
346 			val = (val & 0xffff) | (phys_val & 0xffff0000);
347 	}
348 
349 	ps3_write_phys_ctr(cpu, phys_ctr, val);
350 }
351 EXPORT_SYMBOL_GPL(ps3_write_ctr);
352 
353 /**
354  * ps3_read_pm07_control - Read counter control registers.
355  *
356  * Each logical counter has a corresponding control register.
357  */
358 
359 u32 ps3_read_pm07_control(u32 cpu, u32 ctr)
360 {
361 	return 0;
362 }
363 EXPORT_SYMBOL_GPL(ps3_read_pm07_control);
364 
365 /**
366  * ps3_write_pm07_control - Write counter control registers.
367  *
368  * Each logical counter has a corresponding control register.
369  */
370 
371 void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val)
372 {
373 	int result;
374 	static const u64 mask = 0xFFFFFFFFFFFFFFFFULL;
375 	u64 old_value;
376 
377 	if (ctr >= NR_CTRS) {
378 		dev_dbg(sbd_core(), "%s:%u: ctr too big: %u\n", __func__,
379 			__LINE__, ctr);
380 		return;
381 	}
382 
383 	result = lv1_set_lpm_counter_control(lpm_priv->lpm_id, ctr, val, mask,
384 					     &old_value);
385 	if (result)
386 		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter_control "
387 			"failed: ctr %u, %s\n", __func__, __LINE__, ctr,
388 			ps3_result(result));
389 }
390 EXPORT_SYMBOL_GPL(ps3_write_pm07_control);
391 
392 /**
393  * ps3_read_pm - Read Other LPM control registers.
394  */
395 
396 u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg)
397 {
398 	int result = 0;
399 	u64 val = 0;
400 
401 	switch (reg) {
402 	case pm_control:
403 		return lpm_priv->shadow.pm_control;
404 	case trace_address:
405 		return CBE_PM_TRACE_BUF_EMPTY;
406 	case pm_start_stop:
407 		return lpm_priv->shadow.pm_start_stop;
408 	case pm_interval:
409 		result = lv1_set_lpm_interval(lpm_priv->lpm_id, 0, 0, &val);
410 		if (result) {
411 			val = 0;
412 			dev_dbg(sbd_core(), "%s:%u: lv1 set_inteval failed: "
413 				"reg %u, %s\n", __func__, __LINE__, reg,
414 				ps3_result(result));
415 		}
416 		return (u32)val;
417 	case group_control:
418 		return lpm_priv->shadow.group_control;
419 	case debug_bus_control:
420 		return lpm_priv->shadow.debug_bus_control;
421 	case pm_status:
422 		result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id,
423 						      &val);
424 		if (result) {
425 			val = 0;
426 			dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: "
427 				"reg %u, %s\n", __func__, __LINE__, reg,
428 				ps3_result(result));
429 		}
430 		return (u32)val;
431 	case ext_tr_timer:
432 		return 0;
433 	default:
434 		dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
435 			__LINE__, reg);
436 		BUG();
437 		break;
438 	}
439 
440 	return 0;
441 }
442 EXPORT_SYMBOL_GPL(ps3_read_pm);
443 
444 /**
445  * ps3_write_pm - Write Other LPM control registers.
446  */
447 
448 void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
449 {
450 	int result = 0;
451 	u64 dummy;
452 
453 	switch (reg) {
454 	case group_control:
455 		if (val != lpm_priv->shadow.group_control)
456 			result = lv1_set_lpm_group_control(lpm_priv->lpm_id,
457 							   val,
458 							   PS3_WRITE_PM_MASK,
459 							   &dummy);
460 		lpm_priv->shadow.group_control = val;
461 		break;
462 	case debug_bus_control:
463 		if (val != lpm_priv->shadow.debug_bus_control)
464 			result = lv1_set_lpm_debug_bus_control(lpm_priv->lpm_id,
465 							      val,
466 							      PS3_WRITE_PM_MASK,
467 							      &dummy);
468 		lpm_priv->shadow.debug_bus_control = val;
469 		break;
470 	case pm_control:
471 		if (use_start_stop_bookmark)
472 			val |= (PS3_PM_CONTROL_PPU_TH0_BOOKMARK |
473 				PS3_PM_CONTROL_PPU_TH1_BOOKMARK);
474 		if (val != lpm_priv->shadow.pm_control)
475 			result = lv1_set_lpm_general_control(lpm_priv->lpm_id,
476 							     val,
477 							     PS3_WRITE_PM_MASK,
478 							     0, 0, &dummy,
479 							     &dummy);
480 		lpm_priv->shadow.pm_control = val;
481 		break;
482 	case pm_interval:
483 		result = lv1_set_lpm_interval(lpm_priv->lpm_id, val,
484 					      PS3_WRITE_PM_MASK, &dummy);
485 		break;
486 	case pm_start_stop:
487 		if (val != lpm_priv->shadow.pm_start_stop)
488 			result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
489 							     val,
490 							     PS3_WRITE_PM_MASK,
491 							     &dummy);
492 		lpm_priv->shadow.pm_start_stop = val;
493 		break;
494 	case trace_address:
495 	case ext_tr_timer:
496 	case pm_status:
497 		break;
498 	default:
499 		dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
500 			__LINE__, reg);
501 		BUG();
502 		break;
503 	}
504 
505 	if (result)
506 		dev_err(sbd_core(), "%s:%u: lv1 set_control failed: "
507 			"reg %u, %s\n", __func__, __LINE__, reg,
508 			ps3_result(result));
509 }
510 EXPORT_SYMBOL_GPL(ps3_write_pm);
511 
512 /**
513  * ps3_get_ctr_size - Get the size of a physical counter.
514  *
515  * Returns either 16 or 32.
516  */
517 
518 u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr)
519 {
520 	u32 pm_ctrl;
521 
522 	if (phys_ctr >= NR_PHYS_CTRS) {
523 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
524 			__LINE__, phys_ctr);
525 		return 0;
526 	}
527 
528 	pm_ctrl = ps3_read_pm(cpu, pm_control);
529 	return (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32;
530 }
531 EXPORT_SYMBOL_GPL(ps3_get_ctr_size);
532 
533 /**
534  * ps3_set_ctr_size - Set the size of a physical counter to 16 or 32 bits.
535  */
536 
537 void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size)
538 {
539 	u32 pm_ctrl;
540 
541 	if (phys_ctr >= NR_PHYS_CTRS) {
542 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
543 			__LINE__, phys_ctr);
544 		return;
545 	}
546 
547 	pm_ctrl = ps3_read_pm(cpu, pm_control);
548 
549 	switch (ctr_size) {
550 	case 16:
551 		pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr);
552 		ps3_write_pm(cpu, pm_control, pm_ctrl);
553 		break;
554 
555 	case 32:
556 		pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr);
557 		ps3_write_pm(cpu, pm_control, pm_ctrl);
558 		break;
559 	default:
560 		BUG();
561 	}
562 }
563 EXPORT_SYMBOL_GPL(ps3_set_ctr_size);
564 
565 static u64 pm_translate_signal_group_number_on_island2(u64 subgroup)
566 {
567 
568 	if (subgroup == 2)
569 		subgroup = 3;
570 
571 	if (subgroup <= 6)
572 		return PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER + subgroup;
573 	else if (subgroup == 7)
574 		return PM_ISLAND2_SIGNAL_GROUP_NUMBER1;
575 	else
576 		return PM_ISLAND2_SIGNAL_GROUP_NUMBER2;
577 }
578 
579 static u64 pm_translate_signal_group_number_on_island3(u64 subgroup)
580 {
581 
582 	switch (subgroup) {
583 	case 2:
584 	case 3:
585 	case 4:
586 		subgroup += 2;
587 		break;
588 	case 5:
589 		subgroup = 8;
590 		break;
591 	default:
592 		break;
593 	}
594 	return PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER + subgroup;
595 }
596 
597 static u64 pm_translate_signal_group_number_on_island4(u64 subgroup)
598 {
599 	return PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER + subgroup;
600 }
601 
602 static u64 pm_translate_signal_group_number_on_island5(u64 subgroup)
603 {
604 
605 	switch (subgroup) {
606 	case 3:
607 		subgroup = 4;
608 		break;
609 	case 4:
610 		subgroup = 6;
611 		break;
612 	default:
613 		break;
614 	}
615 	return PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER + subgroup;
616 }
617 
618 static u64 pm_translate_signal_group_number_on_island6(u64 subgroup,
619 						       u64 subsubgroup)
620 {
621 	switch (subgroup) {
622 	case 3:
623 	case 4:
624 	case 5:
625 		subgroup += 1;
626 		break;
627 	default:
628 		break;
629 	}
630 
631 	switch (subsubgroup) {
632 	case 4:
633 	case 5:
634 	case 6:
635 		subsubgroup += 2;
636 		break;
637 	case 7:
638 	case 8:
639 	case 9:
640 	case 10:
641 		subsubgroup += 4;
642 		break;
643 	case 11:
644 	case 12:
645 	case 13:
646 		subsubgroup += 5;
647 		break;
648 	default:
649 		break;
650 	}
651 
652 	if (subgroup <= 5)
653 		return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup);
654 	else
655 		return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup
656 			+ subsubgroup - 1);
657 }
658 
659 static u64 pm_translate_signal_group_number_on_island7(u64 subgroup)
660 {
661 	return PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER + subgroup;
662 }
663 
664 static u64 pm_translate_signal_group_number_on_island8(u64 subgroup)
665 {
666 	return PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER + subgroup;
667 }
668 
669 static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group)
670 {
671 	u64 island;
672 	u64 subgroup;
673 	u64 subsubgroup;
674 
675 	subgroup = 0;
676 	subsubgroup = 0;
677 	island = 0;
678 	if (group < 1000) {
679 		if (group < 100) {
680 			if (20 <= group && group < 30) {
681 				island = 2;
682 				subgroup = group - 20;
683 			} else if (30 <= group && group < 40) {
684 				island = 3;
685 				subgroup = group - 30;
686 			} else if (40 <= group && group < 50) {
687 				island = 4;
688 				subgroup = group - 40;
689 			} else if (50 <= group && group < 60) {
690 				island = 5;
691 				subgroup = group - 50;
692 			} else if (60 <= group && group < 70) {
693 				island = 6;
694 				subgroup = group - 60;
695 			} else if (70 <= group && group < 80) {
696 				island = 7;
697 				subgroup = group - 70;
698 			} else if (80 <= group && group < 90) {
699 				island = 8;
700 				subgroup = group - 80;
701 			}
702 		} else if (200 <= group && group < 300) {
703 			island = 2;
704 			subgroup = group - 200;
705 		} else if (600 <= group && group < 700) {
706 			island = 6;
707 			subgroup = 5;
708 			subsubgroup = group - 650;
709 		}
710 	} else if (6000 <= group && group < 7000) {
711 		island = 6;
712 		subgroup = 5;
713 		subsubgroup = group - 6500;
714 	}
715 
716 	switch (island) {
717 	case 2:
718 		return pm_translate_signal_group_number_on_island2(subgroup);
719 	case 3:
720 		return pm_translate_signal_group_number_on_island3(subgroup);
721 	case 4:
722 		return pm_translate_signal_group_number_on_island4(subgroup);
723 	case 5:
724 		return pm_translate_signal_group_number_on_island5(subgroup);
725 	case 6:
726 		return pm_translate_signal_group_number_on_island6(subgroup,
727 								   subsubgroup);
728 	case 7:
729 		return pm_translate_signal_group_number_on_island7(subgroup);
730 	case 8:
731 		return pm_translate_signal_group_number_on_island8(subgroup);
732 	default:
733 		dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__,
734 			__LINE__, group);
735 		BUG();
736 		break;
737 	}
738 	return 0;
739 }
740 
741 static u64 pm_bus_word_to_ps3_lv1_bus_word(u8 word)
742 {
743 
744 	switch (word) {
745 	case 1:
746 		return 0xF000;
747 	case 2:
748 		return 0x0F00;
749 	case 4:
750 		return 0x00F0;
751 	case 8:
752 	default:
753 		return 0x000F;
754 	}
755 }
756 
757 static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select,
758 			    u64 signal_select, u64 attr1, u64 attr2, u64 attr3)
759 {
760 	int ret;
761 
762 	ret = lv1_set_lpm_signal(lpm_priv->lpm_id, lv1_signal_group, bus_select,
763 				 signal_select, attr1, attr2, attr3);
764 	if (ret)
765 		dev_err(sbd_core(),
766 			"%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
767 			__func__, __LINE__, ret, lv1_signal_group, bus_select,
768 			signal_select, attr1, attr2, attr3);
769 
770 	return ret;
771 }
772 
773 int ps3_set_signal(u64 signal_group, u8 signal_bit, u16 sub_unit,
774 		   u8 bus_word)
775 {
776 	int ret;
777 	u64 lv1_signal_group;
778 	u64 bus_select;
779 	u64 signal_select;
780 	u64 attr1, attr2, attr3;
781 
782 	if (signal_group == 0)
783 		return __ps3_set_signal(0, 0, 0, 0, 0, 0);
784 
785 	lv1_signal_group =
786 		pm_signal_group_to_ps3_lv1_signal_group(signal_group);
787 	bus_select = pm_bus_word_to_ps3_lv1_bus_word(bus_word);
788 
789 	switch (signal_group) {
790 	case PM_SIG_GROUP_SPU_TRIGGER:
791 		signal_select = 1;
792 		signal_select = signal_select << (63 - signal_bit);
793 		break;
794 	case PM_SIG_GROUP_SPU_EVENT:
795 		signal_select = 1;
796 		signal_select = (signal_select << (63 - signal_bit)) | 0x3;
797 		break;
798 	default:
799 		signal_select = 0;
800 		break;
801 	}
802 
803 	/*
804 	 * 0: physical object.
805 	 * 1: logical object.
806 	 * This parameter is only used for the PPE and SPE signals.
807 	 */
808 	attr1 = 1;
809 
810 	/*
811 	 * This parameter is used to specify the target physical/logical
812 	 * PPE/SPE object.
813 	 */
814 	if (PM_SIG_GROUP_SPU <= signal_group &&
815 		signal_group < PM_SIG_GROUP_MFC_MAX)
816 		attr2 = sub_unit;
817 	else
818 		attr2 = lpm_priv->pu_id;
819 
820 	/*
821 	 * This parameter is only used for setting the SPE signal.
822 	 */
823 	attr3 = 0;
824 
825 	ret = __ps3_set_signal(lv1_signal_group, bus_select, signal_select,
826 			       attr1, attr2, attr3);
827 	if (ret)
828 		dev_err(sbd_core(), "%s:%u: __ps3_set_signal failed: %d\n",
829 			__func__, __LINE__, ret);
830 
831 	return ret;
832 }
833 EXPORT_SYMBOL_GPL(ps3_set_signal);
834 
835 u32 ps3_get_hw_thread_id(int cpu)
836 {
837 	return get_hard_smp_processor_id(cpu);
838 }
839 EXPORT_SYMBOL_GPL(ps3_get_hw_thread_id);
840 
841 /**
842  * ps3_enable_pm - Enable the entire performance monitoring unit.
843  *
844  * When we enable the LPM, all pending writes to counters get committed.
845  */
846 
847 void ps3_enable_pm(u32 cpu)
848 {
849 	int result;
850 	u64 tmp;
851 	int insert_bookmark = 0;
852 
853 	lpm_priv->tb_count = 0;
854 
855 	if (use_start_stop_bookmark) {
856 		if (!(lpm_priv->shadow.pm_start_stop &
857 			(PS3_PM_START_STOP_START_MASK
858 			| PS3_PM_START_STOP_STOP_MASK))) {
859 			result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
860 				(PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START |
861 				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START |
862 				PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP |
863 				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP),
864 				0xFFFFFFFFFFFFFFFFULL, &tmp);
865 
866 			if (result)
867 				dev_err(sbd_core(), "%s:%u: "
868 					"lv1_set_lpm_trigger_control failed: "
869 					"%s\n", __func__, __LINE__,
870 					ps3_result(result));
871 
872 			insert_bookmark = !result;
873 		}
874 	}
875 
876 	result = lv1_start_lpm(lpm_priv->lpm_id);
877 
878 	if (result)
879 		dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n",
880 			__func__, __LINE__, ps3_result(result));
881 
882 	if (use_start_stop_bookmark && !result && insert_bookmark)
883 		ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START);
884 }
885 EXPORT_SYMBOL_GPL(ps3_enable_pm);
886 
887 /**
888  * ps3_disable_pm - Disable the entire performance monitoring unit.
889  */
890 
891 void ps3_disable_pm(u32 cpu)
892 {
893 	int result;
894 	u64 tmp;
895 
896 	ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_STOP);
897 
898 	result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp);
899 
900 	if (result) {
901 		if(result != LV1_WRONG_STATE)
902 			dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n",
903 				__func__, __LINE__, ps3_result(result));
904 		return;
905 	}
906 
907 	lpm_priv->tb_count = tmp;
908 
909 	dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__,
910 		lpm_priv->tb_count, lpm_priv->tb_count);
911 }
912 EXPORT_SYMBOL_GPL(ps3_disable_pm);
913 
914 /**
915  * ps3_lpm_copy_tb - Copy data from the trace buffer to a kernel buffer.
916  * @offset: Offset in bytes from the start of the trace buffer.
917  * @buf: Copy destination.
918  * @count: Maximum count of bytes to copy.
919  * @bytes_copied: Pointer to a variable that will recieve the number of
920  *  bytes copied to @buf.
921  *
922  * On error @buf will contain any successfully copied trace buffer data
923  * and bytes_copied will be set to the number of bytes successfully copied.
924  */
925 
926 int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count,
927 		    unsigned long *bytes_copied)
928 {
929 	int result;
930 
931 	*bytes_copied = 0;
932 
933 	if (!lpm_priv->tb_cache)
934 		return -EPERM;
935 
936 	if (offset >= lpm_priv->tb_count)
937 		return 0;
938 
939 	count = min(count, lpm_priv->tb_count - offset);
940 
941 	while (*bytes_copied < count) {
942 		const unsigned long request = count - *bytes_copied;
943 		u64 tmp;
944 
945 		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
946 						   request, &tmp);
947 		if (result) {
948 			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
949 				__func__, __LINE__, request, offset);
950 
951 			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
952 				"failed: %s\n", __func__, __LINE__,
953 				ps3_result(result));
954 			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
955 		}
956 
957 		memcpy(buf, lpm_priv->tb_cache, tmp);
958 		buf += tmp;
959 		*bytes_copied += tmp;
960 		offset += tmp;
961 	}
962 	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
963 		*bytes_copied);
964 
965 	return 0;
966 }
967 EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb);
968 
969 /**
970  * ps3_lpm_copy_tb_to_user - Copy data from the trace buffer to a user buffer.
971  * @offset: Offset in bytes from the start of the trace buffer.
972  * @buf: A __user copy destination.
973  * @count: Maximum count of bytes to copy.
974  * @bytes_copied: Pointer to a variable that will recieve the number of
975  *  bytes copied to @buf.
976  *
977  * On error @buf will contain any successfully copied trace buffer data
978  * and bytes_copied will be set to the number of bytes successfully copied.
979  */
980 
981 int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
982 			    unsigned long count, unsigned long *bytes_copied)
983 {
984 	int result;
985 
986 	*bytes_copied = 0;
987 
988 	if (!lpm_priv->tb_cache)
989 		return -EPERM;
990 
991 	if (offset >= lpm_priv->tb_count)
992 		return 0;
993 
994 	count = min(count, lpm_priv->tb_count - offset);
995 
996 	while (*bytes_copied < count) {
997 		const unsigned long request = count - *bytes_copied;
998 		u64 tmp;
999 
1000 		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
1001 						   request, &tmp);
1002 		if (result) {
1003 			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
1004 				__func__, __LINE__, request, offset);
1005 			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
1006 				"failed: %s\n", __func__, __LINE__,
1007 				ps3_result(result));
1008 			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
1009 		}
1010 
1011 		result = copy_to_user(buf, lpm_priv->tb_cache, tmp);
1012 
1013 		if (result) {
1014 			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n",
1015 				__func__, __LINE__, tmp, buf);
1016 			dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n",
1017 				__func__, __LINE__, result);
1018 			return -EFAULT;
1019 		}
1020 
1021 		buf += tmp;
1022 		*bytes_copied += tmp;
1023 		offset += tmp;
1024 	}
1025 	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
1026 		*bytes_copied);
1027 
1028 	return 0;
1029 }
1030 EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb_to_user);
1031 
1032 /**
1033  * ps3_get_and_clear_pm_interrupts -
1034  *
1035  * Clearing interrupts for the entire performance monitoring unit.
1036  * Reading pm_status clears the interrupt bits.
1037  */
1038 
1039 u32 ps3_get_and_clear_pm_interrupts(u32 cpu)
1040 {
1041 	return ps3_read_pm(cpu, pm_status);
1042 }
1043 EXPORT_SYMBOL_GPL(ps3_get_and_clear_pm_interrupts);
1044 
1045 /**
1046  * ps3_enable_pm_interrupts -
1047  *
1048  * Enabling interrupts for the entire performance monitoring unit.
1049  * Enables the interrupt bits in the pm_status register.
1050  */
1051 
1052 void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
1053 {
1054 	if (mask)
1055 		ps3_write_pm(cpu, pm_status, mask);
1056 }
1057 EXPORT_SYMBOL_GPL(ps3_enable_pm_interrupts);
1058 
1059 /**
1060  * ps3_enable_pm_interrupts -
1061  *
1062  * Disabling interrupts for the entire performance monitoring unit.
1063  */
1064 
1065 void ps3_disable_pm_interrupts(u32 cpu)
1066 {
1067 	ps3_get_and_clear_pm_interrupts(cpu);
1068 	ps3_write_pm(cpu, pm_status, 0);
1069 }
1070 EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts);
1071 
1072 /**
1073  * ps3_lpm_open - Open the logical performance monitor device.
1074  * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm
1075  *  instance, specified by one of enum ps3_lpm_tb_type.
1076  * @tb_cache: Optional user supplied buffer to use as the trace buffer cache.
1077  *  If NULL, the driver will allocate and manage an internal buffer.
1078  *  Unused when when @tb_type is PS3_LPM_TB_TYPE_NONE.
1079  * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer.
1080  *  Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE.
1081  */
1082 
1083 int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
1084 	u64 tb_cache_size)
1085 {
1086 	int result;
1087 	u64 tb_size;
1088 
1089 	BUG_ON(!lpm_priv);
1090 	BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE
1091 		&& tb_type != PS3_LPM_TB_TYPE_INTERNAL);
1092 
1093 	if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache)
1094 		dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__);
1095 
1096 	if (!atomic_add_unless(&lpm_priv->open, 1, 1)) {
1097 		dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__);
1098 		return -EBUSY;
1099 	}
1100 
1101 	/* Note tb_cache needs 128 byte alignment. */
1102 
1103 	if (tb_type == PS3_LPM_TB_TYPE_NONE) {
1104 		lpm_priv->tb_cache_size = 0;
1105 		lpm_priv->tb_cache_internal = NULL;
1106 		lpm_priv->tb_cache = NULL;
1107 	} else if (tb_cache) {
1108 		if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128)
1109 			|| tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) {
1110 			dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n",
1111 				__func__, __LINE__);
1112 			result = -EINVAL;
1113 			goto fail_align;
1114 		}
1115 		lpm_priv->tb_cache_size = tb_cache_size;
1116 		lpm_priv->tb_cache_internal = NULL;
1117 		lpm_priv->tb_cache = tb_cache;
1118 	} else {
1119 		lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE;
1120 		lpm_priv->tb_cache_internal = kzalloc(
1121 			lpm_priv->tb_cache_size + 127, GFP_KERNEL);
1122 		if (!lpm_priv->tb_cache_internal) {
1123 			dev_err(sbd_core(), "%s:%u: alloc internal tb_cache "
1124 				"failed\n", __func__, __LINE__);
1125 			result = -ENOMEM;
1126 			goto fail_malloc;
1127 		}
1128 		lpm_priv->tb_cache = (void *)_ALIGN_UP(
1129 			(unsigned long)lpm_priv->tb_cache_internal, 128);
1130 	}
1131 
1132 	result = lv1_construct_lpm(lpm_priv->node_id, tb_type, 0, 0,
1133 				ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)),
1134 				lpm_priv->tb_cache_size, &lpm_priv->lpm_id,
1135 				&lpm_priv->outlet_id, &tb_size);
1136 
1137 	if (result) {
1138 		dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n",
1139 			__func__, __LINE__, ps3_result(result));
1140 		result = -EINVAL;
1141 		goto fail_construct;
1142 	}
1143 
1144 	lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT;
1145 	lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT;
1146 	lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT;
1147 	lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT;
1148 
1149 	dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, "
1150 		"tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id,
1151 		lpm_priv->outlet_id, tb_size);
1152 
1153 	return 0;
1154 
1155 fail_construct:
1156 	kfree(lpm_priv->tb_cache_internal);
1157 	lpm_priv->tb_cache_internal = NULL;
1158 fail_malloc:
1159 fail_align:
1160 	atomic_dec(&lpm_priv->open);
1161 	return result;
1162 }
1163 EXPORT_SYMBOL_GPL(ps3_lpm_open);
1164 
1165 /**
1166  * ps3_lpm_close - Close the lpm device.
1167  *
1168  */
1169 
1170 int ps3_lpm_close(void)
1171 {
1172 	dev_dbg(sbd_core(), "%s:%u\n", __func__, __LINE__);
1173 
1174 	lv1_destruct_lpm(lpm_priv->lpm_id);
1175 	lpm_priv->lpm_id = 0;
1176 
1177 	kfree(lpm_priv->tb_cache_internal);
1178 	lpm_priv->tb_cache_internal = NULL;
1179 
1180 	atomic_dec(&lpm_priv->open);
1181 	return 0;
1182 }
1183 EXPORT_SYMBOL_GPL(ps3_lpm_close);
1184 
1185 static int __devinit ps3_lpm_probe(struct ps3_system_bus_device *dev)
1186 {
1187 	dev_dbg(&dev->core, " -> %s:%u\n", __func__, __LINE__);
1188 
1189 	if (lpm_priv) {
1190 		dev_info(&dev->core, "%s:%u: called twice\n",
1191 			__func__, __LINE__);
1192 		return -EBUSY;
1193 	}
1194 
1195 	lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL);
1196 
1197 	if (!lpm_priv)
1198 		return -ENOMEM;
1199 
1200 	lpm_priv->sbd = dev;
1201 	lpm_priv->node_id = dev->lpm.node_id;
1202 	lpm_priv->pu_id = dev->lpm.pu_id;
1203 	lpm_priv->rights = dev->lpm.rights;
1204 
1205 	dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
1206 
1207 	return 0;
1208 }
1209 
1210 static int ps3_lpm_remove(struct ps3_system_bus_device *dev)
1211 {
1212 	dev_dbg(&dev->core, " -> %s:%u:\n", __func__, __LINE__);
1213 
1214 	ps3_lpm_close();
1215 
1216 	kfree(lpm_priv);
1217 	lpm_priv = NULL;
1218 
1219 	dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
1220 	return 0;
1221 }
1222 
1223 static struct ps3_system_bus_driver ps3_lpm_driver = {
1224 	.match_id = PS3_MATCH_ID_LPM,
1225 	.core.name	= "ps3-lpm",
1226 	.core.owner	= THIS_MODULE,
1227 	.probe		= ps3_lpm_probe,
1228 	.remove		= ps3_lpm_remove,
1229 	.shutdown	= ps3_lpm_remove,
1230 };
1231 
1232 static int __init ps3_lpm_init(void)
1233 {
1234 	pr_debug("%s:%d:\n", __func__, __LINE__);
1235 	return ps3_system_bus_driver_register(&ps3_lpm_driver);
1236 }
1237 
1238 static void __exit ps3_lpm_exit(void)
1239 {
1240 	pr_debug("%s:%d:\n", __func__, __LINE__);
1241 	ps3_system_bus_driver_unregister(&ps3_lpm_driver);
1242 }
1243 
1244 module_init(ps3_lpm_init);
1245 module_exit(ps3_lpm_exit);
1246 
1247 MODULE_LICENSE("GPL v2");
1248 MODULE_DESCRIPTION("PS3 Logical Performance Monitor Driver");
1249 MODULE_AUTHOR("Sony Corporation");
1250 MODULE_ALIAS(PS3_MODULE_ALIAS_LPM);
1251