1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * PS3 repository routines.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2006 Sony Computer Entertainment Inc.
6*4882a593Smuzhiyun * Copyright 2006 Sony Corp.
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <asm/lv1call.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include "platform.h"
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun enum ps3_vendor_id {
14*4882a593Smuzhiyun PS3_VENDOR_ID_NONE = 0,
15*4882a593Smuzhiyun PS3_VENDOR_ID_SONY = 0x8000000000000000UL,
16*4882a593Smuzhiyun };
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun enum ps3_lpar_id {
19*4882a593Smuzhiyun PS3_LPAR_ID_CURRENT = 0,
20*4882a593Smuzhiyun PS3_LPAR_ID_PME = 1,
21*4882a593Smuzhiyun };
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
_dump_field(const char * hdr,u64 n,const char * func,int line)24*4882a593Smuzhiyun static void _dump_field(const char *hdr, u64 n, const char *func, int line)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun #if defined(DEBUG)
27*4882a593Smuzhiyun char s[16];
28*4882a593Smuzhiyun const char *const in = (const char *)&n;
29*4882a593Smuzhiyun unsigned int i;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun for (i = 0; i < 8; i++)
32*4882a593Smuzhiyun s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.';
33*4882a593Smuzhiyun s[i] = 0;
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun pr_devel("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s);
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #define dump_node_name(_a, _b, _c, _d, _e) \
40*4882a593Smuzhiyun _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
_dump_node_name(unsigned int lpar_id,u64 n1,u64 n2,u64 n3,u64 n4,const char * func,int line)41*4882a593Smuzhiyun static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
42*4882a593Smuzhiyun u64 n4, const char *func, int line)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
45*4882a593Smuzhiyun _dump_field("n1: ", n1, func, line);
46*4882a593Smuzhiyun _dump_field("n2: ", n2, func, line);
47*4882a593Smuzhiyun _dump_field("n3: ", n3, func, line);
48*4882a593Smuzhiyun _dump_field("n4: ", n4, func, line);
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #define dump_node(_a, _b, _c, _d, _e, _f, _g) \
52*4882a593Smuzhiyun _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
_dump_node(unsigned int lpar_id,u64 n1,u64 n2,u64 n3,u64 n4,u64 v1,u64 v2,const char * func,int line)53*4882a593Smuzhiyun static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
54*4882a593Smuzhiyun u64 v1, u64 v2, const char *func, int line)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
57*4882a593Smuzhiyun _dump_field("n1: ", n1, func, line);
58*4882a593Smuzhiyun _dump_field("n2: ", n2, func, line);
59*4882a593Smuzhiyun _dump_field("n3: ", n3, func, line);
60*4882a593Smuzhiyun _dump_field("n4: ", n4, func, line);
61*4882a593Smuzhiyun pr_devel("%s:%d: v1: %016llx\n", func, line, v1);
62*4882a593Smuzhiyun pr_devel("%s:%d: v2: %016llx\n", func, line, v2);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun * make_first_field - Make the first field of a repository node name.
67*4882a593Smuzhiyun * @text: Text portion of the field.
68*4882a593Smuzhiyun * @index: Numeric index portion of the field. Use zero for 'don't care'.
69*4882a593Smuzhiyun *
70*4882a593Smuzhiyun * This routine sets the vendor id to zero (non-vendor specific).
71*4882a593Smuzhiyun * Returns field value.
72*4882a593Smuzhiyun */
73*4882a593Smuzhiyun
make_first_field(const char * text,u64 index)74*4882a593Smuzhiyun static u64 make_first_field(const char *text, u64 index)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun u64 n;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun strncpy((char *)&n, text, 8);
79*4882a593Smuzhiyun return PS3_VENDOR_ID_NONE + (n >> 32) + index;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /**
83*4882a593Smuzhiyun * make_field - Make subsequent fields of a repository node name.
84*4882a593Smuzhiyun * @text: Text portion of the field. Use "" for 'don't care'.
85*4882a593Smuzhiyun * @index: Numeric index portion of the field. Use zero for 'don't care'.
86*4882a593Smuzhiyun *
87*4882a593Smuzhiyun * Returns field value.
88*4882a593Smuzhiyun */
89*4882a593Smuzhiyun
make_field(const char * text,u64 index)90*4882a593Smuzhiyun static u64 make_field(const char *text, u64 index)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun u64 n = 0;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun memcpy((char *)&n, text, strnlen(text, sizeof(n)));
95*4882a593Smuzhiyun return n + index;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /**
99*4882a593Smuzhiyun * read_node - Read a repository node from raw fields.
100*4882a593Smuzhiyun * @n1: First field of node name.
101*4882a593Smuzhiyun * @n2: Second field of node name. Use zero for 'don't care'.
102*4882a593Smuzhiyun * @n3: Third field of node name. Use zero for 'don't care'.
103*4882a593Smuzhiyun * @n4: Fourth field of node name. Use zero for 'don't care'.
104*4882a593Smuzhiyun * @v1: First repository value (high word).
105*4882a593Smuzhiyun * @v2: Second repository value (low word). Optional parameter, use zero
106*4882a593Smuzhiyun * for 'don't care'.
107*4882a593Smuzhiyun */
108*4882a593Smuzhiyun
read_node(unsigned int lpar_id,u64 n1,u64 n2,u64 n3,u64 n4,u64 * _v1,u64 * _v2)109*4882a593Smuzhiyun static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
110*4882a593Smuzhiyun u64 *_v1, u64 *_v2)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun int result;
113*4882a593Smuzhiyun u64 v1;
114*4882a593Smuzhiyun u64 v2;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (lpar_id == PS3_LPAR_ID_CURRENT) {
117*4882a593Smuzhiyun u64 id;
118*4882a593Smuzhiyun lv1_get_logical_partition_id(&id);
119*4882a593Smuzhiyun lpar_id = id;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun result = lv1_read_repository_node(lpar_id, n1, n2, n3, n4, &v1,
123*4882a593Smuzhiyun &v2);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun if (result) {
126*4882a593Smuzhiyun pr_warn("%s:%d: lv1_read_repository_node failed: %s\n",
127*4882a593Smuzhiyun __func__, __LINE__, ps3_result(result));
128*4882a593Smuzhiyun dump_node_name(lpar_id, n1, n2, n3, n4);
129*4882a593Smuzhiyun return -ENOENT;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun if (_v1)
135*4882a593Smuzhiyun *_v1 = v1;
136*4882a593Smuzhiyun if (_v2)
137*4882a593Smuzhiyun *_v2 = v2;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun if (v1 && !_v1)
140*4882a593Smuzhiyun pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n",
141*4882a593Smuzhiyun __func__, __LINE__, v1);
142*4882a593Smuzhiyun if (v2 && !_v2)
143*4882a593Smuzhiyun pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n",
144*4882a593Smuzhiyun __func__, __LINE__, v2);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun return 0;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
ps3_repository_read_bus_str(unsigned int bus_index,const char * bus_str,u64 * value)149*4882a593Smuzhiyun int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
150*4882a593Smuzhiyun u64 *value)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
153*4882a593Smuzhiyun make_first_field("bus", bus_index),
154*4882a593Smuzhiyun make_field(bus_str, 0),
155*4882a593Smuzhiyun 0, 0,
156*4882a593Smuzhiyun value, NULL);
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
ps3_repository_read_bus_id(unsigned int bus_index,u64 * bus_id)159*4882a593Smuzhiyun int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index),
162*4882a593Smuzhiyun make_field("id", 0), 0, 0, bus_id, NULL);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
ps3_repository_read_bus_type(unsigned int bus_index,enum ps3_bus_type * bus_type)165*4882a593Smuzhiyun int ps3_repository_read_bus_type(unsigned int bus_index,
166*4882a593Smuzhiyun enum ps3_bus_type *bus_type)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun int result;
169*4882a593Smuzhiyun u64 v1 = 0;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
172*4882a593Smuzhiyun make_first_field("bus", bus_index),
173*4882a593Smuzhiyun make_field("type", 0),
174*4882a593Smuzhiyun 0, 0,
175*4882a593Smuzhiyun &v1, NULL);
176*4882a593Smuzhiyun *bus_type = v1;
177*4882a593Smuzhiyun return result;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
ps3_repository_read_bus_num_dev(unsigned int bus_index,unsigned int * num_dev)180*4882a593Smuzhiyun int ps3_repository_read_bus_num_dev(unsigned int bus_index,
181*4882a593Smuzhiyun unsigned int *num_dev)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun int result;
184*4882a593Smuzhiyun u64 v1 = 0;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
187*4882a593Smuzhiyun make_first_field("bus", bus_index),
188*4882a593Smuzhiyun make_field("num_dev", 0),
189*4882a593Smuzhiyun 0, 0,
190*4882a593Smuzhiyun &v1, NULL);
191*4882a593Smuzhiyun *num_dev = v1;
192*4882a593Smuzhiyun return result;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
ps3_repository_read_dev_str(unsigned int bus_index,unsigned int dev_index,const char * dev_str,u64 * value)195*4882a593Smuzhiyun int ps3_repository_read_dev_str(unsigned int bus_index,
196*4882a593Smuzhiyun unsigned int dev_index, const char *dev_str, u64 *value)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
199*4882a593Smuzhiyun make_first_field("bus", bus_index),
200*4882a593Smuzhiyun make_field("dev", dev_index),
201*4882a593Smuzhiyun make_field(dev_str, 0),
202*4882a593Smuzhiyun 0,
203*4882a593Smuzhiyun value, NULL);
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun
ps3_repository_read_dev_id(unsigned int bus_index,unsigned int dev_index,u64 * dev_id)206*4882a593Smuzhiyun int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
207*4882a593Smuzhiyun u64 *dev_id)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index),
210*4882a593Smuzhiyun make_field("dev", dev_index), make_field("id", 0), 0,
211*4882a593Smuzhiyun dev_id, NULL);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
ps3_repository_read_dev_type(unsigned int bus_index,unsigned int dev_index,enum ps3_dev_type * dev_type)214*4882a593Smuzhiyun int ps3_repository_read_dev_type(unsigned int bus_index,
215*4882a593Smuzhiyun unsigned int dev_index, enum ps3_dev_type *dev_type)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun int result;
218*4882a593Smuzhiyun u64 v1 = 0;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
221*4882a593Smuzhiyun make_first_field("bus", bus_index),
222*4882a593Smuzhiyun make_field("dev", dev_index),
223*4882a593Smuzhiyun make_field("type", 0),
224*4882a593Smuzhiyun 0,
225*4882a593Smuzhiyun &v1, NULL);
226*4882a593Smuzhiyun *dev_type = v1;
227*4882a593Smuzhiyun return result;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
ps3_repository_read_dev_intr(unsigned int bus_index,unsigned int dev_index,unsigned int intr_index,enum ps3_interrupt_type * intr_type,unsigned int * interrupt_id)230*4882a593Smuzhiyun int ps3_repository_read_dev_intr(unsigned int bus_index,
231*4882a593Smuzhiyun unsigned int dev_index, unsigned int intr_index,
232*4882a593Smuzhiyun enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun int result;
235*4882a593Smuzhiyun u64 v1 = 0;
236*4882a593Smuzhiyun u64 v2 = 0;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
239*4882a593Smuzhiyun make_first_field("bus", bus_index),
240*4882a593Smuzhiyun make_field("dev", dev_index),
241*4882a593Smuzhiyun make_field("intr", intr_index),
242*4882a593Smuzhiyun 0,
243*4882a593Smuzhiyun &v1, &v2);
244*4882a593Smuzhiyun *intr_type = v1;
245*4882a593Smuzhiyun *interrupt_id = v2;
246*4882a593Smuzhiyun return result;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
ps3_repository_read_dev_reg_type(unsigned int bus_index,unsigned int dev_index,unsigned int reg_index,enum ps3_reg_type * reg_type)249*4882a593Smuzhiyun int ps3_repository_read_dev_reg_type(unsigned int bus_index,
250*4882a593Smuzhiyun unsigned int dev_index, unsigned int reg_index,
251*4882a593Smuzhiyun enum ps3_reg_type *reg_type)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun int result;
254*4882a593Smuzhiyun u64 v1 = 0;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
257*4882a593Smuzhiyun make_first_field("bus", bus_index),
258*4882a593Smuzhiyun make_field("dev", dev_index),
259*4882a593Smuzhiyun make_field("reg", reg_index),
260*4882a593Smuzhiyun make_field("type", 0),
261*4882a593Smuzhiyun &v1, NULL);
262*4882a593Smuzhiyun *reg_type = v1;
263*4882a593Smuzhiyun return result;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
ps3_repository_read_dev_reg_addr(unsigned int bus_index,unsigned int dev_index,unsigned int reg_index,u64 * bus_addr,u64 * len)266*4882a593Smuzhiyun int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
267*4882a593Smuzhiyun unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
270*4882a593Smuzhiyun make_first_field("bus", bus_index),
271*4882a593Smuzhiyun make_field("dev", dev_index),
272*4882a593Smuzhiyun make_field("reg", reg_index),
273*4882a593Smuzhiyun make_field("data", 0),
274*4882a593Smuzhiyun bus_addr, len);
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
ps3_repository_read_dev_reg(unsigned int bus_index,unsigned int dev_index,unsigned int reg_index,enum ps3_reg_type * reg_type,u64 * bus_addr,u64 * len)277*4882a593Smuzhiyun int ps3_repository_read_dev_reg(unsigned int bus_index,
278*4882a593Smuzhiyun unsigned int dev_index, unsigned int reg_index,
279*4882a593Smuzhiyun enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
282*4882a593Smuzhiyun reg_index, reg_type);
283*4882a593Smuzhiyun return result ? result
284*4882a593Smuzhiyun : ps3_repository_read_dev_reg_addr(bus_index, dev_index,
285*4882a593Smuzhiyun reg_index, bus_addr, len);
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun
ps3_repository_find_device(struct ps3_repository_device * repo)290*4882a593Smuzhiyun int ps3_repository_find_device(struct ps3_repository_device *repo)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun int result;
293*4882a593Smuzhiyun struct ps3_repository_device tmp = *repo;
294*4882a593Smuzhiyun unsigned int num_dev;
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun BUG_ON(repo->bus_index > 10);
297*4882a593Smuzhiyun BUG_ON(repo->dev_index > 10);
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun if (result) {
302*4882a593Smuzhiyun pr_devel("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
303*4882a593Smuzhiyun return result;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun pr_devel("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n",
307*4882a593Smuzhiyun __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
308*4882a593Smuzhiyun num_dev);
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun if (tmp.dev_index >= num_dev) {
311*4882a593Smuzhiyun pr_devel("%s:%d: no device found\n", __func__, __LINE__);
312*4882a593Smuzhiyun return -ENODEV;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
316*4882a593Smuzhiyun &tmp.dev_type);
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun if (result) {
319*4882a593Smuzhiyun pr_devel("%s:%d read_dev_type failed\n", __func__, __LINE__);
320*4882a593Smuzhiyun return result;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
324*4882a593Smuzhiyun &tmp.dev_id);
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun if (result) {
327*4882a593Smuzhiyun pr_devel("%s:%d ps3_repository_read_dev_id failed\n", __func__,
328*4882a593Smuzhiyun __LINE__);
329*4882a593Smuzhiyun return result;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun pr_devel("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n",
333*4882a593Smuzhiyun __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun *repo = tmp;
336*4882a593Smuzhiyun return 0;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun
ps3_repository_find_device_by_id(struct ps3_repository_device * repo,u64 bus_id,u64 dev_id)339*4882a593Smuzhiyun int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
340*4882a593Smuzhiyun u64 bus_id, u64 dev_id)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun int result = -ENODEV;
343*4882a593Smuzhiyun struct ps3_repository_device tmp;
344*4882a593Smuzhiyun unsigned int num_dev;
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun pr_devel(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__,
347*4882a593Smuzhiyun bus_id, dev_id);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) {
350*4882a593Smuzhiyun result = ps3_repository_read_bus_id(tmp.bus_index,
351*4882a593Smuzhiyun &tmp.bus_id);
352*4882a593Smuzhiyun if (result) {
353*4882a593Smuzhiyun pr_devel("%s:%u read_bus_id(%u) failed\n", __func__,
354*4882a593Smuzhiyun __LINE__, tmp.bus_index);
355*4882a593Smuzhiyun return result;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun if (tmp.bus_id == bus_id)
359*4882a593Smuzhiyun goto found_bus;
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun pr_devel("%s:%u: skip, bus_id %llu\n", __func__, __LINE__,
362*4882a593Smuzhiyun tmp.bus_id);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
365*4882a593Smuzhiyun return result;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun found_bus:
368*4882a593Smuzhiyun result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type);
369*4882a593Smuzhiyun if (result) {
370*4882a593Smuzhiyun pr_devel("%s:%u read_bus_type(%u) failed\n", __func__,
371*4882a593Smuzhiyun __LINE__, tmp.bus_index);
372*4882a593Smuzhiyun return result;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
376*4882a593Smuzhiyun if (result) {
377*4882a593Smuzhiyun pr_devel("%s:%u read_bus_num_dev failed\n", __func__,
378*4882a593Smuzhiyun __LINE__);
379*4882a593Smuzhiyun return result;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) {
383*4882a593Smuzhiyun result = ps3_repository_read_dev_id(tmp.bus_index,
384*4882a593Smuzhiyun tmp.dev_index,
385*4882a593Smuzhiyun &tmp.dev_id);
386*4882a593Smuzhiyun if (result) {
387*4882a593Smuzhiyun pr_devel("%s:%u read_dev_id(%u:%u) failed\n", __func__,
388*4882a593Smuzhiyun __LINE__, tmp.bus_index, tmp.dev_index);
389*4882a593Smuzhiyun return result;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun if (tmp.dev_id == dev_id)
393*4882a593Smuzhiyun goto found_dev;
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun pr_devel("%s:%u: skip, dev_id %llu\n", __func__, __LINE__,
396*4882a593Smuzhiyun tmp.dev_id);
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun pr_devel(" <- %s:%u: dev not found\n", __func__, __LINE__);
399*4882a593Smuzhiyun return result;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun found_dev:
402*4882a593Smuzhiyun result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
403*4882a593Smuzhiyun &tmp.dev_type);
404*4882a593Smuzhiyun if (result) {
405*4882a593Smuzhiyun pr_devel("%s:%u read_dev_type failed\n", __func__, __LINE__);
406*4882a593Smuzhiyun return result;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun pr_devel(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n",
410*4882a593Smuzhiyun __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index,
411*4882a593Smuzhiyun tmp.dev_index, tmp.bus_id, tmp.dev_id);
412*4882a593Smuzhiyun *repo = tmp;
413*4882a593Smuzhiyun return 0;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun
ps3_repository_find_devices(enum ps3_bus_type bus_type,int (* callback)(const struct ps3_repository_device * repo))416*4882a593Smuzhiyun int ps3_repository_find_devices(enum ps3_bus_type bus_type,
417*4882a593Smuzhiyun int (*callback)(const struct ps3_repository_device *repo))
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun int result = 0;
420*4882a593Smuzhiyun struct ps3_repository_device repo;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun pr_devel(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun repo.bus_type = bus_type;
425*4882a593Smuzhiyun result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
426*4882a593Smuzhiyun if (result) {
427*4882a593Smuzhiyun pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
428*4882a593Smuzhiyun return result;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
432*4882a593Smuzhiyun if (result) {
433*4882a593Smuzhiyun pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__,
434*4882a593Smuzhiyun repo.bus_index);
435*4882a593Smuzhiyun return result;
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun for (repo.dev_index = 0; ; repo.dev_index++) {
439*4882a593Smuzhiyun result = ps3_repository_find_device(&repo);
440*4882a593Smuzhiyun if (result == -ENODEV) {
441*4882a593Smuzhiyun result = 0;
442*4882a593Smuzhiyun break;
443*4882a593Smuzhiyun } else if (result)
444*4882a593Smuzhiyun break;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun result = callback(&repo);
447*4882a593Smuzhiyun if (result) {
448*4882a593Smuzhiyun pr_devel("%s:%d: abort at callback\n", __func__,
449*4882a593Smuzhiyun __LINE__);
450*4882a593Smuzhiyun break;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun pr_devel(" <- %s:%d\n", __func__, __LINE__);
455*4882a593Smuzhiyun return result;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun
ps3_repository_find_bus(enum ps3_bus_type bus_type,unsigned int from,unsigned int * bus_index)458*4882a593Smuzhiyun int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
459*4882a593Smuzhiyun unsigned int *bus_index)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun unsigned int i;
462*4882a593Smuzhiyun enum ps3_bus_type type;
463*4882a593Smuzhiyun int error;
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun for (i = from; i < 10; i++) {
466*4882a593Smuzhiyun error = ps3_repository_read_bus_type(i, &type);
467*4882a593Smuzhiyun if (error) {
468*4882a593Smuzhiyun pr_devel("%s:%d read_bus_type failed\n",
469*4882a593Smuzhiyun __func__, __LINE__);
470*4882a593Smuzhiyun *bus_index = UINT_MAX;
471*4882a593Smuzhiyun return error;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun if (type == bus_type) {
474*4882a593Smuzhiyun *bus_index = i;
475*4882a593Smuzhiyun return 0;
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun *bus_index = UINT_MAX;
479*4882a593Smuzhiyun return -ENODEV;
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
ps3_repository_find_interrupt(const struct ps3_repository_device * repo,enum ps3_interrupt_type intr_type,unsigned int * interrupt_id)482*4882a593Smuzhiyun int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
483*4882a593Smuzhiyun enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
484*4882a593Smuzhiyun {
485*4882a593Smuzhiyun int result = 0;
486*4882a593Smuzhiyun unsigned int res_index;
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun pr_devel("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun *interrupt_id = UINT_MAX;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun for (res_index = 0; res_index < 10; res_index++) {
493*4882a593Smuzhiyun enum ps3_interrupt_type t;
494*4882a593Smuzhiyun unsigned int id;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun result = ps3_repository_read_dev_intr(repo->bus_index,
497*4882a593Smuzhiyun repo->dev_index, res_index, &t, &id);
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun if (result) {
500*4882a593Smuzhiyun pr_devel("%s:%d read_dev_intr failed\n",
501*4882a593Smuzhiyun __func__, __LINE__);
502*4882a593Smuzhiyun return result;
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun if (t == intr_type) {
506*4882a593Smuzhiyun *interrupt_id = id;
507*4882a593Smuzhiyun break;
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun if (res_index == 10)
512*4882a593Smuzhiyun return -ENODEV;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun pr_devel("%s:%d: found intr_type %u at res_index %u\n",
515*4882a593Smuzhiyun __func__, __LINE__, intr_type, res_index);
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun return result;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
ps3_repository_find_reg(const struct ps3_repository_device * repo,enum ps3_reg_type reg_type,u64 * bus_addr,u64 * len)520*4882a593Smuzhiyun int ps3_repository_find_reg(const struct ps3_repository_device *repo,
521*4882a593Smuzhiyun enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
522*4882a593Smuzhiyun {
523*4882a593Smuzhiyun int result = 0;
524*4882a593Smuzhiyun unsigned int res_index;
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun pr_devel("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun *bus_addr = *len = 0;
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun for (res_index = 0; res_index < 10; res_index++) {
531*4882a593Smuzhiyun enum ps3_reg_type t;
532*4882a593Smuzhiyun u64 a;
533*4882a593Smuzhiyun u64 l;
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun result = ps3_repository_read_dev_reg(repo->bus_index,
536*4882a593Smuzhiyun repo->dev_index, res_index, &t, &a, &l);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun if (result) {
539*4882a593Smuzhiyun pr_devel("%s:%d read_dev_reg failed\n",
540*4882a593Smuzhiyun __func__, __LINE__);
541*4882a593Smuzhiyun return result;
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun if (t == reg_type) {
545*4882a593Smuzhiyun *bus_addr = a;
546*4882a593Smuzhiyun *len = l;
547*4882a593Smuzhiyun break;
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun if (res_index == 10)
552*4882a593Smuzhiyun return -ENODEV;
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun pr_devel("%s:%d: found reg_type %u at res_index %u\n",
555*4882a593Smuzhiyun __func__, __LINE__, reg_type, res_index);
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun return result;
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
ps3_repository_read_stor_dev_port(unsigned int bus_index,unsigned int dev_index,u64 * port)560*4882a593Smuzhiyun int ps3_repository_read_stor_dev_port(unsigned int bus_index,
561*4882a593Smuzhiyun unsigned int dev_index, u64 *port)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
564*4882a593Smuzhiyun make_first_field("bus", bus_index),
565*4882a593Smuzhiyun make_field("dev", dev_index),
566*4882a593Smuzhiyun make_field("port", 0),
567*4882a593Smuzhiyun 0, port, NULL);
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun
ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,unsigned int dev_index,u64 * blk_size)570*4882a593Smuzhiyun int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,
571*4882a593Smuzhiyun unsigned int dev_index, u64 *blk_size)
572*4882a593Smuzhiyun {
573*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
574*4882a593Smuzhiyun make_first_field("bus", bus_index),
575*4882a593Smuzhiyun make_field("dev", dev_index),
576*4882a593Smuzhiyun make_field("blk_size", 0),
577*4882a593Smuzhiyun 0, blk_size, NULL);
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun
ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,unsigned int dev_index,u64 * num_blocks)580*4882a593Smuzhiyun int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,
581*4882a593Smuzhiyun unsigned int dev_index, u64 *num_blocks)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
584*4882a593Smuzhiyun make_first_field("bus", bus_index),
585*4882a593Smuzhiyun make_field("dev", dev_index),
586*4882a593Smuzhiyun make_field("n_blocks", 0),
587*4882a593Smuzhiyun 0, num_blocks, NULL);
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,unsigned int dev_index,unsigned int * num_regions)590*4882a593Smuzhiyun int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
591*4882a593Smuzhiyun unsigned int dev_index, unsigned int *num_regions)
592*4882a593Smuzhiyun {
593*4882a593Smuzhiyun int result;
594*4882a593Smuzhiyun u64 v1 = 0;
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
597*4882a593Smuzhiyun make_first_field("bus", bus_index),
598*4882a593Smuzhiyun make_field("dev", dev_index),
599*4882a593Smuzhiyun make_field("n_regs", 0),
600*4882a593Smuzhiyun 0, &v1, NULL);
601*4882a593Smuzhiyun *num_regions = v1;
602*4882a593Smuzhiyun return result;
603*4882a593Smuzhiyun }
604*4882a593Smuzhiyun
ps3_repository_read_stor_dev_region_id(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,unsigned int * region_id)605*4882a593Smuzhiyun int ps3_repository_read_stor_dev_region_id(unsigned int bus_index,
606*4882a593Smuzhiyun unsigned int dev_index, unsigned int region_index,
607*4882a593Smuzhiyun unsigned int *region_id)
608*4882a593Smuzhiyun {
609*4882a593Smuzhiyun int result;
610*4882a593Smuzhiyun u64 v1 = 0;
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
613*4882a593Smuzhiyun make_first_field("bus", bus_index),
614*4882a593Smuzhiyun make_field("dev", dev_index),
615*4882a593Smuzhiyun make_field("region", region_index),
616*4882a593Smuzhiyun make_field("id", 0),
617*4882a593Smuzhiyun &v1, NULL);
618*4882a593Smuzhiyun *region_id = v1;
619*4882a593Smuzhiyun return result;
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun
ps3_repository_read_stor_dev_region_size(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,u64 * region_size)622*4882a593Smuzhiyun int ps3_repository_read_stor_dev_region_size(unsigned int bus_index,
623*4882a593Smuzhiyun unsigned int dev_index, unsigned int region_index, u64 *region_size)
624*4882a593Smuzhiyun {
625*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
626*4882a593Smuzhiyun make_first_field("bus", bus_index),
627*4882a593Smuzhiyun make_field("dev", dev_index),
628*4882a593Smuzhiyun make_field("region", region_index),
629*4882a593Smuzhiyun make_field("size", 0),
630*4882a593Smuzhiyun region_size, NULL);
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun
ps3_repository_read_stor_dev_region_start(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,u64 * region_start)633*4882a593Smuzhiyun int ps3_repository_read_stor_dev_region_start(unsigned int bus_index,
634*4882a593Smuzhiyun unsigned int dev_index, unsigned int region_index, u64 *region_start)
635*4882a593Smuzhiyun {
636*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
637*4882a593Smuzhiyun make_first_field("bus", bus_index),
638*4882a593Smuzhiyun make_field("dev", dev_index),
639*4882a593Smuzhiyun make_field("region", region_index),
640*4882a593Smuzhiyun make_field("start", 0),
641*4882a593Smuzhiyun region_start, NULL);
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun
ps3_repository_read_stor_dev_info(unsigned int bus_index,unsigned int dev_index,u64 * port,u64 * blk_size,u64 * num_blocks,unsigned int * num_regions)644*4882a593Smuzhiyun int ps3_repository_read_stor_dev_info(unsigned int bus_index,
645*4882a593Smuzhiyun unsigned int dev_index, u64 *port, u64 *blk_size,
646*4882a593Smuzhiyun u64 *num_blocks, unsigned int *num_regions)
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun int result;
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_port(bus_index, dev_index, port);
651*4882a593Smuzhiyun if (result)
652*4882a593Smuzhiyun return result;
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_blk_size(bus_index, dev_index,
655*4882a593Smuzhiyun blk_size);
656*4882a593Smuzhiyun if (result)
657*4882a593Smuzhiyun return result;
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_num_blocks(bus_index, dev_index,
660*4882a593Smuzhiyun num_blocks);
661*4882a593Smuzhiyun if (result)
662*4882a593Smuzhiyun return result;
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_num_regions(bus_index, dev_index,
665*4882a593Smuzhiyun num_regions);
666*4882a593Smuzhiyun return result;
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun
ps3_repository_read_stor_dev_region(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,unsigned int * region_id,u64 * region_start,u64 * region_size)669*4882a593Smuzhiyun int ps3_repository_read_stor_dev_region(unsigned int bus_index,
670*4882a593Smuzhiyun unsigned int dev_index, unsigned int region_index,
671*4882a593Smuzhiyun unsigned int *region_id, u64 *region_start, u64 *region_size)
672*4882a593Smuzhiyun {
673*4882a593Smuzhiyun int result;
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_region_id(bus_index, dev_index,
676*4882a593Smuzhiyun region_index, region_id);
677*4882a593Smuzhiyun if (result)
678*4882a593Smuzhiyun return result;
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_region_start(bus_index, dev_index,
681*4882a593Smuzhiyun region_index, region_start);
682*4882a593Smuzhiyun if (result)
683*4882a593Smuzhiyun return result;
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_region_size(bus_index, dev_index,
686*4882a593Smuzhiyun region_index, region_size);
687*4882a593Smuzhiyun return result;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun /**
691*4882a593Smuzhiyun * ps3_repository_read_num_pu - Number of logical PU processors for this lpar.
692*4882a593Smuzhiyun */
693*4882a593Smuzhiyun
ps3_repository_read_num_pu(u64 * num_pu)694*4882a593Smuzhiyun int ps3_repository_read_num_pu(u64 *num_pu)
695*4882a593Smuzhiyun {
696*4882a593Smuzhiyun *num_pu = 0;
697*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_CURRENT,
698*4882a593Smuzhiyun make_first_field("bi", 0),
699*4882a593Smuzhiyun make_field("pun", 0),
700*4882a593Smuzhiyun 0, 0,
701*4882a593Smuzhiyun num_pu, NULL);
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun /**
705*4882a593Smuzhiyun * ps3_repository_read_pu_id - Read the logical PU id.
706*4882a593Smuzhiyun * @pu_index: Zero based index.
707*4882a593Smuzhiyun * @pu_id: The logical PU id.
708*4882a593Smuzhiyun */
709*4882a593Smuzhiyun
ps3_repository_read_pu_id(unsigned int pu_index,u64 * pu_id)710*4882a593Smuzhiyun int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_CURRENT,
713*4882a593Smuzhiyun make_first_field("bi", 0),
714*4882a593Smuzhiyun make_field("pu", pu_index),
715*4882a593Smuzhiyun 0, 0,
716*4882a593Smuzhiyun pu_id, NULL);
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun
ps3_repository_read_rm_size(unsigned int ppe_id,u64 * rm_size)719*4882a593Smuzhiyun int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
720*4882a593Smuzhiyun {
721*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_CURRENT,
722*4882a593Smuzhiyun make_first_field("bi", 0),
723*4882a593Smuzhiyun make_field("pu", 0),
724*4882a593Smuzhiyun ppe_id,
725*4882a593Smuzhiyun make_field("rm_size", 0),
726*4882a593Smuzhiyun rm_size, NULL);
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun
ps3_repository_read_region_total(u64 * region_total)729*4882a593Smuzhiyun int ps3_repository_read_region_total(u64 *region_total)
730*4882a593Smuzhiyun {
731*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_CURRENT,
732*4882a593Smuzhiyun make_first_field("bi", 0),
733*4882a593Smuzhiyun make_field("rgntotal", 0),
734*4882a593Smuzhiyun 0, 0,
735*4882a593Smuzhiyun region_total, NULL);
736*4882a593Smuzhiyun }
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun /**
739*4882a593Smuzhiyun * ps3_repository_read_mm_info - Read mm info for single pu system.
740*4882a593Smuzhiyun * @rm_base: Real mode memory base address.
741*4882a593Smuzhiyun * @rm_size: Real mode memory size.
742*4882a593Smuzhiyun * @region_total: Maximum memory region size.
743*4882a593Smuzhiyun */
744*4882a593Smuzhiyun
ps3_repository_read_mm_info(u64 * rm_base,u64 * rm_size,u64 * region_total)745*4882a593Smuzhiyun int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
746*4882a593Smuzhiyun {
747*4882a593Smuzhiyun int result;
748*4882a593Smuzhiyun u64 ppe_id;
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun lv1_get_logical_ppe_id(&ppe_id);
751*4882a593Smuzhiyun *rm_base = 0;
752*4882a593Smuzhiyun result = ps3_repository_read_rm_size(ppe_id, rm_size);
753*4882a593Smuzhiyun return result ? result
754*4882a593Smuzhiyun : ps3_repository_read_region_total(region_total);
755*4882a593Smuzhiyun }
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun /**
758*4882a593Smuzhiyun * ps3_repository_read_highmem_region_count - Read the number of highmem regions
759*4882a593Smuzhiyun *
760*4882a593Smuzhiyun * Bootloaders must arrange the repository nodes such that regions are indexed
761*4882a593Smuzhiyun * with a region_index from 0 to region_count-1.
762*4882a593Smuzhiyun */
763*4882a593Smuzhiyun
ps3_repository_read_highmem_region_count(unsigned int * region_count)764*4882a593Smuzhiyun int ps3_repository_read_highmem_region_count(unsigned int *region_count)
765*4882a593Smuzhiyun {
766*4882a593Smuzhiyun int result;
767*4882a593Smuzhiyun u64 v1 = 0;
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_CURRENT,
770*4882a593Smuzhiyun make_first_field("highmem", 0),
771*4882a593Smuzhiyun make_field("region", 0),
772*4882a593Smuzhiyun make_field("count", 0),
773*4882a593Smuzhiyun 0,
774*4882a593Smuzhiyun &v1, NULL);
775*4882a593Smuzhiyun *region_count = v1;
776*4882a593Smuzhiyun return result;
777*4882a593Smuzhiyun }
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun
ps3_repository_read_highmem_base(unsigned int region_index,u64 * highmem_base)780*4882a593Smuzhiyun int ps3_repository_read_highmem_base(unsigned int region_index,
781*4882a593Smuzhiyun u64 *highmem_base)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_CURRENT,
784*4882a593Smuzhiyun make_first_field("highmem", 0),
785*4882a593Smuzhiyun make_field("region", region_index),
786*4882a593Smuzhiyun make_field("base", 0),
787*4882a593Smuzhiyun 0,
788*4882a593Smuzhiyun highmem_base, NULL);
789*4882a593Smuzhiyun }
790*4882a593Smuzhiyun
ps3_repository_read_highmem_size(unsigned int region_index,u64 * highmem_size)791*4882a593Smuzhiyun int ps3_repository_read_highmem_size(unsigned int region_index,
792*4882a593Smuzhiyun u64 *highmem_size)
793*4882a593Smuzhiyun {
794*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_CURRENT,
795*4882a593Smuzhiyun make_first_field("highmem", 0),
796*4882a593Smuzhiyun make_field("region", region_index),
797*4882a593Smuzhiyun make_field("size", 0),
798*4882a593Smuzhiyun 0,
799*4882a593Smuzhiyun highmem_size, NULL);
800*4882a593Smuzhiyun }
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun /**
803*4882a593Smuzhiyun * ps3_repository_read_highmem_info - Read high memory region info
804*4882a593Smuzhiyun * @region_index: Region index, {0,..,region_count-1}.
805*4882a593Smuzhiyun * @highmem_base: High memory base address.
806*4882a593Smuzhiyun * @highmem_size: High memory size.
807*4882a593Smuzhiyun *
808*4882a593Smuzhiyun * Bootloaders that preallocate highmem regions must place the
809*4882a593Smuzhiyun * region info into the repository at these well known nodes.
810*4882a593Smuzhiyun */
811*4882a593Smuzhiyun
ps3_repository_read_highmem_info(unsigned int region_index,u64 * highmem_base,u64 * highmem_size)812*4882a593Smuzhiyun int ps3_repository_read_highmem_info(unsigned int region_index,
813*4882a593Smuzhiyun u64 *highmem_base, u64 *highmem_size)
814*4882a593Smuzhiyun {
815*4882a593Smuzhiyun int result;
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun *highmem_base = 0;
818*4882a593Smuzhiyun result = ps3_repository_read_highmem_base(region_index, highmem_base);
819*4882a593Smuzhiyun return result ? result
820*4882a593Smuzhiyun : ps3_repository_read_highmem_size(region_index, highmem_size);
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun /**
824*4882a593Smuzhiyun * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
825*4882a593Smuzhiyun * @num_spu: Number of physical spus.
826*4882a593Smuzhiyun */
827*4882a593Smuzhiyun
ps3_repository_read_num_spu_reserved(unsigned int * num_spu_reserved)828*4882a593Smuzhiyun int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun int result;
831*4882a593Smuzhiyun u64 v1 = 0;
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_CURRENT,
834*4882a593Smuzhiyun make_first_field("bi", 0),
835*4882a593Smuzhiyun make_field("spun", 0),
836*4882a593Smuzhiyun 0, 0,
837*4882a593Smuzhiyun &v1, NULL);
838*4882a593Smuzhiyun *num_spu_reserved = v1;
839*4882a593Smuzhiyun return result;
840*4882a593Smuzhiyun }
841*4882a593Smuzhiyun
842*4882a593Smuzhiyun /**
843*4882a593Smuzhiyun * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations.
844*4882a593Smuzhiyun * @num_resource_id: Number of spu resource ids.
845*4882a593Smuzhiyun */
846*4882a593Smuzhiyun
ps3_repository_read_num_spu_resource_id(unsigned int * num_resource_id)847*4882a593Smuzhiyun int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
848*4882a593Smuzhiyun {
849*4882a593Smuzhiyun int result;
850*4882a593Smuzhiyun u64 v1 = 0;
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_CURRENT,
853*4882a593Smuzhiyun make_first_field("bi", 0),
854*4882a593Smuzhiyun make_field("spursvn", 0),
855*4882a593Smuzhiyun 0, 0,
856*4882a593Smuzhiyun &v1, NULL);
857*4882a593Smuzhiyun *num_resource_id = v1;
858*4882a593Smuzhiyun return result;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun /**
862*4882a593Smuzhiyun * ps3_repository_read_spu_resource_id - spu resource reservation id value.
863*4882a593Smuzhiyun * @res_index: Resource reservation index.
864*4882a593Smuzhiyun * @resource_type: Resource reservation type.
865*4882a593Smuzhiyun * @resource_id: Resource reservation id.
866*4882a593Smuzhiyun */
867*4882a593Smuzhiyun
ps3_repository_read_spu_resource_id(unsigned int res_index,enum ps3_spu_resource_type * resource_type,unsigned int * resource_id)868*4882a593Smuzhiyun int ps3_repository_read_spu_resource_id(unsigned int res_index,
869*4882a593Smuzhiyun enum ps3_spu_resource_type *resource_type, unsigned int *resource_id)
870*4882a593Smuzhiyun {
871*4882a593Smuzhiyun int result;
872*4882a593Smuzhiyun u64 v1 = 0;
873*4882a593Smuzhiyun u64 v2 = 0;
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_CURRENT,
876*4882a593Smuzhiyun make_first_field("bi", 0),
877*4882a593Smuzhiyun make_field("spursv", 0),
878*4882a593Smuzhiyun res_index,
879*4882a593Smuzhiyun 0,
880*4882a593Smuzhiyun &v1, &v2);
881*4882a593Smuzhiyun *resource_type = v1;
882*4882a593Smuzhiyun *resource_id = v2;
883*4882a593Smuzhiyun return result;
884*4882a593Smuzhiyun }
885*4882a593Smuzhiyun
ps3_repository_read_boot_dat_address(u64 * address)886*4882a593Smuzhiyun static int ps3_repository_read_boot_dat_address(u64 *address)
887*4882a593Smuzhiyun {
888*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_CURRENT,
889*4882a593Smuzhiyun make_first_field("bi", 0),
890*4882a593Smuzhiyun make_field("boot_dat", 0),
891*4882a593Smuzhiyun make_field("address", 0),
892*4882a593Smuzhiyun 0,
893*4882a593Smuzhiyun address, NULL);
894*4882a593Smuzhiyun }
895*4882a593Smuzhiyun
ps3_repository_read_boot_dat_size(unsigned int * size)896*4882a593Smuzhiyun int ps3_repository_read_boot_dat_size(unsigned int *size)
897*4882a593Smuzhiyun {
898*4882a593Smuzhiyun int result;
899*4882a593Smuzhiyun u64 v1 = 0;
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_CURRENT,
902*4882a593Smuzhiyun make_first_field("bi", 0),
903*4882a593Smuzhiyun make_field("boot_dat", 0),
904*4882a593Smuzhiyun make_field("size", 0),
905*4882a593Smuzhiyun 0,
906*4882a593Smuzhiyun &v1, NULL);
907*4882a593Smuzhiyun *size = v1;
908*4882a593Smuzhiyun return result;
909*4882a593Smuzhiyun }
910*4882a593Smuzhiyun
ps3_repository_read_vuart_av_port(unsigned int * port)911*4882a593Smuzhiyun int ps3_repository_read_vuart_av_port(unsigned int *port)
912*4882a593Smuzhiyun {
913*4882a593Smuzhiyun int result;
914*4882a593Smuzhiyun u64 v1 = 0;
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_CURRENT,
917*4882a593Smuzhiyun make_first_field("bi", 0),
918*4882a593Smuzhiyun make_field("vir_uart", 0),
919*4882a593Smuzhiyun make_field("port", 0),
920*4882a593Smuzhiyun make_field("avset", 0),
921*4882a593Smuzhiyun &v1, NULL);
922*4882a593Smuzhiyun *port = v1;
923*4882a593Smuzhiyun return result;
924*4882a593Smuzhiyun }
925*4882a593Smuzhiyun
ps3_repository_read_vuart_sysmgr_port(unsigned int * port)926*4882a593Smuzhiyun int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
927*4882a593Smuzhiyun {
928*4882a593Smuzhiyun int result;
929*4882a593Smuzhiyun u64 v1 = 0;
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_CURRENT,
932*4882a593Smuzhiyun make_first_field("bi", 0),
933*4882a593Smuzhiyun make_field("vir_uart", 0),
934*4882a593Smuzhiyun make_field("port", 0),
935*4882a593Smuzhiyun make_field("sysmgr", 0),
936*4882a593Smuzhiyun &v1, NULL);
937*4882a593Smuzhiyun *port = v1;
938*4882a593Smuzhiyun return result;
939*4882a593Smuzhiyun }
940*4882a593Smuzhiyun
941*4882a593Smuzhiyun /**
942*4882a593Smuzhiyun * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
943*4882a593Smuzhiyun * address: lpar address of cell_ext_os_area
944*4882a593Smuzhiyun * @size: size of cell_ext_os_area
945*4882a593Smuzhiyun */
946*4882a593Smuzhiyun
ps3_repository_read_boot_dat_info(u64 * lpar_addr,unsigned int * size)947*4882a593Smuzhiyun int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
948*4882a593Smuzhiyun {
949*4882a593Smuzhiyun int result;
950*4882a593Smuzhiyun
951*4882a593Smuzhiyun *size = 0;
952*4882a593Smuzhiyun result = ps3_repository_read_boot_dat_address(lpar_addr);
953*4882a593Smuzhiyun return result ? result
954*4882a593Smuzhiyun : ps3_repository_read_boot_dat_size(size);
955*4882a593Smuzhiyun }
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun /**
958*4882a593Smuzhiyun * ps3_repository_read_num_be - Number of physical BE processors in the system.
959*4882a593Smuzhiyun */
960*4882a593Smuzhiyun
ps3_repository_read_num_be(unsigned int * num_be)961*4882a593Smuzhiyun int ps3_repository_read_num_be(unsigned int *num_be)
962*4882a593Smuzhiyun {
963*4882a593Smuzhiyun int result;
964*4882a593Smuzhiyun u64 v1 = 0;
965*4882a593Smuzhiyun
966*4882a593Smuzhiyun result = read_node(PS3_LPAR_ID_PME,
967*4882a593Smuzhiyun make_first_field("ben", 0),
968*4882a593Smuzhiyun 0,
969*4882a593Smuzhiyun 0,
970*4882a593Smuzhiyun 0,
971*4882a593Smuzhiyun &v1, NULL);
972*4882a593Smuzhiyun *num_be = v1;
973*4882a593Smuzhiyun return result;
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun /**
977*4882a593Smuzhiyun * ps3_repository_read_be_node_id - Read the physical BE processor node id.
978*4882a593Smuzhiyun * @be_index: Zero based index.
979*4882a593Smuzhiyun * @node_id: The BE processor node id.
980*4882a593Smuzhiyun */
981*4882a593Smuzhiyun
ps3_repository_read_be_node_id(unsigned int be_index,u64 * node_id)982*4882a593Smuzhiyun int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
983*4882a593Smuzhiyun {
984*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
985*4882a593Smuzhiyun make_first_field("be", be_index),
986*4882a593Smuzhiyun 0,
987*4882a593Smuzhiyun 0,
988*4882a593Smuzhiyun 0,
989*4882a593Smuzhiyun node_id, NULL);
990*4882a593Smuzhiyun }
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun /**
993*4882a593Smuzhiyun * ps3_repository_read_be_id - Read the physical BE processor id.
994*4882a593Smuzhiyun * @node_id: The BE processor node id.
995*4882a593Smuzhiyun * @be_id: The BE processor id.
996*4882a593Smuzhiyun */
997*4882a593Smuzhiyun
ps3_repository_read_be_id(u64 node_id,u64 * be_id)998*4882a593Smuzhiyun int ps3_repository_read_be_id(u64 node_id, u64 *be_id)
999*4882a593Smuzhiyun {
1000*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
1001*4882a593Smuzhiyun make_first_field("be", 0),
1002*4882a593Smuzhiyun node_id,
1003*4882a593Smuzhiyun 0,
1004*4882a593Smuzhiyun 0,
1005*4882a593Smuzhiyun be_id, NULL);
1006*4882a593Smuzhiyun }
1007*4882a593Smuzhiyun
ps3_repository_read_tb_freq(u64 node_id,u64 * tb_freq)1008*4882a593Smuzhiyun int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
1009*4882a593Smuzhiyun {
1010*4882a593Smuzhiyun return read_node(PS3_LPAR_ID_PME,
1011*4882a593Smuzhiyun make_first_field("be", 0),
1012*4882a593Smuzhiyun node_id,
1013*4882a593Smuzhiyun make_field("clock", 0),
1014*4882a593Smuzhiyun 0,
1015*4882a593Smuzhiyun tb_freq, NULL);
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun
ps3_repository_read_be_tb_freq(unsigned int be_index,u64 * tb_freq)1018*4882a593Smuzhiyun int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
1019*4882a593Smuzhiyun {
1020*4882a593Smuzhiyun int result;
1021*4882a593Smuzhiyun u64 node_id;
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun *tb_freq = 0;
1024*4882a593Smuzhiyun result = ps3_repository_read_be_node_id(be_index, &node_id);
1025*4882a593Smuzhiyun return result ? result
1026*4882a593Smuzhiyun : ps3_repository_read_tb_freq(node_id, tb_freq);
1027*4882a593Smuzhiyun }
1028*4882a593Smuzhiyun
ps3_repository_read_lpm_privileges(unsigned int be_index,u64 * lpar,u64 * rights)1029*4882a593Smuzhiyun int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
1030*4882a593Smuzhiyun u64 *rights)
1031*4882a593Smuzhiyun {
1032*4882a593Smuzhiyun int result;
1033*4882a593Smuzhiyun u64 node_id;
1034*4882a593Smuzhiyun
1035*4882a593Smuzhiyun *lpar = 0;
1036*4882a593Smuzhiyun *rights = 0;
1037*4882a593Smuzhiyun result = ps3_repository_read_be_node_id(be_index, &node_id);
1038*4882a593Smuzhiyun return result ? result
1039*4882a593Smuzhiyun : read_node(PS3_LPAR_ID_PME,
1040*4882a593Smuzhiyun make_first_field("be", 0),
1041*4882a593Smuzhiyun node_id,
1042*4882a593Smuzhiyun make_field("lpm", 0),
1043*4882a593Smuzhiyun make_field("priv", 0),
1044*4882a593Smuzhiyun lpar, rights);
1045*4882a593Smuzhiyun }
1046*4882a593Smuzhiyun
1047*4882a593Smuzhiyun #if defined(CONFIG_PS3_REPOSITORY_WRITE)
1048*4882a593Smuzhiyun
create_node(u64 n1,u64 n2,u64 n3,u64 n4,u64 v1,u64 v2)1049*4882a593Smuzhiyun static int create_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2)
1050*4882a593Smuzhiyun {
1051*4882a593Smuzhiyun int result;
1052*4882a593Smuzhiyun
1053*4882a593Smuzhiyun dump_node(0, n1, n2, n3, n4, v1, v2);
1054*4882a593Smuzhiyun
1055*4882a593Smuzhiyun result = lv1_create_repository_node(n1, n2, n3, n4, v1, v2);
1056*4882a593Smuzhiyun
1057*4882a593Smuzhiyun if (result) {
1058*4882a593Smuzhiyun pr_devel("%s:%d: lv1_create_repository_node failed: %s\n",
1059*4882a593Smuzhiyun __func__, __LINE__, ps3_result(result));
1060*4882a593Smuzhiyun return -ENOENT;
1061*4882a593Smuzhiyun }
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun return 0;
1064*4882a593Smuzhiyun }
1065*4882a593Smuzhiyun
delete_node(u64 n1,u64 n2,u64 n3,u64 n4)1066*4882a593Smuzhiyun static int delete_node(u64 n1, u64 n2, u64 n3, u64 n4)
1067*4882a593Smuzhiyun {
1068*4882a593Smuzhiyun int result;
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun dump_node(0, n1, n2, n3, n4, 0, 0);
1071*4882a593Smuzhiyun
1072*4882a593Smuzhiyun result = lv1_delete_repository_node(n1, n2, n3, n4);
1073*4882a593Smuzhiyun
1074*4882a593Smuzhiyun if (result) {
1075*4882a593Smuzhiyun pr_devel("%s:%d: lv1_delete_repository_node failed: %s\n",
1076*4882a593Smuzhiyun __func__, __LINE__, ps3_result(result));
1077*4882a593Smuzhiyun return -ENOENT;
1078*4882a593Smuzhiyun }
1079*4882a593Smuzhiyun
1080*4882a593Smuzhiyun return 0;
1081*4882a593Smuzhiyun }
1082*4882a593Smuzhiyun
write_node(u64 n1,u64 n2,u64 n3,u64 n4,u64 v1,u64 v2)1083*4882a593Smuzhiyun static int write_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2)
1084*4882a593Smuzhiyun {
1085*4882a593Smuzhiyun int result;
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun result = create_node(n1, n2, n3, n4, v1, v2);
1088*4882a593Smuzhiyun
1089*4882a593Smuzhiyun if (!result)
1090*4882a593Smuzhiyun return 0;
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun result = lv1_write_repository_node(n1, n2, n3, n4, v1, v2);
1093*4882a593Smuzhiyun
1094*4882a593Smuzhiyun if (result) {
1095*4882a593Smuzhiyun pr_devel("%s:%d: lv1_write_repository_node failed: %s\n",
1096*4882a593Smuzhiyun __func__, __LINE__, ps3_result(result));
1097*4882a593Smuzhiyun return -ENOENT;
1098*4882a593Smuzhiyun }
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun return 0;
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun
ps3_repository_write_highmem_region_count(unsigned int region_count)1103*4882a593Smuzhiyun int ps3_repository_write_highmem_region_count(unsigned int region_count)
1104*4882a593Smuzhiyun {
1105*4882a593Smuzhiyun int result;
1106*4882a593Smuzhiyun u64 v1 = (u64)region_count;
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun result = write_node(
1109*4882a593Smuzhiyun make_first_field("highmem", 0),
1110*4882a593Smuzhiyun make_field("region", 0),
1111*4882a593Smuzhiyun make_field("count", 0),
1112*4882a593Smuzhiyun 0,
1113*4882a593Smuzhiyun v1, 0);
1114*4882a593Smuzhiyun return result;
1115*4882a593Smuzhiyun }
1116*4882a593Smuzhiyun
ps3_repository_write_highmem_base(unsigned int region_index,u64 highmem_base)1117*4882a593Smuzhiyun int ps3_repository_write_highmem_base(unsigned int region_index,
1118*4882a593Smuzhiyun u64 highmem_base)
1119*4882a593Smuzhiyun {
1120*4882a593Smuzhiyun return write_node(
1121*4882a593Smuzhiyun make_first_field("highmem", 0),
1122*4882a593Smuzhiyun make_field("region", region_index),
1123*4882a593Smuzhiyun make_field("base", 0),
1124*4882a593Smuzhiyun 0,
1125*4882a593Smuzhiyun highmem_base, 0);
1126*4882a593Smuzhiyun }
1127*4882a593Smuzhiyun
ps3_repository_write_highmem_size(unsigned int region_index,u64 highmem_size)1128*4882a593Smuzhiyun int ps3_repository_write_highmem_size(unsigned int region_index,
1129*4882a593Smuzhiyun u64 highmem_size)
1130*4882a593Smuzhiyun {
1131*4882a593Smuzhiyun return write_node(
1132*4882a593Smuzhiyun make_first_field("highmem", 0),
1133*4882a593Smuzhiyun make_field("region", region_index),
1134*4882a593Smuzhiyun make_field("size", 0),
1135*4882a593Smuzhiyun 0,
1136*4882a593Smuzhiyun highmem_size, 0);
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun
ps3_repository_write_highmem_info(unsigned int region_index,u64 highmem_base,u64 highmem_size)1139*4882a593Smuzhiyun int ps3_repository_write_highmem_info(unsigned int region_index,
1140*4882a593Smuzhiyun u64 highmem_base, u64 highmem_size)
1141*4882a593Smuzhiyun {
1142*4882a593Smuzhiyun int result;
1143*4882a593Smuzhiyun
1144*4882a593Smuzhiyun result = ps3_repository_write_highmem_base(region_index, highmem_base);
1145*4882a593Smuzhiyun return result ? result
1146*4882a593Smuzhiyun : ps3_repository_write_highmem_size(region_index, highmem_size);
1147*4882a593Smuzhiyun }
1148*4882a593Smuzhiyun
ps3_repository_delete_highmem_base(unsigned int region_index)1149*4882a593Smuzhiyun static int ps3_repository_delete_highmem_base(unsigned int region_index)
1150*4882a593Smuzhiyun {
1151*4882a593Smuzhiyun return delete_node(
1152*4882a593Smuzhiyun make_first_field("highmem", 0),
1153*4882a593Smuzhiyun make_field("region", region_index),
1154*4882a593Smuzhiyun make_field("base", 0),
1155*4882a593Smuzhiyun 0);
1156*4882a593Smuzhiyun }
1157*4882a593Smuzhiyun
ps3_repository_delete_highmem_size(unsigned int region_index)1158*4882a593Smuzhiyun static int ps3_repository_delete_highmem_size(unsigned int region_index)
1159*4882a593Smuzhiyun {
1160*4882a593Smuzhiyun return delete_node(
1161*4882a593Smuzhiyun make_first_field("highmem", 0),
1162*4882a593Smuzhiyun make_field("region", region_index),
1163*4882a593Smuzhiyun make_field("size", 0),
1164*4882a593Smuzhiyun 0);
1165*4882a593Smuzhiyun }
1166*4882a593Smuzhiyun
ps3_repository_delete_highmem_info(unsigned int region_index)1167*4882a593Smuzhiyun int ps3_repository_delete_highmem_info(unsigned int region_index)
1168*4882a593Smuzhiyun {
1169*4882a593Smuzhiyun int result;
1170*4882a593Smuzhiyun
1171*4882a593Smuzhiyun result = ps3_repository_delete_highmem_base(region_index);
1172*4882a593Smuzhiyun result += ps3_repository_delete_highmem_size(region_index);
1173*4882a593Smuzhiyun
1174*4882a593Smuzhiyun return result ? -1 : 0;
1175*4882a593Smuzhiyun }
1176*4882a593Smuzhiyun
1177*4882a593Smuzhiyun #endif /* defined(CONFIG_PS3_REPOSITORY_WRITE) */
1178*4882a593Smuzhiyun
1179*4882a593Smuzhiyun #if defined(DEBUG)
1180*4882a593Smuzhiyun
ps3_repository_dump_resource_info(const struct ps3_repository_device * repo)1181*4882a593Smuzhiyun int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
1182*4882a593Smuzhiyun {
1183*4882a593Smuzhiyun int result = 0;
1184*4882a593Smuzhiyun unsigned int res_index;
1185*4882a593Smuzhiyun
1186*4882a593Smuzhiyun pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
1187*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1188*4882a593Smuzhiyun
1189*4882a593Smuzhiyun for (res_index = 0; res_index < 10; res_index++) {
1190*4882a593Smuzhiyun enum ps3_interrupt_type intr_type;
1191*4882a593Smuzhiyun unsigned int interrupt_id;
1192*4882a593Smuzhiyun
1193*4882a593Smuzhiyun result = ps3_repository_read_dev_intr(repo->bus_index,
1194*4882a593Smuzhiyun repo->dev_index, res_index, &intr_type, &interrupt_id);
1195*4882a593Smuzhiyun
1196*4882a593Smuzhiyun if (result) {
1197*4882a593Smuzhiyun if (result != LV1_NO_ENTRY)
1198*4882a593Smuzhiyun pr_devel("%s:%d ps3_repository_read_dev_intr"
1199*4882a593Smuzhiyun " (%u:%u) failed\n", __func__, __LINE__,
1200*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1201*4882a593Smuzhiyun break;
1202*4882a593Smuzhiyun }
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun pr_devel("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
1205*4882a593Smuzhiyun __func__, __LINE__, repo->bus_index, repo->dev_index,
1206*4882a593Smuzhiyun intr_type, interrupt_id);
1207*4882a593Smuzhiyun }
1208*4882a593Smuzhiyun
1209*4882a593Smuzhiyun for (res_index = 0; res_index < 10; res_index++) {
1210*4882a593Smuzhiyun enum ps3_reg_type reg_type;
1211*4882a593Smuzhiyun u64 bus_addr;
1212*4882a593Smuzhiyun u64 len;
1213*4882a593Smuzhiyun
1214*4882a593Smuzhiyun result = ps3_repository_read_dev_reg(repo->bus_index,
1215*4882a593Smuzhiyun repo->dev_index, res_index, ®_type, &bus_addr, &len);
1216*4882a593Smuzhiyun
1217*4882a593Smuzhiyun if (result) {
1218*4882a593Smuzhiyun if (result != LV1_NO_ENTRY)
1219*4882a593Smuzhiyun pr_devel("%s:%d ps3_repository_read_dev_reg"
1220*4882a593Smuzhiyun " (%u:%u) failed\n", __func__, __LINE__,
1221*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1222*4882a593Smuzhiyun break;
1223*4882a593Smuzhiyun }
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun pr_devel("%s:%d (%u:%u) reg_type %u, bus_addr %llxh, len %llxh\n",
1226*4882a593Smuzhiyun __func__, __LINE__, repo->bus_index, repo->dev_index,
1227*4882a593Smuzhiyun reg_type, bus_addr, len);
1228*4882a593Smuzhiyun }
1229*4882a593Smuzhiyun
1230*4882a593Smuzhiyun pr_devel(" <- %s:%d\n", __func__, __LINE__);
1231*4882a593Smuzhiyun return result;
1232*4882a593Smuzhiyun }
1233*4882a593Smuzhiyun
dump_stor_dev_info(struct ps3_repository_device * repo)1234*4882a593Smuzhiyun static int dump_stor_dev_info(struct ps3_repository_device *repo)
1235*4882a593Smuzhiyun {
1236*4882a593Smuzhiyun int result = 0;
1237*4882a593Smuzhiyun unsigned int num_regions, region_index;
1238*4882a593Smuzhiyun u64 port, blk_size, num_blocks;
1239*4882a593Smuzhiyun
1240*4882a593Smuzhiyun pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
1241*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_info(repo->bus_index,
1244*4882a593Smuzhiyun repo->dev_index, &port, &blk_size, &num_blocks, &num_regions);
1245*4882a593Smuzhiyun if (result) {
1246*4882a593Smuzhiyun pr_devel("%s:%d ps3_repository_read_stor_dev_info"
1247*4882a593Smuzhiyun " (%u:%u) failed\n", __func__, __LINE__,
1248*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1249*4882a593Smuzhiyun goto out;
1250*4882a593Smuzhiyun }
1251*4882a593Smuzhiyun
1252*4882a593Smuzhiyun pr_devel("%s:%d (%u:%u): port %llu, blk_size %llu, num_blocks "
1253*4882a593Smuzhiyun "%llu, num_regions %u\n",
1254*4882a593Smuzhiyun __func__, __LINE__, repo->bus_index, repo->dev_index,
1255*4882a593Smuzhiyun port, blk_size, num_blocks, num_regions);
1256*4882a593Smuzhiyun
1257*4882a593Smuzhiyun for (region_index = 0; region_index < num_regions; region_index++) {
1258*4882a593Smuzhiyun unsigned int region_id;
1259*4882a593Smuzhiyun u64 region_start, region_size;
1260*4882a593Smuzhiyun
1261*4882a593Smuzhiyun result = ps3_repository_read_stor_dev_region(repo->bus_index,
1262*4882a593Smuzhiyun repo->dev_index, region_index, ®ion_id,
1263*4882a593Smuzhiyun ®ion_start, ®ion_size);
1264*4882a593Smuzhiyun if (result) {
1265*4882a593Smuzhiyun pr_devel("%s:%d ps3_repository_read_stor_dev_region"
1266*4882a593Smuzhiyun " (%u:%u) failed\n", __func__, __LINE__,
1267*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1268*4882a593Smuzhiyun break;
1269*4882a593Smuzhiyun }
1270*4882a593Smuzhiyun
1271*4882a593Smuzhiyun pr_devel("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
1272*4882a593Smuzhiyun __func__, __LINE__, repo->bus_index, repo->dev_index,
1273*4882a593Smuzhiyun region_id, (unsigned long)region_start,
1274*4882a593Smuzhiyun (unsigned long)region_size);
1275*4882a593Smuzhiyun }
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun out:
1278*4882a593Smuzhiyun pr_devel(" <- %s:%d\n", __func__, __LINE__);
1279*4882a593Smuzhiyun return result;
1280*4882a593Smuzhiyun }
1281*4882a593Smuzhiyun
dump_device_info(struct ps3_repository_device * repo,unsigned int num_dev)1282*4882a593Smuzhiyun static int dump_device_info(struct ps3_repository_device *repo,
1283*4882a593Smuzhiyun unsigned int num_dev)
1284*4882a593Smuzhiyun {
1285*4882a593Smuzhiyun int result = 0;
1286*4882a593Smuzhiyun
1287*4882a593Smuzhiyun pr_devel(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);
1288*4882a593Smuzhiyun
1289*4882a593Smuzhiyun for (repo->dev_index = 0; repo->dev_index < num_dev;
1290*4882a593Smuzhiyun repo->dev_index++) {
1291*4882a593Smuzhiyun
1292*4882a593Smuzhiyun result = ps3_repository_read_dev_type(repo->bus_index,
1293*4882a593Smuzhiyun repo->dev_index, &repo->dev_type);
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun if (result) {
1296*4882a593Smuzhiyun pr_devel("%s:%d ps3_repository_read_dev_type"
1297*4882a593Smuzhiyun " (%u:%u) failed\n", __func__, __LINE__,
1298*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1299*4882a593Smuzhiyun break;
1300*4882a593Smuzhiyun }
1301*4882a593Smuzhiyun
1302*4882a593Smuzhiyun result = ps3_repository_read_dev_id(repo->bus_index,
1303*4882a593Smuzhiyun repo->dev_index, &repo->dev_id);
1304*4882a593Smuzhiyun
1305*4882a593Smuzhiyun if (result) {
1306*4882a593Smuzhiyun pr_devel("%s:%d ps3_repository_read_dev_id"
1307*4882a593Smuzhiyun " (%u:%u) failed\n", __func__, __LINE__,
1308*4882a593Smuzhiyun repo->bus_index, repo->dev_index);
1309*4882a593Smuzhiyun continue;
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun pr_devel("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__,
1313*4882a593Smuzhiyun __LINE__, repo->bus_index, repo->dev_index,
1314*4882a593Smuzhiyun repo->dev_type, (unsigned long)repo->dev_id);
1315*4882a593Smuzhiyun
1316*4882a593Smuzhiyun ps3_repository_dump_resource_info(repo);
1317*4882a593Smuzhiyun
1318*4882a593Smuzhiyun if (repo->bus_type == PS3_BUS_TYPE_STORAGE)
1319*4882a593Smuzhiyun dump_stor_dev_info(repo);
1320*4882a593Smuzhiyun }
1321*4882a593Smuzhiyun
1322*4882a593Smuzhiyun pr_devel(" <- %s:%d\n", __func__, __LINE__);
1323*4882a593Smuzhiyun return result;
1324*4882a593Smuzhiyun }
1325*4882a593Smuzhiyun
ps3_repository_dump_bus_info(void)1326*4882a593Smuzhiyun int ps3_repository_dump_bus_info(void)
1327*4882a593Smuzhiyun {
1328*4882a593Smuzhiyun int result = 0;
1329*4882a593Smuzhiyun struct ps3_repository_device repo;
1330*4882a593Smuzhiyun
1331*4882a593Smuzhiyun pr_devel(" -> %s:%d\n", __func__, __LINE__);
1332*4882a593Smuzhiyun
1333*4882a593Smuzhiyun memset(&repo, 0, sizeof(repo));
1334*4882a593Smuzhiyun
1335*4882a593Smuzhiyun for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
1336*4882a593Smuzhiyun unsigned int num_dev;
1337*4882a593Smuzhiyun
1338*4882a593Smuzhiyun result = ps3_repository_read_bus_type(repo.bus_index,
1339*4882a593Smuzhiyun &repo.bus_type);
1340*4882a593Smuzhiyun
1341*4882a593Smuzhiyun if (result) {
1342*4882a593Smuzhiyun pr_devel("%s:%d read_bus_type(%u) failed\n",
1343*4882a593Smuzhiyun __func__, __LINE__, repo.bus_index);
1344*4882a593Smuzhiyun break;
1345*4882a593Smuzhiyun }
1346*4882a593Smuzhiyun
1347*4882a593Smuzhiyun result = ps3_repository_read_bus_id(repo.bus_index,
1348*4882a593Smuzhiyun &repo.bus_id);
1349*4882a593Smuzhiyun
1350*4882a593Smuzhiyun if (result) {
1351*4882a593Smuzhiyun pr_devel("%s:%d read_bus_id(%u) failed\n",
1352*4882a593Smuzhiyun __func__, __LINE__, repo.bus_index);
1353*4882a593Smuzhiyun continue;
1354*4882a593Smuzhiyun }
1355*4882a593Smuzhiyun
1356*4882a593Smuzhiyun if (repo.bus_index != repo.bus_id)
1357*4882a593Smuzhiyun pr_devel("%s:%d bus_index != bus_id\n",
1358*4882a593Smuzhiyun __func__, __LINE__);
1359*4882a593Smuzhiyun
1360*4882a593Smuzhiyun result = ps3_repository_read_bus_num_dev(repo.bus_index,
1361*4882a593Smuzhiyun &num_dev);
1362*4882a593Smuzhiyun
1363*4882a593Smuzhiyun if (result) {
1364*4882a593Smuzhiyun pr_devel("%s:%d read_bus_num_dev(%u) failed\n",
1365*4882a593Smuzhiyun __func__, __LINE__, repo.bus_index);
1366*4882a593Smuzhiyun continue;
1367*4882a593Smuzhiyun }
1368*4882a593Smuzhiyun
1369*4882a593Smuzhiyun pr_devel("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
1370*4882a593Smuzhiyun __func__, __LINE__, repo.bus_index, repo.bus_type,
1371*4882a593Smuzhiyun (unsigned long)repo.bus_id, num_dev);
1372*4882a593Smuzhiyun
1373*4882a593Smuzhiyun dump_device_info(&repo, num_dev);
1374*4882a593Smuzhiyun }
1375*4882a593Smuzhiyun
1376*4882a593Smuzhiyun pr_devel(" <- %s:%d\n", __func__, __LINE__);
1377*4882a593Smuzhiyun return result;
1378*4882a593Smuzhiyun }
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun #endif /* defined(DEBUG) */
1381