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
27extern uint8 gBootedFromImage;
28extern uint8 gBootDriveAPI; // ATARI_BOOT_DRIVE_API_*
29extern uint8 gBootDriveID;
30extern uint32 gBootPartitionOffset;
31
32#define SCRATCH_SIZE (2*4096)
33static uint8 gScratchBuffer[SCRATCH_SIZE];
34
35
36//	#pragma mark -
37
38
39ExecDevice::ExecDevice(struct IORequest *ioRequest)
40{
41	fIORequest = ioRequest;
42	fIOStdReq = (struct IOStdReq *)ioRequest;
43}
44
45
46ExecDevice::ExecDevice(size_t requestSize)
47{
48	AllocRequest(requestSize);
49}
50
51
52ExecDevice::ExecDevice()
53{
54	fIORequest = NULL;
55	fIOStdReq = NULL;
56}
57
58
59ExecDevice::~ExecDevice()
60{
61	CloseDevice(fIORequest);
62	DeleteIORequest(fIORequest);
63}
64
65
66status_t
67ExecDevice::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
81status_t
82ExecDevice::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
97ssize_t
98ExecDevice::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
111ssize_t
112ExecDevice::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
125off_t
126ExecDevice::Size() const
127{
128
129	// ToDo: fix this!
130	return 1024LL * 1024 * 1024 * 1024;
131		// 1024 GB
132}
133
134
135status_t
136ExecDevice::Do()
137{
138	status_t err;
139	err = exec_error(DoIO(fIORequest));
140	return err;
141}
142
143
144status_t
145ExecDevice::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
158status_t
159platform_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
170status_t
171platform_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
181status_t
182platform_add_block_devices(stage2_args *args, NodeList *devicesList)
183{
184//TODO
185	return B_ERROR;
186}
187
188
189status_t
190platform_register_boot_device(Node *device)
191{
192//TODO
193
194	return B_OK;
195}
196
197
198void
199platform_cleanup_devices()
200{
201}
202