1 /*
2 * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <KernelExport.h>
8 #include <boot/platform.h>
9 #include <boot/partitions.h>
10 #include <boot/stdio.h>
11 #include <boot/stage2.h>
12
13 #include <string.h>
14
15 #include "Handle.h"
16 #include "rom_calls.h"
17
18 //#define TRACE_DEVICES
19 #ifdef TRACE_DEVICES
20 # define TRACE(x) dprintf x
21 #else
22 # define TRACE(x) ;
23 #endif
24
25
26 // exported from shell.S
27 extern uint8 gBootedFromImage;
28 extern uint8 gBootDriveAPI; // ATARI_BOOT_DRIVE_API_*
29 extern uint8 gBootDriveID;
30 extern uint32 gBootPartitionOffset;
31
32 #define SCRATCH_SIZE (2*4096)
33 static uint8 gScratchBuffer[SCRATCH_SIZE];
34
35
36 // #pragma mark -
37
38
ExecDevice(struct IORequest * ioRequest)39 ExecDevice::ExecDevice(struct IORequest *ioRequest)
40 {
41 fIORequest = ioRequest;
42 fIOStdReq = (struct IOStdReq *)ioRequest;
43 }
44
45
ExecDevice(size_t requestSize)46 ExecDevice::ExecDevice(size_t requestSize)
47 {
48 AllocRequest(requestSize);
49 }
50
51
ExecDevice()52 ExecDevice::ExecDevice()
53 {
54 fIORequest = NULL;
55 fIOStdReq = NULL;
56 }
57
58
~ExecDevice()59 ExecDevice::~ExecDevice()
60 {
61 CloseDevice(fIORequest);
62 DeleteIORequest(fIORequest);
63 }
64
65
66 status_t
AllocRequest(size_t requestSize)67 ExecDevice::AllocRequest(size_t requestSize)
68 {
69 struct MsgPort *inputPort = CreateMsgPort();
70 if (inputPort == NULL)
71 panic("CreateMsgPort()");
72
73 fIORequest = (struct IORequest *)CreateIORequest(inputPort, requestSize);
74 if (fIORequest == NULL)
75 panic("CreateIORequest()");
76 fIOStdReq = (struct IOStdReq *)fIORequest;
77 return B_OK;
78 }
79
80
81 status_t
Open(const char * name,unsigned long unit,unsigned long flags)82 ExecDevice::Open(const char *name, unsigned long unit, unsigned long flags)
83 {
84 status_t err = B_OK;
85
86 if (fIORequest == NULL)
87 err = AllocRequest(sizeof(struct IOStdReq));
88 if (err < B_OK)
89 return err;
90 err = exec_error(OpenDevice((uint8 *)name, unit, fIORequest, flags));
91 if (err < B_OK)
92 return err;
93 return B_OK;
94 }
95
96
97 ssize_t
ReadAt(void * cookie,off_t pos,void * buffer,size_t bufferSize)98 ExecDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
99 {
100 fIOStdReq->io_Command = CMD_READ;
101 fIOStdReq->io_Length = bufferSize;
102 fIOStdReq->io_Data = buffer;
103 fIOStdReq->io_Offset = (uint32)pos;
104 status_t err = Do();
105 if (err < B_OK)
106 return err;
107 return (ssize_t)fIOStdReq->io_Actual;
108 }
109
110
111 ssize_t
WriteAt(void * cookie,off_t pos,const void * buffer,size_t bufferSize)112 ExecDevice::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
113 {
114 fIOStdReq->io_Command = CMD_WRITE;
115 fIOStdReq->io_Length = bufferSize;
116 fIOStdReq->io_Data = (void *)buffer;
117 fIOStdReq->io_Offset = (uint32)pos;
118 status_t err = Do();
119 if (err < B_OK)
120 return err;
121 return (ssize_t)fIOStdReq->io_Actual;
122 }
123
124
125 off_t
Size() const126 ExecDevice::Size() const
127 {
128
129 // ToDo: fix this!
130 return 1024LL * 1024 * 1024 * 1024;
131 // 1024 GB
132 }
133
134
135 status_t
Do()136 ExecDevice::Do()
137 {
138 status_t err;
139 err = exec_error(DoIO(fIORequest));
140 return err;
141 }
142
143
144 status_t
Clear()145 ExecDevice::Clear()
146 {
147 fIOStdReq->io_Command = CMD_CLEAR;
148 status_t err = Do();
149 if (err < B_OK)
150 return err;
151 return B_OK;
152 }
153
154
155 // #pragma mark -
156
157
158 status_t
platform_add_boot_device(struct stage2_args * args,NodeList * devicesList)159 platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
160 {
161 TRACE(("boot drive ID: %x\n", gBootDriveID));
162
163 //TODO
164 gBootVolume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootedFromImage);
165
166 return B_OK;
167 }
168
169
170 status_t
platform_get_boot_partitions(struct stage2_args * args,Node * bootDevice,NodeList * list,NodeList * partitions)171 platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
172 NodeList *list, NodeList *partitions)
173 {
174
175 //TODO
176
177 return B_ENTRY_NOT_FOUND;
178 }
179
180
181 status_t
platform_add_block_devices(stage2_args * args,NodeList * devicesList)182 platform_add_block_devices(stage2_args *args, NodeList *devicesList)
183 {
184 //TODO
185 return B_ERROR;
186 }
187
188
189 status_t
platform_register_boot_device(Node * device)190 platform_register_boot_device(Node *device)
191 {
192 //TODO
193
194 return B_OK;
195 }
196
197
198 void
platform_cleanup_devices()199 platform_cleanup_devices()
200 {
201 }
202