Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / promif / common / prom_file.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: prom_file.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * Copyright (c) 2001-2003 Sun Microsystems, Inc.
46 * All rights reserved.
47 * Use is subject to license terms.
48 */
49
50#pragma ident "@(#)prom_file.c 1.1 01/04/19 SMI"
51
52#include <sys/promif.h>
53#include <sys/promimpl.h>
54
55#define BLOCKSIZE 0x1000
56
57typedef struct DEBLOCK_T {
58 long start;
59 long blocksize;
60 uchar_t buffer[BLOCKSIZE];
61} deblock_t;
62
63typedef struct FILE_T {
64 ihandle_t ihandle;
65 long size;
66 long currentpos;
67 deblock_t deblock;
68} FILE;
69
70#define _FILEDEFED
71#include <stdio.h>
72
73
74/*
75 * this counts on the fact that the standalone program was boot disked rather
76 * than boot netted. (ufs-file-system package is already loaded)
77 * By the way, isn't ufs-file-system redundant?
78 */
79
80void *
81loadfile(ihandle_t instance, uint32_t addr)
82{
83 cell_t ci[8];
84 int32_t retval;
85
86 ci[0] = p1275_ptr2cell("call-method"); /* Service name */
87 ci[1] = (cell_t)3; /* #argument cells */
88 ci[2] = (cell_t)2; /* #result cells */
89 ci[3] = p1275_ptr2cell("load"); /* Arg1: method name */
90 ci[4] = p1275_ihandle2cell(instance); /* Arg2:SA1:dev-node ihandle */
91 ci[5] = p1275_int2cell(addr); /* Arg3: SA2: load-addr */
92
93 retval = p1275_cif_handler(&ci);
94
95 if (retval != 0)
96 return ((void *)-1);
97 if (ci[6] != 0) /* Res1: Catch result */
98 return ((void *)-1);
99
100 return ((void *)ci[7]); /* Res2: virt addr */
101}
102
103long
104filesize(ihandle_t instance)
105{
106 cell_t ci[8];
107 int32_t retval;
108
109 ci[0] = p1275_ptr2cell("call-method"); /* Service name */
110 ci[1] = (cell_t)2; /* #argument cells */
111 ci[2] = (cell_t)3; /* #result cells */
112 ci[3] = p1275_ptr2cell("size"); /* Arg1: method name */
113 ci[4] = p1275_ihandle2cell(instance); /* Arg2:SA1:dev-node ihandle */
114
115 retval = p1275_cif_handler(&ci);
116
117 if (retval != 0)
118 return (-1);
119 if (ci[5] != 0) /* Res1: Catch result */
120 return (-1);
121 /* Res2: Don't care */
122
123 return ((long)ci[7]); /* Res3: file size */
124}
125
126long
127fileseek(ihandle_t instance, int32_t offset)
128{
129 /*
130 * Note that the order of the args passed in (after the ihandle)
131 * is being reversed so that when they are popped onto the forth
132 * stack they will be in the correct order for seeking
133 * ( offset whence -- error? )
134 */
135
136 cell_t ci[9];
137 int32_t retval;
138
139 ci[0] = p1275_ptr2cell("call-method"); /* Service name */
140 ci[1] = (cell_t)4; /* #argument cells */
141 ci[2] = (cell_t)2; /* #result cells */
142 ci[3] = p1275_ptr2cell("seek"); /* Arg1: method name */
143 ci[4] = p1275_ihandle2cell(instance); /* Arg2:SA1:dev-node ihandle */
144 ci[5] = p1275_int2cell(0); /* Arg3: SA3: whence */
145 ci[6] = p1275_int2cell(offset); /* Arg4: SA2: offset */
146
147 retval = p1275_cif_handler(&ci);
148
149 if (retval != 0)
150 return (-1);
151 if (ci[7] != 0) /* Res1: Catch result */
152 return (-1);
153
154 return (ci[8]); /* Res2: error? */
155}
156
157int32_t
158fileread(ihandle_t instance, uchar_t *addr, int32_t len)
159{
160 /*
161 * Note that the order of the args passed in (after the ihandle)
162 * is being reversed so that when they are popped onto the forth
163 * stack they will be in the correct order for reading
164 * ( addr len -- act-len )
165 */
166
167 cell_t ci[9];
168 int32_t retval;
169
170 ci[0] = p1275_ptr2cell("call-method"); /* Service name */
171 ci[1] = (cell_t)4; /* #argument cells */
172 ci[2] = (cell_t)2; /* #result cells */
173 ci[3] = p1275_ptr2cell("read"); /* Arg1: method name */
174 ci[4] = p1275_ihandle2cell(instance); /* Arg2:SA1:dev-node ihandle */
175 ci[5] = p1275_int2cell(len); /* Arg3: SA3: length */
176 ci[6] = p1275_int2cell(addr); /* Arg4: SA2: addr */
177
178 retval = p1275_cif_handler(&ci);
179
180 if (retval != 0)
181 return (-1);
182 if (ci[7] != 0) /* Res1: Catch result */
183 return (-1);
184
185 return (ci[8]); /* Res2: actual len */
186}
187
188/* it's always read/write */
189FILE *
190fopen(char const *filename, char const *mode)
191{
192 static FILE thisfile;
193 ihandle_t ihandle;
194
195 char ext_filename[100];
196 prom_strcpy(ext_filename, "disk:,");
197 filename = "|platform|platforms.di";
198 prom_strcat(ext_filename, (caddr_t)filename);
199
200 if ((ihandle = prom_open(ext_filename)) == NULL)
201 return (NULL);
202
203 prom_printf("thisfile %x\n", thisfile);
204 prom_printf("ihandle %x\n", ihandle);
205
206 thisfile.size = filesize(ihandle);
207 thisfile.currentpos = 0;
208 thisfile.ihandle = ihandle;
209 thisfile.deblock.start = -1; /* nothing read */
210
211 printf("filesize = %i\n", thisfile.size);
212
213 return (&thisfile);
214}
215
216int32_t
217fclose(FILE *stream)
218{
219 return (prom_close(stream->ihandle));
220}
221
222int32_t
223fseek(FILE *stream, long offset, int32_t whence)
224{
225 switch (whence) {
226 case SEEK_SET:
227 stream->currentpos = 0 + offset;
228 break;
229 case SEEK_CUR:
230 stream->currentpos += offset;
231 break;
232 case SEEK_END:
233 /* Unix allows going off the end of a stream! */
234 stream->currentpos = stream->size + offset;
235 break;
236 default:
237 return (-1);
238 }
239 return (fileseek(stream->ihandle, stream->currentpos));
240}
241
242long
243ftell(FILE *stream)
244{
245 return (stream->currentpos);
246}
247
248int32_t
249min(int32_t a, int32_t b)
250{
251 if (a < b)
252 return (a);
253 else
254 return (b);
255}
256
257
258int32_t
259fgetc(FILE *stream)
260{
261 /* I should buffer this */
262
263 long file_end = stream->size;
264 long position = stream->currentpos;
265 long size = min((stream->size - position), BLOCKSIZE);
266 uchar_t *buffer = stream->deblock.buffer;
267
268 if (position >= file_end)
269 return (EOF);
270
271 if ((position < stream->deblock.start) ||
272 (position >= stream->deblock.start + stream->deblock.blocksize) ||
273 (stream->deblock.start == -1)) {
274 stream->deblock.start = position;
275 stream->deblock.blocksize = size;
276 if ((fileread(stream->ihandle, buffer, size)) != size)
277 return (-1);
278 }
279
280 return ((int32_t)buffer[stream->currentpos++ - stream->deblock.start]);
281
282}