1 /* OpenFirmware-based filesystem
3 Copyright (C) 1999 Benjamin Herrenschmidt
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 BrokenFirmware cannot "read" from the network. We use tftp "load" method
20 for network boot for now, we may provide our own NFS implementation in
21 a later version. That means that we allocate a huge block of memory for
22 the entire file before loading it. We use the location where the kernel puts
23 RTAS, it's not used by the bootloader and if freed when the kernel is booted.
24 This will have to be changed if we plan to instanciate RTAS in the bootloader
36 #include "partition.h"
41 #define LOAD_BUFFER_POS 0x600000
42 #define LOAD_BUFFER_SIZE 0x400000
44 static int of_open(struct boot_file_t* file, const char* dev_name,
45 struct partition_t* part, const char* file_name);
46 static int of_read(struct boot_file_t* file, unsigned int size, void* buffer);
47 static int of_seek(struct boot_file_t* file, unsigned int newpos);
48 static int of_close(struct boot_file_t* file);
51 static int of_net_open(struct boot_file_t* file, const char* dev_name,
52 struct partition_t* part, const char* file_name);
53 static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer);
54 static int of_net_seek(struct boot_file_t* file, unsigned int newpos);
57 struct fs_t of_filesystem =
66 struct fs_t of_net_filesystem =
76 of_open(struct boot_file_t* file, const char* dev_name,
77 struct partition_t* part, const char* file_name)
79 static char buffer[1024];
86 strncpy(buffer, dev_name, 768);
90 sprintf(pn, "%02d", part->part_number);
93 if (file_name && strlen(file_name)) {
96 filename = strdup(file_name);
97 for (p = filename; *p; p++)
100 strcat(buffer, filename);
104 DEBUG_F("opening: \"%s\"\n", buffer);
106 file->of_device = prom_open(buffer);
108 DEBUG_F("file->of_device = %p\n", file->of_device);
112 if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
114 DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
115 return FILE_ERR_BAD_FSYS;
118 DEBUG_LEAVE(FILE_ERR_OK);
123 of_net_open(struct boot_file_t* file, const char* dev_name,
124 struct partition_t* part, const char* file_name)
126 static char buffer[1024];
133 strncpy(buffer, dev_name, 768);
134 if (file_name && strlen(file_name)) {
136 filename = strdup(file_name);
137 for (p = filename; *p; p++)
140 strcat(buffer, filename);
144 DEBUG_F("Opening: \"%s\"\n", buffer);
146 file->of_device = prom_open(buffer);
148 DEBUG_F("file->of_device = %p\n", file->of_device);
151 if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
153 DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
154 return FILE_ERR_BAD_FSYS;
157 file->buffer = prom_claim((void *)LOAD_BUFFER_POS, LOAD_BUFFER_SIZE, 0);
158 if (file->buffer == (void *)-1) {
159 prom_printf("Can't claim memory for TFTP download\n");
160 prom_close(file->of_device);
161 DEBUG_LEAVE(FILE_IOERR);
164 memset(file->buffer, 0, LOAD_BUFFER_SIZE);
168 file->len = prom_loadmethod(file->of_device, file->buffer);
170 DEBUG_F("result: %Ld\n", file->len);
172 DEBUG_LEAVE(FILE_ERR_OK);
177 of_read(struct boot_file_t* file, unsigned int size, void* buffer)
181 count = prom_read(file->of_device, buffer, size);
187 of_net_read(struct boot_file_t* file, unsigned int size, void* buffer)
189 unsigned int count, av;
191 av = file->len - file->pos;
192 count = size > av ? av : size;
193 memcpy(buffer, file->buffer + file->pos, count);
199 of_seek(struct boot_file_t* file, unsigned int newpos)
201 if (prom_seek(file->of_device, newpos)) {
206 return FILE_CANT_SEEK;
210 of_net_seek(struct boot_file_t* file, unsigned int newpos)
212 file->pos = (newpos > file->len) ? file->len : newpos;
217 of_close(struct boot_file_t* file)
221 DEBUG_F("<@%p>\n", file->of_device);
224 prom_release(file->buffer, LOAD_BUFFER_SIZE);
226 prom_close(file->of_device);
227 DEBUG_F("of_close called\n");
235 * c-file-style: "K&R"