Convert line endings to LF
In r33670 the svn:eol-style property was dropped, which took care of locally converting the line endings to the user's native style. While most files use Unix-style LF line endings, some files have Windows-style CR LF line endings. Assure that the following r37262 directories use Unix-style line endings: src/system/boot/ src/system/boot/arch/ src/system/boot/arch/ppc/ src/system/boot/loader/ src/system/boot/loader/net/ src/system/boot/platform/ src/system/boot/platform/openfirmware/ src/system/boot/platform/openfirmware/arch/ src/system/boot/platform/openfirmware/arch/ppc/ src/system/kernel/ src/system/kernel/arch/ src/system/kernel/arch/ppc/ src/system/kernel/platform/ src/system/kernel/platform/openfirmware/ headers/private/kernel/ headers/private/kernel/arch/ headers/private/kernel/arch/ppc/ headers/private/kernel/platform/ headers/private/kernel/platform/openfirmware/ headers/private/kernel/boot/ headers/private/kernel/boot/net/ headers/private/kernel/boot/platform/ headers/private/kernel/boot/platform/openfirmware/ This avoids patches containing irrelevant lines unintentionally converted. No functional changes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37265 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5317b5f385
commit
04ec719a70
@ -1,79 +1,79 @@
|
||||
/*
|
||||
* Copyright 2008, François Revol <revol@free.fr>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _BOOT_FILE_MAP_DISK_H
|
||||
#define _BOOT_FILE_MAP_DISK_H
|
||||
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/partitions.h>
|
||||
|
||||
#define FMAP_FOLDER_NAME "BEOS"
|
||||
#define FMAP_IMAGE_NAME "IMAGE.BE"
|
||||
//#define FMAP_FOLDER_NAME "HAIKU"
|
||||
//#define FMAP_IMAGE_NAME "IMAGE.BFS"
|
||||
|
||||
#define FMAP_MAX_RUNS 128
|
||||
|
||||
struct file_map_run {
|
||||
off_t offset;
|
||||
off_t block;
|
||||
off_t len;
|
||||
};
|
||||
|
||||
struct file_map_boot_item {
|
||||
int32 block_size;
|
||||
int32 num_runs;
|
||||
struct file_map_run runs[FMAP_MAX_RUNS];
|
||||
};
|
||||
|
||||
#ifdef _BOOT_MODE
|
||||
|
||||
class FileMap {
|
||||
public:
|
||||
FileMap();
|
||||
~FileMap();
|
||||
void AddRun(off_t offset, off_t block, off_t len);
|
||||
|
||||
private:
|
||||
struct file_map_run fRuns[FMAP_MAX_RUNS];
|
||||
};
|
||||
|
||||
class FileMapDisk : public Node {
|
||||
public:
|
||||
FileMapDisk();
|
||||
virtual ~FileMapDisk();
|
||||
|
||||
status_t Init(Node *node/*Partition *partition, FileMap *map, off_t imageSize*/);
|
||||
|
||||
virtual status_t Open(void **_cookie, int mode);
|
||||
virtual status_t Close(void *cookie);
|
||||
|
||||
|
||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
||||
size_t bufferSize);
|
||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
||||
virtual status_t GetFileMap(struct file_map_run *runs, int32 *count);
|
||||
virtual off_t Size() const;
|
||||
|
||||
static FileMapDisk *FindAnyFileMapDisk(Directory *volume);
|
||||
|
||||
status_t RegisterFileMapBootItem();
|
||||
|
||||
private:
|
||||
Node *fNode;
|
||||
/*
|
||||
Partition *fPartition;
|
||||
FileMap *fMap;
|
||||
off_t fImageSize;
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
#endif // _BOOT_MODE
|
||||
|
||||
#endif // _BOOT_FILE_MAP_DISK_H
|
||||
/*
|
||||
* Copyright 2008, François Revol <revol@free.fr>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _BOOT_FILE_MAP_DISK_H
|
||||
#define _BOOT_FILE_MAP_DISK_H
|
||||
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/partitions.h>
|
||||
|
||||
#define FMAP_FOLDER_NAME "BEOS"
|
||||
#define FMAP_IMAGE_NAME "IMAGE.BE"
|
||||
//#define FMAP_FOLDER_NAME "HAIKU"
|
||||
//#define FMAP_IMAGE_NAME "IMAGE.BFS"
|
||||
|
||||
#define FMAP_MAX_RUNS 128
|
||||
|
||||
struct file_map_run {
|
||||
off_t offset;
|
||||
off_t block;
|
||||
off_t len;
|
||||
};
|
||||
|
||||
struct file_map_boot_item {
|
||||
int32 block_size;
|
||||
int32 num_runs;
|
||||
struct file_map_run runs[FMAP_MAX_RUNS];
|
||||
};
|
||||
|
||||
#ifdef _BOOT_MODE
|
||||
|
||||
class FileMap {
|
||||
public:
|
||||
FileMap();
|
||||
~FileMap();
|
||||
void AddRun(off_t offset, off_t block, off_t len);
|
||||
|
||||
private:
|
||||
struct file_map_run fRuns[FMAP_MAX_RUNS];
|
||||
};
|
||||
|
||||
class FileMapDisk : public Node {
|
||||
public:
|
||||
FileMapDisk();
|
||||
virtual ~FileMapDisk();
|
||||
|
||||
status_t Init(Node *node/*Partition *partition, FileMap *map, off_t imageSize*/);
|
||||
|
||||
virtual status_t Open(void **_cookie, int mode);
|
||||
virtual status_t Close(void *cookie);
|
||||
|
||||
|
||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
||||
size_t bufferSize);
|
||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
||||
virtual status_t GetFileMap(struct file_map_run *runs, int32 *count);
|
||||
virtual off_t Size() const;
|
||||
|
||||
static FileMapDisk *FindAnyFileMapDisk(Directory *volume);
|
||||
|
||||
status_t RegisterFileMapBootItem();
|
||||
|
||||
private:
|
||||
Node *fNode;
|
||||
/*
|
||||
Partition *fPartition;
|
||||
FileMap *fMap;
|
||||
off_t fImageSize;
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
#endif // _BOOT_MODE
|
||||
|
||||
#endif // _BOOT_FILE_MAP_DISK_H
|
||||
|
@ -1,28 +1,28 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef KERNEL_BOOT_ARCH_H
|
||||
#define KERNEL_BOOT_ARCH_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <boot/elf.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ELF support */
|
||||
|
||||
extern status_t boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
||||
struct Elf32_Rel *rel, int rel_len);
|
||||
extern status_t boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
||||
struct Elf32_Rela *rel, int rel_len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KERNEL_BOOT_ARCH_H */
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef KERNEL_BOOT_ARCH_H
|
||||
#define KERNEL_BOOT_ARCH_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <boot/elf.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ELF support */
|
||||
|
||||
extern status_t boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
||||
struct Elf32_Rel *rel, int rel_len);
|
||||
extern status_t boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
||||
struct Elf32_Rela *rel, int rel_len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KERNEL_BOOT_ARCH_H */
|
||||
|
@ -1,54 +1,54 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _BOOT_REMOTE_DISK_H
|
||||
#define _BOOT_REMOTE_DISK_H
|
||||
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/net/NetDefs.h>
|
||||
#include <boot/net/RemoteDiskDefs.h>
|
||||
|
||||
class UDPPacket;
|
||||
class UDPSocket;
|
||||
|
||||
class RemoteDisk : public Node {
|
||||
public:
|
||||
RemoteDisk();
|
||||
~RemoteDisk();
|
||||
|
||||
status_t Init(ip_addr_t serverAddress, uint16 serverPort, off_t imageSize);
|
||||
|
||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
||||
size_t bufferSize);
|
||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
||||
virtual off_t Size() const;
|
||||
|
||||
ip_addr_t ServerIPAddress() const;
|
||||
uint16 ServerPort() const;
|
||||
|
||||
static RemoteDisk *FindAnyRemoteDisk();
|
||||
|
||||
private:
|
||||
ssize_t _ReadFromPacket(off_t &pos, uint8 *&buffer, size_t &bufferSize);
|
||||
|
||||
static status_t _SendRequest(UDPSocket *socket, ip_addr_t serverAddress,
|
||||
uint16 serverPort, remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **packet);
|
||||
status_t _SendRequest(remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **packet);
|
||||
|
||||
private:
|
||||
ip_addr_t fServerAddress;
|
||||
uint16 fServerPort;
|
||||
off_t fImageSize;
|
||||
uint64 fRequestID;
|
||||
UDPSocket *fSocket;
|
||||
UDPPacket *fPacket;
|
||||
};
|
||||
|
||||
#endif // _BOOT_REMOTE_DISK_H
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _BOOT_REMOTE_DISK_H
|
||||
#define _BOOT_REMOTE_DISK_H
|
||||
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/net/NetDefs.h>
|
||||
#include <boot/net/RemoteDiskDefs.h>
|
||||
|
||||
class UDPPacket;
|
||||
class UDPSocket;
|
||||
|
||||
class RemoteDisk : public Node {
|
||||
public:
|
||||
RemoteDisk();
|
||||
~RemoteDisk();
|
||||
|
||||
status_t Init(ip_addr_t serverAddress, uint16 serverPort, off_t imageSize);
|
||||
|
||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
||||
size_t bufferSize);
|
||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
||||
virtual off_t Size() const;
|
||||
|
||||
ip_addr_t ServerIPAddress() const;
|
||||
uint16 ServerPort() const;
|
||||
|
||||
static RemoteDisk *FindAnyRemoteDisk();
|
||||
|
||||
private:
|
||||
ssize_t _ReadFromPacket(off_t &pos, uint8 *&buffer, size_t &bufferSize);
|
||||
|
||||
static status_t _SendRequest(UDPSocket *socket, ip_addr_t serverAddress,
|
||||
uint16 serverPort, remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **packet);
|
||||
status_t _SendRequest(remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **packet);
|
||||
|
||||
private:
|
||||
ip_addr_t fServerAddress;
|
||||
uint16 fServerPort;
|
||||
off_t fImageSize;
|
||||
uint64 fRequestID;
|
||||
UDPSocket *fSocket;
|
||||
UDPPacket *fPacket;
|
||||
};
|
||||
|
||||
#endif // _BOOT_REMOTE_DISK_H
|
||||
|
@ -1,64 +1,64 @@
|
||||
/*
|
||||
* Copyright 2005-2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _BOOT_REMOTE_DISK_DEFS_H
|
||||
#define _BOOT_REMOTE_DISK_DEFS_H
|
||||
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
enum {
|
||||
REMOTE_DISK_SERVER_PORT = 8765,
|
||||
REMOTE_DISK_BLOCK_SIZE = 1024,
|
||||
};
|
||||
|
||||
enum {
|
||||
// requests
|
||||
|
||||
REMOTE_DISK_HELLO_REQUEST = 0,
|
||||
// port: client port
|
||||
|
||||
REMOTE_DISK_READ_REQUEST = 1,
|
||||
// port: client port
|
||||
// offset: byte offset of data to read
|
||||
// size: number of bytes to read (server might serve more, though)
|
||||
|
||||
REMOTE_DISK_WRITE_REQUEST = 2,
|
||||
// port: client port
|
||||
// offset: byte offset of data to write
|
||||
// size: number of bytes to write
|
||||
// data: the data
|
||||
|
||||
// replies
|
||||
|
||||
REMOTE_DISK_HELLO_REPLY = 3,
|
||||
// offset: disk size
|
||||
|
||||
REMOTE_DISK_READ_REPLY = 4, // port unused
|
||||
// offset: byte offset of read data
|
||||
// size: number of bytes of data read; < 0 => error
|
||||
// data: read data
|
||||
|
||||
REMOTE_DISK_WRITE_REPLY = 5, // port, data unused
|
||||
// offset: byte offset of data written
|
||||
// size: number of bytes of data written; < 0 => error
|
||||
};
|
||||
|
||||
// errors
|
||||
enum {
|
||||
REMOTE_DISK_IO_ERROR = -1,
|
||||
REMOTE_DISK_BAD_REQUEST = -2,
|
||||
};
|
||||
|
||||
struct remote_disk_header {
|
||||
uint64_t offset;
|
||||
uint64_t request_id;
|
||||
int16_t size;
|
||||
uint16_t port;
|
||||
uint8_t command;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#endif // _BOOT_REMOTE_DISK_DEFS_H
|
||||
/*
|
||||
* Copyright 2005-2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _BOOT_REMOTE_DISK_DEFS_H
|
||||
#define _BOOT_REMOTE_DISK_DEFS_H
|
||||
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
enum {
|
||||
REMOTE_DISK_SERVER_PORT = 8765,
|
||||
REMOTE_DISK_BLOCK_SIZE = 1024,
|
||||
};
|
||||
|
||||
enum {
|
||||
// requests
|
||||
|
||||
REMOTE_DISK_HELLO_REQUEST = 0,
|
||||
// port: client port
|
||||
|
||||
REMOTE_DISK_READ_REQUEST = 1,
|
||||
// port: client port
|
||||
// offset: byte offset of data to read
|
||||
// size: number of bytes to read (server might serve more, though)
|
||||
|
||||
REMOTE_DISK_WRITE_REQUEST = 2,
|
||||
// port: client port
|
||||
// offset: byte offset of data to write
|
||||
// size: number of bytes to write
|
||||
// data: the data
|
||||
|
||||
// replies
|
||||
|
||||
REMOTE_DISK_HELLO_REPLY = 3,
|
||||
// offset: disk size
|
||||
|
||||
REMOTE_DISK_READ_REPLY = 4, // port unused
|
||||
// offset: byte offset of read data
|
||||
// size: number of bytes of data read; < 0 => error
|
||||
// data: read data
|
||||
|
||||
REMOTE_DISK_WRITE_REPLY = 5, // port, data unused
|
||||
// offset: byte offset of data written
|
||||
// size: number of bytes of data written; < 0 => error
|
||||
};
|
||||
|
||||
// errors
|
||||
enum {
|
||||
REMOTE_DISK_IO_ERROR = -1,
|
||||
REMOTE_DISK_BAD_REQUEST = -2,
|
||||
};
|
||||
|
||||
struct remote_disk_header {
|
||||
uint64_t offset;
|
||||
uint64_t request_id;
|
||||
int16_t size;
|
||||
uint16_t port;
|
||||
uint8_t command;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#endif // _BOOT_REMOTE_DISK_DEFS_H
|
||||
|
@ -1,22 +1,22 @@
|
||||
/*
|
||||
* Copyright 2005-2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL_OPEN_FIRMWARE_DEVICES_H
|
||||
#define _KERNEL_OPEN_FIRMWARE_DEVICES_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t of_get_next_device(int *_cookie, int root, const char *type,
|
||||
char *path, size_t pathSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL_OPEN_FIRMWARE_DEVICES_H */
|
||||
/*
|
||||
* Copyright 2005-2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL_OPEN_FIRMWARE_DEVICES_H
|
||||
#define _KERNEL_OPEN_FIRMWARE_DEVICES_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t of_get_next_device(int *_cookie, int root, const char *type,
|
||||
char *path, size_t pathSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL_OPEN_FIRMWARE_DEVICES_H */
|
||||
|
@ -1,189 +1,189 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <boot/FileMapDisk.h>
|
||||
#include <boot_item.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <OS.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
//#define TRACE_FILEMAPDISK
|
||||
#ifdef TRACE_FILEMAPDISK
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
// constructor
|
||||
FileMapDisk::FileMapDisk()
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
FileMapDisk::~FileMapDisk()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
status_t
|
||||
FileMapDisk::Init(Node *node/*, Partition *partition, FileMap *map, off_t imageSize*/)
|
||||
{
|
||||
TRACE(("FileMapDisk::FileMapDisk(%p)\n", node));
|
||||
fNode = node;
|
||||
/*
|
||||
fPartition = partition;
|
||||
fMap = map;
|
||||
fImageSize = imageSize;
|
||||
|
||||
// create and bind socket
|
||||
fSocket = new(nothrow) UDPSocket;
|
||||
if (!fSocket)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = fSocket->Bind(INADDR_ANY, 6666);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
*/
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::Open(void **_cookie, int mode)
|
||||
{
|
||||
TRACE(("FileMapDisk::Open(, 0x%08x)\n", mode));
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fNode->Open(_cookie, mode);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::Close(void *cookie)
|
||||
{
|
||||
TRACE(("FileMapDisk::Close(%p)\n", cookie));
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fNode->Close(cookie);
|
||||
}
|
||||
|
||||
|
||||
// ReadAt
|
||||
ssize_t
|
||||
FileMapDisk::ReadAt(void *cookie, off_t pos, void *_buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
TRACE(("FileMapDisk::ReadAt(%p, %lld, , %ld)\n", cookie, pos, bufferSize));
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fNode->ReadAt(cookie, pos, _buffer, bufferSize);
|
||||
}
|
||||
|
||||
|
||||
// WriteAt
|
||||
ssize_t
|
||||
FileMapDisk::WriteAt(void */*cookie*/, off_t pos, const void *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
// Not needed in the boot loader.
|
||||
return B_PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
// GetName
|
||||
status_t
|
||||
FileMapDisk::GetName(char *nameBuffer, size_t bufferSize) const
|
||||
{
|
||||
const char *prefix = "FileMapDisk:";
|
||||
if (!nameBuffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
snprintf(nameBuffer, bufferSize, prefix);
|
||||
if (bufferSize > strlen(prefix) && fNode)
|
||||
return fNode->GetName(nameBuffer + strlen(prefix),
|
||||
bufferSize - strlen(prefix));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::GetFileMap(struct file_map_run *runs, int32 *count)
|
||||
{
|
||||
return fNode->GetFileMap(runs, count);
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
FileMapDisk::Size() const
|
||||
{
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
return fNode->Size();
|
||||
}
|
||||
|
||||
|
||||
FileMapDisk *
|
||||
FileMapDisk::FindAnyFileMapDisk(Directory *volume)
|
||||
{
|
||||
TRACE(("FileMapDisk::FindAnyFileMapDisk(%p)\n", volume));
|
||||
Node *node;
|
||||
status_t error;
|
||||
|
||||
if (!volume)
|
||||
return NULL;
|
||||
|
||||
//XXX: check lower/mixed case as well
|
||||
Node *dirnode;
|
||||
Directory *dir;
|
||||
dirnode = volume->Lookup(FMAP_FOLDER_NAME, true);
|
||||
if (!dirnode || !S_ISDIR(dirnode->Type()))
|
||||
return NULL;
|
||||
dir = (Directory *)dirnode;
|
||||
node = dir->Lookup(FMAP_IMAGE_NAME, true);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
// create a FileMapDisk object
|
||||
FileMapDisk *disk = new(nothrow) FileMapDisk;
|
||||
if (disk) {
|
||||
error = disk->Init(node);
|
||||
if (error != B_OK) {
|
||||
delete disk;
|
||||
disk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return disk;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::RegisterFileMapBootItem()
|
||||
{
|
||||
return B_ERROR;
|
||||
struct file_map_boot_item *item;
|
||||
item = (struct file_map_boot_item *)malloc(sizeof(struct file_map_boot_item));
|
||||
item->num_runs = FMAP_MAX_RUNS;
|
||||
status_t err;
|
||||
err = GetFileMap(item->runs, &item->num_runs);
|
||||
if (err < B_OK)
|
||||
return err;
|
||||
// err = add_boot_item("file_map_disk", item, sizeof(struct file_map_boot_item));
|
||||
err = B_ERROR;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <boot/FileMapDisk.h>
|
||||
#include <boot_item.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <OS.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
//#define TRACE_FILEMAPDISK
|
||||
#ifdef TRACE_FILEMAPDISK
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
// constructor
|
||||
FileMapDisk::FileMapDisk()
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
FileMapDisk::~FileMapDisk()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
status_t
|
||||
FileMapDisk::Init(Node *node/*, Partition *partition, FileMap *map, off_t imageSize*/)
|
||||
{
|
||||
TRACE(("FileMapDisk::FileMapDisk(%p)\n", node));
|
||||
fNode = node;
|
||||
/*
|
||||
fPartition = partition;
|
||||
fMap = map;
|
||||
fImageSize = imageSize;
|
||||
|
||||
// create and bind socket
|
||||
fSocket = new(nothrow) UDPSocket;
|
||||
if (!fSocket)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = fSocket->Bind(INADDR_ANY, 6666);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
*/
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::Open(void **_cookie, int mode)
|
||||
{
|
||||
TRACE(("FileMapDisk::Open(, 0x%08x)\n", mode));
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fNode->Open(_cookie, mode);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::Close(void *cookie)
|
||||
{
|
||||
TRACE(("FileMapDisk::Close(%p)\n", cookie));
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fNode->Close(cookie);
|
||||
}
|
||||
|
||||
|
||||
// ReadAt
|
||||
ssize_t
|
||||
FileMapDisk::ReadAt(void *cookie, off_t pos, void *_buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
TRACE(("FileMapDisk::ReadAt(%p, %lld, , %ld)\n", cookie, pos, bufferSize));
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fNode->ReadAt(cookie, pos, _buffer, bufferSize);
|
||||
}
|
||||
|
||||
|
||||
// WriteAt
|
||||
ssize_t
|
||||
FileMapDisk::WriteAt(void */*cookie*/, off_t pos, const void *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
// Not needed in the boot loader.
|
||||
return B_PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
// GetName
|
||||
status_t
|
||||
FileMapDisk::GetName(char *nameBuffer, size_t bufferSize) const
|
||||
{
|
||||
const char *prefix = "FileMapDisk:";
|
||||
if (!nameBuffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
snprintf(nameBuffer, bufferSize, prefix);
|
||||
if (bufferSize > strlen(prefix) && fNode)
|
||||
return fNode->GetName(nameBuffer + strlen(prefix),
|
||||
bufferSize - strlen(prefix));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::GetFileMap(struct file_map_run *runs, int32 *count)
|
||||
{
|
||||
return fNode->GetFileMap(runs, count);
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
FileMapDisk::Size() const
|
||||
{
|
||||
if (!fNode)
|
||||
return B_NO_INIT;
|
||||
return fNode->Size();
|
||||
}
|
||||
|
||||
|
||||
FileMapDisk *
|
||||
FileMapDisk::FindAnyFileMapDisk(Directory *volume)
|
||||
{
|
||||
TRACE(("FileMapDisk::FindAnyFileMapDisk(%p)\n", volume));
|
||||
Node *node;
|
||||
status_t error;
|
||||
|
||||
if (!volume)
|
||||
return NULL;
|
||||
|
||||
//XXX: check lower/mixed case as well
|
||||
Node *dirnode;
|
||||
Directory *dir;
|
||||
dirnode = volume->Lookup(FMAP_FOLDER_NAME, true);
|
||||
if (!dirnode || !S_ISDIR(dirnode->Type()))
|
||||
return NULL;
|
||||
dir = (Directory *)dirnode;
|
||||
node = dir->Lookup(FMAP_IMAGE_NAME, true);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
// create a FileMapDisk object
|
||||
FileMapDisk *disk = new(nothrow) FileMapDisk;
|
||||
if (disk) {
|
||||
error = disk->Init(node);
|
||||
if (error != B_OK) {
|
||||
delete disk;
|
||||
disk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return disk;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileMapDisk::RegisterFileMapBootItem()
|
||||
{
|
||||
return B_ERROR;
|
||||
struct file_map_boot_item *item;
|
||||
item = (struct file_map_boot_item *)malloc(sizeof(struct file_map_boot_item));
|
||||
item->num_runs = FMAP_MAX_RUNS;
|
||||
status_t err;
|
||||
err = GetFileMap(item->runs, &item->num_runs);
|
||||
if (err < B_OK)
|
||||
return err;
|
||||
// err = add_boot_item("file_map_disk", item, sizeof(struct file_map_boot_item));
|
||||
err = B_ERROR;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,313 +1,313 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <boot/net/RemoteDisk.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <OS.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <boot/net/UDP.h>
|
||||
|
||||
|
||||
static const bigtime_t kRequestTimeout = 100000LL;
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
|
||||
static inline
|
||||
uint64_t swap_uint64(uint64_t data)
|
||||
{
|
||||
return ((data & 0xff) << 56)
|
||||
| ((data & 0xff00) << 40)
|
||||
| ((data & 0xff0000) << 24)
|
||||
| ((data & 0xff000000) << 8)
|
||||
| ((data >> 8) & 0xff000000)
|
||||
| ((data >> 24) & 0xff0000)
|
||||
| ((data >> 40) & 0xff00)
|
||||
| ((data >> 56) & 0xff);
|
||||
}
|
||||
|
||||
#define host_to_net64(data) swap_uint64(data)
|
||||
#define net_to_host64(data) swap_uint64(data)
|
||||
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define host_to_net64(data) (data)
|
||||
#define net_to_host64(data) (data)
|
||||
#endif
|
||||
|
||||
#undef htonll
|
||||
#undef ntohll
|
||||
#define htonll(data) host_to_net64(data)
|
||||
#define ntohll(data) net_to_host64(data)
|
||||
|
||||
|
||||
// constructor
|
||||
RemoteDisk::RemoteDisk()
|
||||
: fServerAddress(INADDR_ANY),
|
||||
fServerPort(0),
|
||||
fImageSize(0),
|
||||
fRequestID(0),
|
||||
fSocket(NULL),
|
||||
fPacket(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
RemoteDisk::~RemoteDisk()
|
||||
{
|
||||
delete fSocket;
|
||||
delete fPacket;
|
||||
}
|
||||
|
||||
// Init
|
||||
status_t
|
||||
RemoteDisk::Init(ip_addr_t serverAddress, uint16 serverPort, off_t imageSize)
|
||||
{
|
||||
fServerAddress = serverAddress;
|
||||
fServerPort = serverPort;
|
||||
fImageSize = imageSize;
|
||||
|
||||
// create and bind socket
|
||||
fSocket = new(nothrow) UDPSocket;
|
||||
if (!fSocket)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = fSocket->Bind(INADDR_ANY, 6666);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// ReadAt
|
||||
ssize_t
|
||||
RemoteDisk::ReadAt(void */*cookie*/, off_t pos, void *_buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
if (!fSocket)
|
||||
return B_NO_INIT;
|
||||
|
||||
uint8 *buffer = (uint8*)_buffer;
|
||||
if (!buffer || pos < 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (bufferSize == 0)
|
||||
return 0;
|
||||
|
||||
// Check whether the current packet already contains the beginning of the
|
||||
// data to read.
|
||||
ssize_t bytesRead = _ReadFromPacket(pos, buffer, bufferSize);
|
||||
|
||||
// If there still remains something to be read, we need to get it from the
|
||||
// server.
|
||||
status_t error = B_OK;
|
||||
while (bufferSize > 0) {
|
||||
// prepare request
|
||||
remote_disk_header request;
|
||||
request.offset = htonll(pos);
|
||||
uint32 toRead = min_c(bufferSize, REMOTE_DISK_BLOCK_SIZE);
|
||||
request.size = htons(toRead);
|
||||
request.command = REMOTE_DISK_READ_REQUEST;
|
||||
|
||||
// send request
|
||||
UDPPacket *packet;
|
||||
error = _SendRequest(&request, sizeof(request), REMOTE_DISK_READ_REPLY,
|
||||
&packet);
|
||||
if (error != B_OK)
|
||||
break;
|
||||
|
||||
// check for errors
|
||||
int16 packetSize = ntohs(((remote_disk_header*)packet->Data())->size);
|
||||
if (packetSize < 0) {
|
||||
if (packetSize == REMOTE_DISK_IO_ERROR)
|
||||
error = B_IO_ERROR;
|
||||
else if (packetSize == REMOTE_DISK_BAD_REQUEST)
|
||||
error = B_BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// make the reply packet the current packet
|
||||
delete fPacket;
|
||||
fPacket = packet;
|
||||
|
||||
// read from the packet
|
||||
size_t packetBytesRead = _ReadFromPacket(pos, buffer, bufferSize);
|
||||
if (packetBytesRead == 0)
|
||||
break;
|
||||
bytesRead += packetBytesRead;
|
||||
}
|
||||
|
||||
// only return an error, when we were not able to read anything at all
|
||||
return (bytesRead == 0 ? error : bytesRead);
|
||||
}
|
||||
|
||||
// WriteAt
|
||||
ssize_t
|
||||
RemoteDisk::WriteAt(void */*cookie*/, off_t pos, const void *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
// Not needed in the boot loader.
|
||||
return B_PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
// GetName
|
||||
status_t
|
||||
RemoteDisk::GetName(char *nameBuffer, size_t bufferSize) const
|
||||
{
|
||||
if (!nameBuffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
snprintf(nameBuffer, bufferSize, "RemoteDisk:%ld.%ld.%ld.%ld:%hd",
|
||||
(fServerAddress >> 24) & 0xff, (fServerAddress >> 16) & 0xff,
|
||||
(fServerAddress >> 8) & 0xff, fServerAddress & 0xff, fServerPort);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Size
|
||||
off_t
|
||||
RemoteDisk::Size() const
|
||||
{
|
||||
return fImageSize;
|
||||
}
|
||||
|
||||
ip_addr_t
|
||||
RemoteDisk::ServerIPAddress() const
|
||||
{
|
||||
return fServerAddress;
|
||||
}
|
||||
|
||||
uint16
|
||||
RemoteDisk::ServerPort() const
|
||||
{
|
||||
return fServerPort;
|
||||
}
|
||||
|
||||
// FindAnyRemoteDisk
|
||||
RemoteDisk *
|
||||
RemoteDisk::FindAnyRemoteDisk()
|
||||
{
|
||||
// create a socket and bind it
|
||||
UDPSocket socket;
|
||||
status_t error = socket.Bind(INADDR_ANY, 6665);
|
||||
if (error != B_OK) {
|
||||
printf("RemoteDisk::GetAnyRemoteDisk(): Failed to bind socket.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// prepare request
|
||||
remote_disk_header request;
|
||||
request.command = REMOTE_DISK_HELLO_REQUEST;
|
||||
|
||||
// send request
|
||||
UDPPacket *packet;
|
||||
error = _SendRequest(&socket, INADDR_BROADCAST, REMOTE_DISK_SERVER_PORT,
|
||||
&request, sizeof(request), REMOTE_DISK_HELLO_REPLY, &packet);
|
||||
if (error != B_OK) {
|
||||
printf("RemoteDisk::GetAnyRemoteDisk(): Got no server reply.\n");
|
||||
return NULL;
|
||||
}
|
||||
remote_disk_header *reply = (remote_disk_header*)packet->Data();
|
||||
|
||||
// create a RemoteDisk object
|
||||
RemoteDisk *remoteDisk = new(nothrow) RemoteDisk;
|
||||
if (remoteDisk) {
|
||||
error = remoteDisk->Init(packet->SourceAddress(), ntohs(reply->port),
|
||||
ntohll(reply->offset));
|
||||
if (error != B_OK) {
|
||||
delete remoteDisk;
|
||||
remoteDisk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
delete packet;
|
||||
|
||||
return remoteDisk;
|
||||
}
|
||||
|
||||
// _ReadFromPacket
|
||||
ssize_t
|
||||
RemoteDisk::_ReadFromPacket(off_t &pos, uint8 *&buffer, size_t &bufferSize)
|
||||
{
|
||||
if (!fPacket)
|
||||
return 0;
|
||||
|
||||
remote_disk_header *header = (remote_disk_header*)fPacket->Data();
|
||||
uint64 packetOffset = ntohll(header->offset);
|
||||
uint32 packetSize = ntohs(header->size);
|
||||
if (packetOffset > (uint64)pos || packetOffset + packetSize <= (uint64)pos)
|
||||
return 0;
|
||||
|
||||
// we do indeed have some bytes already
|
||||
size_t toCopy = size_t(packetOffset + packetSize - (uint64)pos);
|
||||
if (toCopy > bufferSize)
|
||||
toCopy = bufferSize;
|
||||
memcpy(buffer, header->data + (pos - packetOffset), toCopy);
|
||||
|
||||
pos += toCopy;
|
||||
buffer += toCopy;
|
||||
bufferSize -= toCopy;
|
||||
return toCopy;
|
||||
}
|
||||
|
||||
// _SendRequest
|
||||
status_t
|
||||
RemoteDisk::_SendRequest(UDPSocket *socket, ip_addr_t serverAddress,
|
||||
uint16 serverPort, remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **_packet)
|
||||
{
|
||||
request->port = htons(socket->Port());
|
||||
|
||||
// try sending the request 3 times at most
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// send request
|
||||
status_t error = socket->Send(serverAddress, serverPort, request, size);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// receive reply
|
||||
bigtime_t timeout = system_time() + kRequestTimeout;
|
||||
do {
|
||||
UDPPacket *packet;
|
||||
error = socket->Receive(&packet, timeout - system_time());
|
||||
if (error == B_OK) {
|
||||
// got something; check, if it is looks good
|
||||
if (packet->DataSize() >= sizeof(remote_disk_header)) {
|
||||
remote_disk_header *reply
|
||||
= (remote_disk_header*)packet->Data();
|
||||
if (reply->request_id == request->request_id
|
||||
&& reply->command == expectedReply) {
|
||||
*_packet = packet;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// reply not OK
|
||||
delete packet;
|
||||
} else if (error != B_TIMED_OUT && error != B_WOULD_BLOCK)
|
||||
return error;
|
||||
|
||||
} while (timeout > system_time());
|
||||
}
|
||||
|
||||
// no reply
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// _SendRequest
|
||||
status_t
|
||||
RemoteDisk::_SendRequest(remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **packet)
|
||||
{
|
||||
request->request_id = fRequestID++;
|
||||
return _SendRequest(fSocket, fServerAddress, fServerPort, request, size,
|
||||
expectedReply, packet);
|
||||
}
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <boot/net/RemoteDisk.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <OS.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <boot/net/UDP.h>
|
||||
|
||||
|
||||
static const bigtime_t kRequestTimeout = 100000LL;
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
|
||||
static inline
|
||||
uint64_t swap_uint64(uint64_t data)
|
||||
{
|
||||
return ((data & 0xff) << 56)
|
||||
| ((data & 0xff00) << 40)
|
||||
| ((data & 0xff0000) << 24)
|
||||
| ((data & 0xff000000) << 8)
|
||||
| ((data >> 8) & 0xff000000)
|
||||
| ((data >> 24) & 0xff0000)
|
||||
| ((data >> 40) & 0xff00)
|
||||
| ((data >> 56) & 0xff);
|
||||
}
|
||||
|
||||
#define host_to_net64(data) swap_uint64(data)
|
||||
#define net_to_host64(data) swap_uint64(data)
|
||||
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define host_to_net64(data) (data)
|
||||
#define net_to_host64(data) (data)
|
||||
#endif
|
||||
|
||||
#undef htonll
|
||||
#undef ntohll
|
||||
#define htonll(data) host_to_net64(data)
|
||||
#define ntohll(data) net_to_host64(data)
|
||||
|
||||
|
||||
// constructor
|
||||
RemoteDisk::RemoteDisk()
|
||||
: fServerAddress(INADDR_ANY),
|
||||
fServerPort(0),
|
||||
fImageSize(0),
|
||||
fRequestID(0),
|
||||
fSocket(NULL),
|
||||
fPacket(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
RemoteDisk::~RemoteDisk()
|
||||
{
|
||||
delete fSocket;
|
||||
delete fPacket;
|
||||
}
|
||||
|
||||
// Init
|
||||
status_t
|
||||
RemoteDisk::Init(ip_addr_t serverAddress, uint16 serverPort, off_t imageSize)
|
||||
{
|
||||
fServerAddress = serverAddress;
|
||||
fServerPort = serverPort;
|
||||
fImageSize = imageSize;
|
||||
|
||||
// create and bind socket
|
||||
fSocket = new(nothrow) UDPSocket;
|
||||
if (!fSocket)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = fSocket->Bind(INADDR_ANY, 6666);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// ReadAt
|
||||
ssize_t
|
||||
RemoteDisk::ReadAt(void */*cookie*/, off_t pos, void *_buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
if (!fSocket)
|
||||
return B_NO_INIT;
|
||||
|
||||
uint8 *buffer = (uint8*)_buffer;
|
||||
if (!buffer || pos < 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (bufferSize == 0)
|
||||
return 0;
|
||||
|
||||
// Check whether the current packet already contains the beginning of the
|
||||
// data to read.
|
||||
ssize_t bytesRead = _ReadFromPacket(pos, buffer, bufferSize);
|
||||
|
||||
// If there still remains something to be read, we need to get it from the
|
||||
// server.
|
||||
status_t error = B_OK;
|
||||
while (bufferSize > 0) {
|
||||
// prepare request
|
||||
remote_disk_header request;
|
||||
request.offset = htonll(pos);
|
||||
uint32 toRead = min_c(bufferSize, REMOTE_DISK_BLOCK_SIZE);
|
||||
request.size = htons(toRead);
|
||||
request.command = REMOTE_DISK_READ_REQUEST;
|
||||
|
||||
// send request
|
||||
UDPPacket *packet;
|
||||
error = _SendRequest(&request, sizeof(request), REMOTE_DISK_READ_REPLY,
|
||||
&packet);
|
||||
if (error != B_OK)
|
||||
break;
|
||||
|
||||
// check for errors
|
||||
int16 packetSize = ntohs(((remote_disk_header*)packet->Data())->size);
|
||||
if (packetSize < 0) {
|
||||
if (packetSize == REMOTE_DISK_IO_ERROR)
|
||||
error = B_IO_ERROR;
|
||||
else if (packetSize == REMOTE_DISK_BAD_REQUEST)
|
||||
error = B_BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// make the reply packet the current packet
|
||||
delete fPacket;
|
||||
fPacket = packet;
|
||||
|
||||
// read from the packet
|
||||
size_t packetBytesRead = _ReadFromPacket(pos, buffer, bufferSize);
|
||||
if (packetBytesRead == 0)
|
||||
break;
|
||||
bytesRead += packetBytesRead;
|
||||
}
|
||||
|
||||
// only return an error, when we were not able to read anything at all
|
||||
return (bytesRead == 0 ? error : bytesRead);
|
||||
}
|
||||
|
||||
// WriteAt
|
||||
ssize_t
|
||||
RemoteDisk::WriteAt(void */*cookie*/, off_t pos, const void *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
// Not needed in the boot loader.
|
||||
return B_PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
// GetName
|
||||
status_t
|
||||
RemoteDisk::GetName(char *nameBuffer, size_t bufferSize) const
|
||||
{
|
||||
if (!nameBuffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
snprintf(nameBuffer, bufferSize, "RemoteDisk:%ld.%ld.%ld.%ld:%hd",
|
||||
(fServerAddress >> 24) & 0xff, (fServerAddress >> 16) & 0xff,
|
||||
(fServerAddress >> 8) & 0xff, fServerAddress & 0xff, fServerPort);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Size
|
||||
off_t
|
||||
RemoteDisk::Size() const
|
||||
{
|
||||
return fImageSize;
|
||||
}
|
||||
|
||||
ip_addr_t
|
||||
RemoteDisk::ServerIPAddress() const
|
||||
{
|
||||
return fServerAddress;
|
||||
}
|
||||
|
||||
uint16
|
||||
RemoteDisk::ServerPort() const
|
||||
{
|
||||
return fServerPort;
|
||||
}
|
||||
|
||||
// FindAnyRemoteDisk
|
||||
RemoteDisk *
|
||||
RemoteDisk::FindAnyRemoteDisk()
|
||||
{
|
||||
// create a socket and bind it
|
||||
UDPSocket socket;
|
||||
status_t error = socket.Bind(INADDR_ANY, 6665);
|
||||
if (error != B_OK) {
|
||||
printf("RemoteDisk::GetAnyRemoteDisk(): Failed to bind socket.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// prepare request
|
||||
remote_disk_header request;
|
||||
request.command = REMOTE_DISK_HELLO_REQUEST;
|
||||
|
||||
// send request
|
||||
UDPPacket *packet;
|
||||
error = _SendRequest(&socket, INADDR_BROADCAST, REMOTE_DISK_SERVER_PORT,
|
||||
&request, sizeof(request), REMOTE_DISK_HELLO_REPLY, &packet);
|
||||
if (error != B_OK) {
|
||||
printf("RemoteDisk::GetAnyRemoteDisk(): Got no server reply.\n");
|
||||
return NULL;
|
||||
}
|
||||
remote_disk_header *reply = (remote_disk_header*)packet->Data();
|
||||
|
||||
// create a RemoteDisk object
|
||||
RemoteDisk *remoteDisk = new(nothrow) RemoteDisk;
|
||||
if (remoteDisk) {
|
||||
error = remoteDisk->Init(packet->SourceAddress(), ntohs(reply->port),
|
||||
ntohll(reply->offset));
|
||||
if (error != B_OK) {
|
||||
delete remoteDisk;
|
||||
remoteDisk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
delete packet;
|
||||
|
||||
return remoteDisk;
|
||||
}
|
||||
|
||||
// _ReadFromPacket
|
||||
ssize_t
|
||||
RemoteDisk::_ReadFromPacket(off_t &pos, uint8 *&buffer, size_t &bufferSize)
|
||||
{
|
||||
if (!fPacket)
|
||||
return 0;
|
||||
|
||||
remote_disk_header *header = (remote_disk_header*)fPacket->Data();
|
||||
uint64 packetOffset = ntohll(header->offset);
|
||||
uint32 packetSize = ntohs(header->size);
|
||||
if (packetOffset > (uint64)pos || packetOffset + packetSize <= (uint64)pos)
|
||||
return 0;
|
||||
|
||||
// we do indeed have some bytes already
|
||||
size_t toCopy = size_t(packetOffset + packetSize - (uint64)pos);
|
||||
if (toCopy > bufferSize)
|
||||
toCopy = bufferSize;
|
||||
memcpy(buffer, header->data + (pos - packetOffset), toCopy);
|
||||
|
||||
pos += toCopy;
|
||||
buffer += toCopy;
|
||||
bufferSize -= toCopy;
|
||||
return toCopy;
|
||||
}
|
||||
|
||||
// _SendRequest
|
||||
status_t
|
||||
RemoteDisk::_SendRequest(UDPSocket *socket, ip_addr_t serverAddress,
|
||||
uint16 serverPort, remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **_packet)
|
||||
{
|
||||
request->port = htons(socket->Port());
|
||||
|
||||
// try sending the request 3 times at most
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// send request
|
||||
status_t error = socket->Send(serverAddress, serverPort, request, size);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// receive reply
|
||||
bigtime_t timeout = system_time() + kRequestTimeout;
|
||||
do {
|
||||
UDPPacket *packet;
|
||||
error = socket->Receive(&packet, timeout - system_time());
|
||||
if (error == B_OK) {
|
||||
// got something; check, if it is looks good
|
||||
if (packet->DataSize() >= sizeof(remote_disk_header)) {
|
||||
remote_disk_header *reply
|
||||
= (remote_disk_header*)packet->Data();
|
||||
if (reply->request_id == request->request_id
|
||||
&& reply->command == expectedReply) {
|
||||
*_packet = packet;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// reply not OK
|
||||
delete packet;
|
||||
} else if (error != B_TIMED_OUT && error != B_WOULD_BLOCK)
|
||||
return error;
|
||||
|
||||
} while (timeout > system_time());
|
||||
}
|
||||
|
||||
// no reply
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// _SendRequest
|
||||
status_t
|
||||
RemoteDisk::_SendRequest(remote_disk_header *request, size_t size,
|
||||
uint8 expectedReply, UDPPacket **packet)
|
||||
{
|
||||
request->request_id = fRequestID++;
|
||||
return _SendRequest(fSocket, fServerAddress, fServerPort, request, size,
|
||||
expectedReply, packet);
|
||||
}
|
||||
|
@ -1,114 +1,114 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <boot/platform/openfirmware/platform_arch.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <kernel.h>
|
||||
#include <platform/openfirmware/devices.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
#define TRACE_CPU
|
||||
#ifdef TRACE_CPU
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
status_t
|
||||
boot_arch_cpu_init(void)
|
||||
{
|
||||
// iterate through the "/cpus" node to find all CPUs
|
||||
int cpus = of_finddevice("/cpus");
|
||||
if (cpus == OF_FAILED) {
|
||||
printf("boot_arch_cpu_init(): Failed to open \"/cpus\"!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
char cpuPath[256];
|
||||
int cookie = 0;
|
||||
int cpuCount = 0;
|
||||
while (of_get_next_device(&cookie, cpus, "cpu", cpuPath,
|
||||
sizeof(cpuPath)) == B_OK) {
|
||||
TRACE(("found CPU: %s\n", cpuPath));
|
||||
|
||||
// For the first CPU get the frequencies of CPU, bus, and time base.
|
||||
// We assume they are the same for all CPUs.
|
||||
if (cpuCount == 0) {
|
||||
int cpu = of_finddevice(cpuPath);
|
||||
if (cpu == OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed get CPU device node!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// TODO: Does encode-int really encode quadlet (32 bit numbers)
|
||||
// only?
|
||||
int32 clockFrequency;
|
||||
if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get CPU clock "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
int32 busFrequency;
|
||||
if (of_getprop(cpu, "bus-frequency", &busFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get bus clock "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
int32 timeBaseFrequency;
|
||||
if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get time base "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
gKernelArgs.arch_args.cpu_frequency = clockFrequency;
|
||||
gKernelArgs.arch_args.bus_frequency = busFrequency;
|
||||
gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
|
||||
|
||||
TRACE((" CPU clock frequency: %ld\n", clockFrequency));
|
||||
TRACE((" bus clock frequency: %ld\n", busFrequency));
|
||||
TRACE((" time base frequency: %ld\n", timeBaseFrequency));
|
||||
}
|
||||
|
||||
cpuCount++;
|
||||
}
|
||||
|
||||
if (cpuCount == 0) {
|
||||
printf("boot_arch_cpu_init(): Found no CPUs!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
gKernelArgs.num_cpus = cpuCount;
|
||||
|
||||
// allocate the kernel stacks (the memory stuff is already initialized
|
||||
// at this point)
|
||||
addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
|
||||
cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE),
|
||||
B_READ_AREA | B_WRITE_AREA, false);
|
||||
if (!stack) {
|
||||
printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (int i = 0; i < cpuCount; i++) {
|
||||
gKernelArgs.cpu_kstack[i].start = stack;
|
||||
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
|
||||
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||
stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <boot/platform/openfirmware/platform_arch.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <kernel.h>
|
||||
#include <platform/openfirmware/devices.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
#define TRACE_CPU
|
||||
#ifdef TRACE_CPU
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
status_t
|
||||
boot_arch_cpu_init(void)
|
||||
{
|
||||
// iterate through the "/cpus" node to find all CPUs
|
||||
int cpus = of_finddevice("/cpus");
|
||||
if (cpus == OF_FAILED) {
|
||||
printf("boot_arch_cpu_init(): Failed to open \"/cpus\"!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
char cpuPath[256];
|
||||
int cookie = 0;
|
||||
int cpuCount = 0;
|
||||
while (of_get_next_device(&cookie, cpus, "cpu", cpuPath,
|
||||
sizeof(cpuPath)) == B_OK) {
|
||||
TRACE(("found CPU: %s\n", cpuPath));
|
||||
|
||||
// For the first CPU get the frequencies of CPU, bus, and time base.
|
||||
// We assume they are the same for all CPUs.
|
||||
if (cpuCount == 0) {
|
||||
int cpu = of_finddevice(cpuPath);
|
||||
if (cpu == OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed get CPU device node!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// TODO: Does encode-int really encode quadlet (32 bit numbers)
|
||||
// only?
|
||||
int32 clockFrequency;
|
||||
if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get CPU clock "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
int32 busFrequency;
|
||||
if (of_getprop(cpu, "bus-frequency", &busFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get bus clock "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
int32 timeBaseFrequency;
|
||||
if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get time base "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
gKernelArgs.arch_args.cpu_frequency = clockFrequency;
|
||||
gKernelArgs.arch_args.bus_frequency = busFrequency;
|
||||
gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
|
||||
|
||||
TRACE((" CPU clock frequency: %ld\n", clockFrequency));
|
||||
TRACE((" bus clock frequency: %ld\n", busFrequency));
|
||||
TRACE((" time base frequency: %ld\n", timeBaseFrequency));
|
||||
}
|
||||
|
||||
cpuCount++;
|
||||
}
|
||||
|
||||
if (cpuCount == 0) {
|
||||
printf("boot_arch_cpu_init(): Found no CPUs!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
gKernelArgs.num_cpus = cpuCount;
|
||||
|
||||
// allocate the kernel stacks (the memory stuff is already initialized
|
||||
// at this point)
|
||||
addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
|
||||
cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE),
|
||||
B_READ_AREA | B_WRITE_AREA, false);
|
||||
if (!stack) {
|
||||
printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (int i = 0; i < cpuCount; i++) {
|
||||
gKernelArgs.cpu_kstack[i].start = stack;
|
||||
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
|
||||
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||
stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,29 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "real_time_clock.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <platform/openfirmware/devices.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
status_t
|
||||
init_real_time_clock(void)
|
||||
{
|
||||
// find RTC
|
||||
int rtcCookie = 0;
|
||||
if (of_get_next_device(&rtcCookie, 0, "rtc",
|
||||
gKernelArgs.platform_args.rtc_path,
|
||||
sizeof(gKernelArgs.platform_args.rtc_path)) != B_OK) {
|
||||
printf("init_real_time_clock(): Found no RTC device!");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "real_time_clock.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <platform/openfirmware/devices.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
status_t
|
||||
init_real_time_clock(void)
|
||||
{
|
||||
// find RTC
|
||||
int rtcCookie = 0;
|
||||
if (of_get_next_device(&rtcCookie, 0, "rtc",
|
||||
gKernelArgs.platform_args.rtc_path,
|
||||
sizeof(gKernelArgs.platform_args.rtc_path)) != B_OK) {
|
||||
printf("init_real_time_clock(): Found no RTC device!");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef OPENFIRMWARE_REAL_TIME_CLOCK_H
|
||||
#define OPENFIRMWARE_REAL_TIME_CLOCK_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t init_real_time_clock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* OPENFIRMWARE_REAL_TIME_CLOCK_H */
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef OPENFIRMWARE_REAL_TIME_CLOCK_H
|
||||
#define OPENFIRMWARE_REAL_TIME_CLOCK_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t init_real_time_clock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* OPENFIRMWARE_REAL_TIME_CLOCK_H */
|
||||
|
@ -1,15 +1,15 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
int result = of_milliseconds();
|
||||
return (result == OF_FAILED ? 0 : bigtime_t(result) * 1000);
|
||||
}
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
int result = of_milliseconds();
|
||||
return (result == OF_FAILED ? 0 : bigtime_t(result) * 1000);
|
||||
}
|
||||
|
@ -1,251 +1,251 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <arch_platform.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <real_time_clock.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
|
||||
static PPCPlatform *sPPCPlatform;
|
||||
|
||||
|
||||
// constructor
|
||||
PPCPlatform::PPCPlatform(ppc_platform_type platformType)
|
||||
: fPlatformType(platformType)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
PPCPlatform::~PPCPlatform()
|
||||
{
|
||||
}
|
||||
|
||||
// Default
|
||||
PPCPlatform *
|
||||
PPCPlatform::Default()
|
||||
{
|
||||
return sPPCPlatform;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Open Firmware
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class PPCOpenFirmware : public PPCPlatform {
|
||||
public:
|
||||
PPCOpenFirmware();
|
||||
virtual ~PPCOpenFirmware();
|
||||
|
||||
virtual status_t Init(struct kernel_args *kernelArgs);
|
||||
virtual status_t InitSerialDebug(struct kernel_args *kernelArgs);
|
||||
virtual status_t InitPostVM(struct kernel_args *kernelArgs);
|
||||
virtual status_t InitRTC(struct kernel_args *kernelArgs,
|
||||
struct real_time_data *data);
|
||||
|
||||
virtual char SerialDebugGetChar();
|
||||
virtual void SerialDebugPutChar(char c);
|
||||
|
||||
virtual void SetHardwareRTC(uint32 seconds);
|
||||
virtual uint32 GetHardwareRTC();
|
||||
|
||||
virtual void ShutDown(bool reboot);
|
||||
|
||||
private:
|
||||
int fInput;
|
||||
int fOutput;
|
||||
int fRTC;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::PPCOpenFirmware;
|
||||
|
||||
|
||||
// OF debugger commands
|
||||
|
||||
// debug_command_of_exit
|
||||
static int
|
||||
debug_command_of_exit(int argc, char **argv)
|
||||
{
|
||||
of_exit();
|
||||
kprintf("of_exit() failed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// debug_command_of_enter
|
||||
static int
|
||||
debug_command_of_enter(int argc, char **argv)
|
||||
{
|
||||
of_call_client_function("enter", 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// constructor
|
||||
PPCOpenFirmware::PPCOpenFirmware()
|
||||
: PPCPlatform(PPC_PLATFORM_OPEN_FIRMWARE),
|
||||
fInput(-1),
|
||||
fOutput(-1),
|
||||
fRTC(-1)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
PPCOpenFirmware::~PPCOpenFirmware()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
status_t
|
||||
PPCOpenFirmware::Init(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return of_init(
|
||||
(int(*)(void*))kernelArgs->platform_args.openfirmware_entry);
|
||||
}
|
||||
|
||||
// InitSerialDebug
|
||||
status_t
|
||||
PPCOpenFirmware::InitSerialDebug(struct kernel_args *kernelArgs)
|
||||
{
|
||||
if (of_getprop(gChosen, "stdin", &fInput, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
if (of_getprop(gChosen, "stdout", &fOutput, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// InitPostVM
|
||||
status_t
|
||||
PPCOpenFirmware::InitPostVM(struct kernel_args *kernelArgs)
|
||||
{
|
||||
add_debugger_command("of_exit", &debug_command_of_exit,
|
||||
"Exit to the Open Firmware prompt. No way to get back into the OS!");
|
||||
add_debugger_command("of_enter", &debug_command_of_enter,
|
||||
"Enter a subordinate Open Firmware interpreter. Quitting it returns "
|
||||
"to KDL.");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// InitRTC
|
||||
status_t
|
||||
PPCOpenFirmware::InitRTC(struct kernel_args *kernelArgs,
|
||||
struct real_time_data *data)
|
||||
{
|
||||
// open RTC
|
||||
fRTC = of_open(kernelArgs->platform_args.rtc_path);
|
||||
if (fRTC == OF_FAILED) {
|
||||
dprintf("PPCOpenFirmware::InitRTC(): Failed open RTC device!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// DebugSerialGetChar
|
||||
char
|
||||
PPCOpenFirmware::SerialDebugGetChar()
|
||||
{
|
||||
int key;
|
||||
if (of_interpret("key", 0, 1, &key) == OF_FAILED)
|
||||
return 0;
|
||||
return (char)key;
|
||||
}
|
||||
|
||||
// DebugSerialPutChar
|
||||
void
|
||||
PPCOpenFirmware::SerialDebugPutChar(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
of_write(fOutput, "\r\n", 2);
|
||||
else
|
||||
of_write(fOutput, &c, 1);
|
||||
}
|
||||
|
||||
// SetHardwareRTC
|
||||
void
|
||||
PPCOpenFirmware::SetHardwareRTC(uint32 seconds)
|
||||
{
|
||||
struct tm t;
|
||||
rtc_secs_to_tm(seconds, &t);
|
||||
|
||||
t.tm_year += RTC_EPOCH_BASE_YEAR;
|
||||
t.tm_mon++;
|
||||
|
||||
if (of_call_method(fRTC, "set-time", 6, 0, t.tm_year, t.tm_mon, t.tm_mday,
|
||||
t.tm_hour, t.tm_min, t.tm_sec) == OF_FAILED) {
|
||||
dprintf("PPCOpenFirmware::SetHardwareRTC(): Failed to set RTC!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// GetHardwareRTC
|
||||
uint32
|
||||
PPCOpenFirmware::GetHardwareRTC()
|
||||
{
|
||||
struct tm t;
|
||||
if (of_call_method(fRTC, "get-time", 0, 6, &t.tm_year, &t.tm_mon,
|
||||
&t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) == OF_FAILED) {
|
||||
dprintf("PPCOpenFirmware::GetHardwareRTC(): Failed to get RTC!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
t.tm_year -= RTC_EPOCH_BASE_YEAR;
|
||||
t.tm_mon--;
|
||||
|
||||
return rtc_tm_to_secs(&t);
|
||||
}
|
||||
|
||||
// ShutDown
|
||||
void
|
||||
PPCOpenFirmware::ShutDown(bool reboot)
|
||||
{
|
||||
if (reboot) {
|
||||
of_interpret("reset-all", 0, 0);
|
||||
} else {
|
||||
// not standardized, so it might fail
|
||||
of_interpret("shut-down", 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// # pragma mark -
|
||||
|
||||
|
||||
// static buffer for constructing the actual PPCPlatform
|
||||
static char *sPPCPlatformBuffer[sizeof(PPCOpenFirmware)];
|
||||
|
||||
status_t
|
||||
arch_platform_init(struct kernel_args *kernelArgs)
|
||||
{
|
||||
// only OpenFirmware supported for now
|
||||
if (true)
|
||||
sPPCPlatform = new(sPPCPlatformBuffer) PPCOpenFirmware;
|
||||
|
||||
return sPPCPlatform->Init(kernelArgs);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
arch_platform_init_post_vm(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return sPPCPlatform->InitPostVM(kernelArgs);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
arch_platform_init_post_thread(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <arch_platform.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <real_time_clock.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
|
||||
static PPCPlatform *sPPCPlatform;
|
||||
|
||||
|
||||
// constructor
|
||||
PPCPlatform::PPCPlatform(ppc_platform_type platformType)
|
||||
: fPlatformType(platformType)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
PPCPlatform::~PPCPlatform()
|
||||
{
|
||||
}
|
||||
|
||||
// Default
|
||||
PPCPlatform *
|
||||
PPCPlatform::Default()
|
||||
{
|
||||
return sPPCPlatform;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Open Firmware
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class PPCOpenFirmware : public PPCPlatform {
|
||||
public:
|
||||
PPCOpenFirmware();
|
||||
virtual ~PPCOpenFirmware();
|
||||
|
||||
virtual status_t Init(struct kernel_args *kernelArgs);
|
||||
virtual status_t InitSerialDebug(struct kernel_args *kernelArgs);
|
||||
virtual status_t InitPostVM(struct kernel_args *kernelArgs);
|
||||
virtual status_t InitRTC(struct kernel_args *kernelArgs,
|
||||
struct real_time_data *data);
|
||||
|
||||
virtual char SerialDebugGetChar();
|
||||
virtual void SerialDebugPutChar(char c);
|
||||
|
||||
virtual void SetHardwareRTC(uint32 seconds);
|
||||
virtual uint32 GetHardwareRTC();
|
||||
|
||||
virtual void ShutDown(bool reboot);
|
||||
|
||||
private:
|
||||
int fInput;
|
||||
int fOutput;
|
||||
int fRTC;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::PPCOpenFirmware;
|
||||
|
||||
|
||||
// OF debugger commands
|
||||
|
||||
// debug_command_of_exit
|
||||
static int
|
||||
debug_command_of_exit(int argc, char **argv)
|
||||
{
|
||||
of_exit();
|
||||
kprintf("of_exit() failed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// debug_command_of_enter
|
||||
static int
|
||||
debug_command_of_enter(int argc, char **argv)
|
||||
{
|
||||
of_call_client_function("enter", 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// constructor
|
||||
PPCOpenFirmware::PPCOpenFirmware()
|
||||
: PPCPlatform(PPC_PLATFORM_OPEN_FIRMWARE),
|
||||
fInput(-1),
|
||||
fOutput(-1),
|
||||
fRTC(-1)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
PPCOpenFirmware::~PPCOpenFirmware()
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
status_t
|
||||
PPCOpenFirmware::Init(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return of_init(
|
||||
(int(*)(void*))kernelArgs->platform_args.openfirmware_entry);
|
||||
}
|
||||
|
||||
// InitSerialDebug
|
||||
status_t
|
||||
PPCOpenFirmware::InitSerialDebug(struct kernel_args *kernelArgs)
|
||||
{
|
||||
if (of_getprop(gChosen, "stdin", &fInput, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
if (of_getprop(gChosen, "stdout", &fOutput, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// InitPostVM
|
||||
status_t
|
||||
PPCOpenFirmware::InitPostVM(struct kernel_args *kernelArgs)
|
||||
{
|
||||
add_debugger_command("of_exit", &debug_command_of_exit,
|
||||
"Exit to the Open Firmware prompt. No way to get back into the OS!");
|
||||
add_debugger_command("of_enter", &debug_command_of_enter,
|
||||
"Enter a subordinate Open Firmware interpreter. Quitting it returns "
|
||||
"to KDL.");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// InitRTC
|
||||
status_t
|
||||
PPCOpenFirmware::InitRTC(struct kernel_args *kernelArgs,
|
||||
struct real_time_data *data)
|
||||
{
|
||||
// open RTC
|
||||
fRTC = of_open(kernelArgs->platform_args.rtc_path);
|
||||
if (fRTC == OF_FAILED) {
|
||||
dprintf("PPCOpenFirmware::InitRTC(): Failed open RTC device!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// DebugSerialGetChar
|
||||
char
|
||||
PPCOpenFirmware::SerialDebugGetChar()
|
||||
{
|
||||
int key;
|
||||
if (of_interpret("key", 0, 1, &key) == OF_FAILED)
|
||||
return 0;
|
||||
return (char)key;
|
||||
}
|
||||
|
||||
// DebugSerialPutChar
|
||||
void
|
||||
PPCOpenFirmware::SerialDebugPutChar(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
of_write(fOutput, "\r\n", 2);
|
||||
else
|
||||
of_write(fOutput, &c, 1);
|
||||
}
|
||||
|
||||
// SetHardwareRTC
|
||||
void
|
||||
PPCOpenFirmware::SetHardwareRTC(uint32 seconds)
|
||||
{
|
||||
struct tm t;
|
||||
rtc_secs_to_tm(seconds, &t);
|
||||
|
||||
t.tm_year += RTC_EPOCH_BASE_YEAR;
|
||||
t.tm_mon++;
|
||||
|
||||
if (of_call_method(fRTC, "set-time", 6, 0, t.tm_year, t.tm_mon, t.tm_mday,
|
||||
t.tm_hour, t.tm_min, t.tm_sec) == OF_FAILED) {
|
||||
dprintf("PPCOpenFirmware::SetHardwareRTC(): Failed to set RTC!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// GetHardwareRTC
|
||||
uint32
|
||||
PPCOpenFirmware::GetHardwareRTC()
|
||||
{
|
||||
struct tm t;
|
||||
if (of_call_method(fRTC, "get-time", 0, 6, &t.tm_year, &t.tm_mon,
|
||||
&t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) == OF_FAILED) {
|
||||
dprintf("PPCOpenFirmware::GetHardwareRTC(): Failed to get RTC!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
t.tm_year -= RTC_EPOCH_BASE_YEAR;
|
||||
t.tm_mon--;
|
||||
|
||||
return rtc_tm_to_secs(&t);
|
||||
}
|
||||
|
||||
// ShutDown
|
||||
void
|
||||
PPCOpenFirmware::ShutDown(bool reboot)
|
||||
{
|
||||
if (reboot) {
|
||||
of_interpret("reset-all", 0, 0);
|
||||
} else {
|
||||
// not standardized, so it might fail
|
||||
of_interpret("shut-down", 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// # pragma mark -
|
||||
|
||||
|
||||
// static buffer for constructing the actual PPCPlatform
|
||||
static char *sPPCPlatformBuffer[sizeof(PPCOpenFirmware)];
|
||||
|
||||
status_t
|
||||
arch_platform_init(struct kernel_args *kernelArgs)
|
||||
{
|
||||
// only OpenFirmware supported for now
|
||||
if (true)
|
||||
sPPCPlatform = new(sPPCPlatformBuffer) PPCOpenFirmware;
|
||||
|
||||
return sPPCPlatform->Init(kernelArgs);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
arch_platform_init_post_vm(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return sPPCPlatform->InitPostVM(kernelArgs);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
arch_platform_init_post_thread(struct kernel_args *kernelArgs)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user