Ticket #4385: devices.cpp

File devices.cpp, 4.7 KB (added by kallisti5, 10 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