PageRenderTime 30ms CodeModel.GetById 10ms app.highlight 16ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/arm/boot/compressed/ofw-shark.c

https://bitbucket.org/evzijst/gittest
C | 260 lines | 194 code | 42 blank | 24 comment | 13 complexity | 0042574a306e9aea51d00796da5b6314 MD5 | raw file
  1/*
  2 * linux/arch/arm/boot/compressed/ofw-shark.c
  3 *
  4 * by Alexander Schulz
  5 *
  6 * This file is used to get some basic information
  7 * about the memory layout of the shark we are running
  8 * on. Memory is usually divided in blocks a 8 MB.
  9 * And bootargs are copied from OpenFirmware.
 10 */
 11
 12
 13#include <linux/kernel.h>
 14#include <linux/types.h>
 15#include <asm/setup.h>
 16#include <asm/page.h>
 17
 18
 19asmlinkage void
 20create_params (unsigned long *buffer)
 21{
 22	/* Is there a better address? Also change in mach-shark/core.c */
 23	struct tag *tag = (struct tag *) 0x08003000;
 24	int j,i,m,k,nr_banks,size;
 25	unsigned char *c;
 26
 27	k = 0;
 28
 29	/* Head of the taglist */
 30	tag->hdr.tag  = ATAG_CORE;
 31	tag->hdr.size = tag_size(tag_core);
 32	tag->u.core.flags = 1;
 33	tag->u.core.pagesize = PAGE_SIZE;
 34	tag->u.core.rootdev = 0;
 35
 36	/* Build up one tagged block for each memory region */
 37	size=0;
 38	nr_banks=(unsigned int) buffer[0];
 39	for (j=0;j<nr_banks;j++){
 40		/* search the lowest address and put it into the next entry   */
 41		/* not a fast sort algorithm, but there are at most 8 entries */
 42		/* and this is used only once anyway                          */
 43		m=0xffffffff;
 44		for (i=0;i<(unsigned int) buffer[0];i++){
 45			if (buffer[2*i+1]<m) {
 46				m=buffer[2*i+1];
 47				k=i;
 48			}
 49		}
 50	  
 51		tag = tag_next(tag);
 52		tag->hdr.tag = ATAG_MEM;
 53		tag->hdr.size = tag_size(tag_mem32);
 54		tag->u.mem.size = buffer[2*k+2];
 55		tag->u.mem.start = buffer[2*k+1];
 56
 57		size += buffer[2*k+2];
 58
 59		buffer[2*k+1]=0xffffffff;                    /* mark as copied */
 60	}
 61	
 62	/* The command line */
 63	tag = tag_next(tag);
 64	tag->hdr.tag = ATAG_CMDLINE;
 65	
 66	c=(unsigned char *)(&buffer[34]);
 67	j=0;
 68	while (*c) tag->u.cmdline.cmdline[j++]=*c++;
 69
 70	tag->u.cmdline.cmdline[j]=0;
 71	tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2;
 72
 73	/* Hardware revision */
 74	tag = tag_next(tag);
 75	tag->hdr.tag = ATAG_REVISION;
 76	tag->hdr.size = tag_size(tag_revision);
 77	tag->u.revision.rev = ((unsigned char) buffer[33])-'0';
 78
 79	/* End of the taglist */
 80	tag = tag_next(tag);
 81	tag->hdr.tag = 0;
 82	tag->hdr.size = 0;
 83}
 84
 85
 86typedef int (*ofw_handle_t)(void *);
 87
 88/* Everything below is called with a wrong MMU setting.
 89 * This means: no string constants, no initialization of
 90 * arrays, no global variables! This is ugly but I didn't
 91 * want to write this in assembler :-)
 92 */
 93
 94int
 95of_decode_int(const unsigned char *p)
 96{
 97	unsigned int i = *p++ << 8;
 98	i = (i + *p++) << 8;
 99	i = (i + *p++) << 8;
100	return (i + *p);
101}
102  
103int
104OF_finddevice(ofw_handle_t openfirmware, char *name)
105{
106	unsigned int args[8];
107	char service[12];
108
109	service[0]='f';
110	service[1]='i';
111	service[2]='n';
112	service[3]='d';
113	service[4]='d';
114	service[5]='e';
115	service[6]='v';
116	service[7]='i';
117	service[8]='c';
118	service[9]='e';
119	service[10]='\0';
120
121	args[0]=(unsigned int)service;
122	args[1]=1;
123	args[2]=1;
124	args[3]=(unsigned int)name;
125
126	if (openfirmware(args) == -1)
127		return -1;
128	return args[4];
129}
130
131int
132OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
133{
134	unsigned int args[8];
135	char service[12];
136
137	service[0]='g';
138	service[1]='e';
139	service[2]='t';
140	service[3]='p';
141	service[4]='r';
142	service[5]='o';
143	service[6]='p';
144	service[7]='l';
145	service[8]='e';
146	service[9]='n';
147	service[10]='\0';
148
149	args[0] = (unsigned int)service;
150	args[1] = 2;
151	args[2] = 1;
152	args[3] = (unsigned int)handle;
153	args[4] = (unsigned int)prop;
154
155	if (openfirmware(args) == -1)
156		return -1;
157	return args[5];
158}
159  
160int
161OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
162{
163	unsigned int args[8];
164	char service[8];
165
166	service[0]='g';
167	service[1]='e';
168	service[2]='t';
169	service[3]='p';
170	service[4]='r';
171	service[5]='o';
172	service[6]='p';
173	service[7]='\0';
174
175	args[0] = (unsigned int)service;
176	args[1] = 4;
177	args[2] = 1;
178	args[3] = (unsigned int)handle;
179	args[4] = (unsigned int)prop;
180	args[5] = (unsigned int)buf;
181	args[6] = buflen;
182
183	if (openfirmware(args) == -1)
184		return -1;
185	return args[7];
186}
187  
188asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
189{
190	int phandle,i,mem_len,buffer[32];
191	char temp[15];
192  
193	temp[0]='/';
194	temp[1]='m';
195	temp[2]='e';
196	temp[3]='m';
197	temp[4]='o';
198	temp[5]='r';
199	temp[6]='y';
200	temp[7]='\0';
201
202	phandle=OF_finddevice(o,temp);
203
204	temp[0]='r';
205	temp[1]='e';
206	temp[2]='g';
207	temp[3]='\0';
208
209	mem_len = OF_getproplen(o,phandle, temp);
210	OF_getprop(o,phandle, temp, buffer, mem_len);
211	*nomr=mem_len >> 3;
212
213	for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
214
215	temp[0]='/';
216	temp[1]='c';
217	temp[2]='h';
218	temp[3]='o';
219	temp[4]='s';
220	temp[5]='e';
221	temp[6]='n';
222	temp[7]='\0';
223
224	phandle=OF_finddevice(o,temp);
225
226	temp[0]='b';
227	temp[1]='o';
228	temp[2]='o';
229	temp[3]='t';
230	temp[4]='a';
231	temp[5]='r';
232	temp[6]='g';
233	temp[7]='s';
234	temp[8]='\0';
235
236	mem_len = OF_getproplen(o,phandle, temp);
237	OF_getprop(o,phandle, temp, buffer, mem_len);
238	if (mem_len > 128) mem_len=128;
239	for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i];
240	pointer[i+33]=0;
241
242	temp[0]='/';
243	temp[1]='\0';
244	phandle=OF_finddevice(o,temp);
245	temp[0]='b';
246	temp[1]='a';
247	temp[2]='n';
248	temp[3]='n';
249	temp[4]='e';
250	temp[5]='r';
251	temp[6]='-';
252	temp[7]='n';
253	temp[8]='a';
254	temp[9]='m';
255	temp[10]='e';
256	temp[11]='\0';
257	mem_len = OF_getproplen(o,phandle, temp);
258	OF_getprop(o,phandle, temp, buffer, mem_len);
259	(unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
260}