Ticket #4385: devices.cpp

File devices.cpp, 4.7 KB (added by kallisti5, 15 years ago)
Line 
1/*
2 * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "Handle.h"
7#include "machine.h"
8
9#include <boot/platform.h>
10#include <boot/vfs.h>
11#include <boot/stdio.h>
12#include <boot/stage2.h>
13#include <boot/net/NetStack.h>
14#include <boot/net/RemoteDisk.h>
15#include <platform/openfirmware/devices.h>
16#include <platform/openfirmware/openfirmware.h>
17#include <util/kernel_cpp.h>
18
19#include <string.h>
20
21
22char sBootPath[192];
23
24
25status_t
26platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
27{
28 // print out the boot path (to be removed later?)
29
30 int length = of_getprop(gChosen, "bootpath", sBootPath, sizeof(sBootPath));
31 if (length <= 1)
32 return B_ENTRY_NOT_FOUND;
33 printf("boot path = \"%s\"\n", sBootPath);
34
35 int node = of_finddevice(sBootPath);
36 if (node != OF_FAILED) {
37 char type[16];
38 of_getprop(node, "device_type", type, sizeof(type));
39 printf("boot type = %s\n", type);
40
41 // If the boot device is a network device, we try to find a
42 // "remote disk" at this point.
43 if (strcmp(type, "network") == 0) {
44 // init the net stack
45 status_t error = net_stack_init();
46 if (error != B_OK)
47 return error;
48
49 // init a remote disk, if possible
50 RemoteDisk *remoteDisk = RemoteDisk::FindAnyRemoteDisk();
51 if (!remoteDisk)
52 return B_ENTRY_NOT_FOUND;
53
54 devicesList->Add(remoteDisk);
55 return B_OK;
56 }
57
58 if (strcmp("block", type) != 0) {
59 printf("boot device is not a block device!\n");
60 return B_ENTRY_NOT_FOUND;
61 }
62 } else
63 printf("could not open boot path.\n");
64
65/* char name[256];
66 strcpy(name, sBootPath);
67 strcat(name, ":kernel_ppc");
68 int kernel = of_open(name);
69 if (kernel == OF_FAILED) {
70 puts("open kernel failed");
71 } else
72 puts("open kernel succeeded");
73*/
74 int handle = of_open(sBootPath);
75 if (handle == OF_FAILED) {
76 puts("\t\t(open failed)");
77 return B_ERROR;
78 }
79
80 Handle *device = new(nothrow) Handle(handle);
81 if (device == NULL)
82 return B_NO_MEMORY;
83
84 devicesList->Add(device);
85 return B_OK;
86}
87
88
89status_t
90platform_get_boot_partition(struct stage2_args *args, Node *device,
91 NodeList *list, boot::Partition **_partition)
92{
93 NodeIterator iterator = list->GetIterator();
94 boot::Partition *partition = NULL;
95 while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
96 // ToDo: just take the first partition for now
97 *_partition = partition;
98 return B_OK;
99 }
100
101 return B_ENTRY_NOT_FOUND;
102}
103
104
105#define DUMPED_BLOCK_SIZE 16
106
107void
108dumpBlock(const char *buffer, int size, const char *prefix)
109{
110 int i;
111
112 for (i = 0; i < size;) {
113 int start = i;
114
115 printf(prefix);
116 for (; i < start+DUMPED_BLOCK_SIZE; i++) {
117 if (!(i % 4))
118 printf(" ");
119
120 if (i >= size)
121 printf(" ");
122 else
123 printf("%02x", *(unsigned char *)(buffer + i));
124 }
125 printf(" ");
126
127 for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
128 if (i < size) {
129 char c = buffer[i];
130
131 if (c < 30)
132 printf(".");
133 else
134 printf("%c", c);
135 } else
136 break;
137 }
138 printf("\n");
139 }
140}
141
142
143status_t
144platform_add_block_devices(stage2_args *args, NodeList *devicesList)
145{
146 // add all block devices to the list of possible boot devices
147
148 int cookie = 0;
149 char path[256];
150 status_t status;
151 while ((status = of_get_next_device(&cookie, 0, "block", path,
152 sizeof(path))) == B_OK) {
153 printf("new device!\n");
154 if (!strcmp(path, sBootPath)) {
155 printf("dont add boot device twice\n");
156 // don't add the boot device twice
157 continue;
158 }
159
160 // Adjust the arguments passed to the open command so that
161 // the disk-label package is by-passed - unfortunately,
162 // this is implementation specific (and I found no docs
163 // for the Apple OF disk-label usage, of course)
164
165 // SUN's OpenBoot:
166 //strcpy(path + strlen(path), ":nolabel");
167 // Apple:
168 if (gMachine & MACHINE_MAC)
169 strcpy(path + strlen(path), ":0");
170
171 printf("\t%s\n", path);
172
173 printf("calling of_path\n");
174 int handle = of_open(path);
175 printf("checking of_path results\n");
176 if (handle == OF_FAILED) {
177 puts("\t\t(failed)");
178 continue;
179 }
180
181 printf("adding device handle\n");
182 Handle *device = new(nothrow) Handle(handle);
183 printf("\t\t(could open device, handle = %p, node = %p)\n", (void *)handle, device);
184
185 printf("device handle created\n");
186 printf("adding device to devicesList\n");
187 devicesList->Add(device);
188 printf("device added to device list\n");
189 }
190 printf("\t(loop ended with %ld)\n", status);
191
192 return B_OK;
193}
194
195status_t
196platform_register_boot_device(Node *device)
197{
198 disk_identifier disk;
199
200 disk.bus_type = UNKNOWN_BUS;
201 disk.device_type = UNKNOWN_DEVICE;
202 disk.device.unknown.size = device->Size();
203
204 gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE,
205 &disk, sizeof(disk_identifier));
206
207 return B_OK;
208}
209