OpenFirmware bindings for the stage2 boot loader.
Not yet complete. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4465 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ededd6e07f
commit
8abaaaf7e5
3
src/kernel/boot/platform/Jamfile
Normal file
3
src/kernel/boot/platform/Jamfile
Normal file
@ -0,0 +1,3 @@
|
||||
SubDir OBOS_TOP src kernel boot platform ;
|
||||
|
||||
SubInclude OBOS_TOP src kernel boot platform $(OBOS_BOOT_PLATFORM) ;
|
64
src/kernel/boot/platform/openfirmware/Handle.cpp
Normal file
64
src/kernel/boot/platform/openfirmware/Handle.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "Handle.h"
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
Handle::Handle(int handle, bool takeOwnership)
|
||||
:
|
||||
fHandle(handle),
|
||||
fOwnHandle(takeOwnership)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Handle::Handle(void)
|
||||
:
|
||||
fHandle(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Handle::~Handle()
|
||||
{
|
||||
if (fOwnHandle)
|
||||
of_close(fHandle);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Handle::SetHandle(int handle, bool takeOwnership)
|
||||
{
|
||||
if (fHandle && fOwnHandle)
|
||||
of_close(fHandle);
|
||||
|
||||
fHandle = handle;
|
||||
fOwnHandle = takeOwnership;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
Handle::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||
{
|
||||
if (pos == -1 || of_seek(fHandle, pos) != OF_FAILED)
|
||||
return of_read(fHandle, buffer, bufferSize);
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
Handle::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
||||
{
|
||||
if (pos == -1 || of_seek(fHandle, pos) != OF_FAILED)
|
||||
return of_write(fHandle, buffer, bufferSize);
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
32
src/kernel/boot/platform/openfirmware/Handle.h
Normal file
32
src/kernel/boot/platform/openfirmware/Handle.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
#ifndef HANDLE_H
|
||||
#define HANDLE_H
|
||||
|
||||
|
||||
#include <boot/vfs.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
class Handle : public ConsoleNode {
|
||||
public:
|
||||
Handle(int handle, bool takeOwnership = true);
|
||||
Handle();
|
||||
virtual ~Handle();
|
||||
|
||||
void SetHandle(int handle, bool takeOwnership = true);
|
||||
|
||||
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);
|
||||
|
||||
protected:
|
||||
int fHandle;
|
||||
bool fOwnHandle;
|
||||
};
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HANDLE_H */
|
19
src/kernel/boot/platform/openfirmware/Jamfile
Normal file
19
src/kernel/boot/platform/openfirmware/Jamfile
Normal file
@ -0,0 +1,19 @@
|
||||
SubDir OBOS_TOP src kernel boot platform openfirmware ;
|
||||
|
||||
SubDirHdrs $(OBOS_TOP) headers private kernel boot platform $(OBOS_BOOT_PLATFORM) ;
|
||||
|
||||
KernelMergeObject boot_platform_openfirmware.o :
|
||||
# crt0.S
|
||||
<$(SOURCE_GRIST)>start.c
|
||||
<$(SOURCE_GRIST)>openfirmware.c
|
||||
<$(SOURCE_GRIST)>debug.c
|
||||
<$(SOURCE_GRIST)>Handle.cpp
|
||||
<$(SOURCE_GRIST)>devices.cpp
|
||||
<$(SOURCE_GRIST)>console.cpp
|
||||
<$(SOURCE_GRIST)>heap.cpp
|
||||
:
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles crt0.S ]
|
||||
= [ FDirName $(OBOS_TOP) src kernel boot arch $(OBOS_ARCH) ] ;
|
||||
|
76
src/kernel/boot/platform/openfirmware/console.cpp
Normal file
76
src/kernel/boot/platform/openfirmware/console.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Handle.h"
|
||||
#include "console.h"
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
class ConsoleHandle : public Handle {
|
||||
public:
|
||||
ConsoleHandle();
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
static ConsoleHandle sInput, sOutput;
|
||||
FILE *stdin, *stdout, *stderr;
|
||||
int gChosen;
|
||||
|
||||
|
||||
ConsoleHandle::ConsoleHandle()
|
||||
: Handle()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
ConsoleHandle::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||
{
|
||||
// don't seek in character devices
|
||||
return of_read(fHandle, buffer, bufferSize);
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
ConsoleHandle::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
||||
{
|
||||
// don't seek in character devices
|
||||
return of_write(fHandle, buffer, bufferSize);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
console_init(void)
|
||||
{
|
||||
gChosen = of_finddevice("/chosen");
|
||||
if (gChosen == OF_FAILED)
|
||||
return B_ERROR;
|
||||
|
||||
int input, output;
|
||||
if (of_getprop(gChosen, "stdin", &input, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
if (of_getprop(gChosen, "stdout", &output, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
|
||||
sInput.SetHandle(input);
|
||||
sOutput.SetHandle(output);
|
||||
|
||||
// now that we're initialized, enable stdio functionality
|
||||
stdin = (FILE *)&sInput;
|
||||
stdout = stderr = (FILE *)&sOutput;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
29
src/kernel/boot/platform/openfirmware/console.h
Normal file
29
src/kernel/boot/platform/openfirmware/console.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/stdio.h>
|
||||
|
||||
#include "Handle.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern status_t console_init(void);
|
||||
|
||||
extern status_t set_cursor_pos(FILE *, int x, int y);
|
||||
extern status_t set_foreground_color(FILE *, int c);
|
||||
extern status_t set_background_color(FILE *, int c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONSOLE_H */
|
31
src/kernel/boot/platform/openfirmware/debug.c
Normal file
31
src/kernel/boot/platform/openfirmware/debug.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
/** ToDo: this works only after console_init() was called.
|
||||
* But it probably should do something before as well...
|
||||
*/
|
||||
|
||||
void
|
||||
panic(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
|
||||
puts("*** PANIC ***");
|
||||
|
||||
va_start(list, format);
|
||||
vprintf(format, list);
|
||||
va_end(list);
|
||||
|
||||
of_exit();
|
||||
}
|
||||
|
30
src/kernel/boot/platform/openfirmware/devices.cpp
Normal file
30
src/kernel/boot/platform/openfirmware/devices.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <boot/platform.h>
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/stdio.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include "Handle.h"
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
status_t
|
||||
platform_get_boot_devices(stage2_args *args, list *devicesList)
|
||||
{
|
||||
int handle;
|
||||
|
||||
if ((handle = of_finddevice("ide0")) != OF_FAILED) {
|
||||
Handle *device = new Handle(handle, false);
|
||||
|
||||
printf("Found IDE device, handle = %d.\n", handle);
|
||||
list_add_item(devicesList, device);
|
||||
}
|
||||
puts("platform_get_boot_devices() end.");
|
||||
return B_OK;
|
||||
}
|
||||
|
61
src/kernel/boot/platform/openfirmware/heap.cpp
Normal file
61
src/kernel/boot/platform/openfirmware/heap.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <boot/platform.h>
|
||||
#include <boot/heap.h>
|
||||
#include <boot/stdio.h>
|
||||
#include "openfirmware.h"
|
||||
|
||||
|
||||
#define TRACE_HEAP 1
|
||||
#if TRACE_HEAP
|
||||
# define TRACE(x) printf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
#define HEAP_SIZE 32768
|
||||
|
||||
|
||||
struct of_address {
|
||||
void *base;
|
||||
int size;
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
platform_init_heap(stage2_args *args, void **_base, void **_top)
|
||||
{
|
||||
TRACE(("platform_init_heap()\n"));
|
||||
|
||||
int memory;
|
||||
if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
|
||||
printf("memory = %d\n", memory);
|
||||
struct of_address available;
|
||||
int memPackage = of_instance_to_package(memory);
|
||||
printf("memPackage = %d\n", memPackage);
|
||||
of_getprop(memPackage, "available", &available, sizeof(struct of_address));
|
||||
printf("available: base = %p, size = %d\n", available.base, available.size);
|
||||
|
||||
*_base = of_claim(available.base, HEAP_SIZE);
|
||||
printf("heap base = %p\n", *_base);
|
||||
*_top = (void *)((int8 *)*_base + HEAP_SIZE);
|
||||
printf("heap top = %p\n", *_top);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
platform_release_heap(void *base)
|
||||
{
|
||||
if (base != NULL)
|
||||
of_release(base, HEAP_SIZE);
|
||||
}
|
||||
|
471
src/kernel/boot/platform/openfirmware/openfirmware.c
Normal file
471
src/kernel/boot/platform/openfirmware/openfirmware.c
Normal file
@ -0,0 +1,471 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include "openfirmware.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
// OpenFirmware entry function
|
||||
static int (*gCallOpenFirmware)(void *) = 0;
|
||||
|
||||
|
||||
void
|
||||
of_init(int (*openFirmwareEntry)(void *))
|
||||
{
|
||||
gCallOpenFirmware = openFirmwareEntry;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_call_method(const char *method, int numArgs, int numReturns, ...)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
void *args[10];
|
||||
} args = {method, numArgs, numReturns};
|
||||
va_list list;
|
||||
int i;
|
||||
|
||||
// iterate over all arguments and copy them into the
|
||||
// structure passed over to the OpenFirmware
|
||||
|
||||
va_start(list, numReturns);
|
||||
for (i = 0; i < numArgs; i++) {
|
||||
// copy args
|
||||
args.args[i] = (void *)va_arg(list, void *);
|
||||
}
|
||||
for (i = numArgs; i < numArgs + numReturns; i++) {
|
||||
// clear return values
|
||||
args.args[i] = NULL;
|
||||
}
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
if (numReturns > 0) {
|
||||
// copy return values over to the provided location
|
||||
|
||||
for (i = numArgs; i < numArgs + numReturns; i++) {
|
||||
void **store = va_arg(list, void **);
|
||||
if (store)
|
||||
*store = args.args[i];
|
||||
}
|
||||
}
|
||||
va_end(list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_finddevice(const char *device)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
const char *device;
|
||||
int handle;
|
||||
} args = {"finddevice", 1, 1, device, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.handle;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the first child of the given node
|
||||
*/
|
||||
|
||||
int
|
||||
of_child(int node)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int node;
|
||||
int child;
|
||||
} args = {"child", 1, 1, node, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.child;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the next sibling of the given node
|
||||
*/
|
||||
|
||||
int
|
||||
of_peer(int node)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int node;
|
||||
int next_sibling;
|
||||
} args = {"peer", 1, 1, node, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.next_sibling;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the parent of the given node
|
||||
*/
|
||||
|
||||
int
|
||||
of_parent(int node)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int node;
|
||||
int parent;
|
||||
} args = {"parent", 1, 1, node, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.parent;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_instance_to_path(int instance, char *pathBuffer, int bufferSize)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int instance;
|
||||
char *path_buffer;
|
||||
int buffer_size;
|
||||
int size;
|
||||
} args = {"instance-to-path", 3, 1, instance, pathBuffer, bufferSize, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.size;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_instance_to_package(int instance)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int instance;
|
||||
int package;
|
||||
} args = {"instance-to-package", 1, 1, instance, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.package;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_getprop(int package, const char *property, void *buffer, int bufferSize)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int package;
|
||||
const char *property;
|
||||
void *buffer;
|
||||
int buffer_size;
|
||||
int size;
|
||||
} args = {"getprop", 4, 1, package, property, buffer, bufferSize, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.size;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_setprop(int package, const char *property, const void *buffer, int bufferSize)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int package;
|
||||
const char *property;
|
||||
const void *buffer;
|
||||
int buffer_size;
|
||||
int size;
|
||||
} args = {"setprop", 4, 1, package, property, buffer, bufferSize, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.size;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_getproplen(int package, const char *property)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int package;
|
||||
const char *property;
|
||||
int size;
|
||||
} args = {"getproplen", 2, 1, package, property, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.size;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_nextprop(int package, const char *previousProperty, char *nextProperty)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int package;
|
||||
const char *previous_property;
|
||||
char *next_property;
|
||||
int flag;
|
||||
} args = {"nextprop", 3, 1, package, previousProperty, nextProperty, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.flag;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_package_to_path(int package, char *pathBuffer, int bufferSize)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int package;
|
||||
char *path_buffer;
|
||||
int buffer_size;
|
||||
int size;
|
||||
} args = {"package-to-path", 3, 1, package, pathBuffer, bufferSize, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.size;
|
||||
}
|
||||
|
||||
|
||||
// I/O functions
|
||||
|
||||
|
||||
int
|
||||
of_open(const char *nodeName)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
const char *node_name;
|
||||
int handle;
|
||||
} args = {"open", 1, 1, nodeName, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED || args.handle == 0)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.handle;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
of_close(int handle)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int handle;
|
||||
} args = {"close", 1, 0, handle};
|
||||
|
||||
gCallOpenFirmware(&args);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_read(int handle, void *buffer, int bufferSize)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int handle;
|
||||
void *buffer;
|
||||
int buffer_size;
|
||||
int size;
|
||||
} args = {"read", 3, 1, handle, buffer, bufferSize, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.size;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_write(int handle, const void *buffer, int bufferSize)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int handle;
|
||||
const void *buffer;
|
||||
int buffer_size;
|
||||
int size;
|
||||
} args = {"write", 3, 1, handle, buffer, bufferSize, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.size;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
of_seek(int handle, long long pos)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int handle;
|
||||
int64 pos;
|
||||
int status;
|
||||
} args = {"seek", 3, 1, handle, pos, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.status;
|
||||
}
|
||||
|
||||
|
||||
// memory functions
|
||||
|
||||
|
||||
int
|
||||
of_release(void *virtual, int size)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
void *virtual;
|
||||
int size;
|
||||
} args = {"release", 2, 0, virtual, size};
|
||||
|
||||
return gCallOpenFirmware(&args);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
of_claim(void *virtual, int size)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
void *virtual;
|
||||
int size;
|
||||
int align;
|
||||
void *address;
|
||||
} args = {"claim", 3, 1, virtual, size, 64};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return NULL;
|
||||
|
||||
return args.address;
|
||||
}
|
||||
|
||||
|
||||
// misc functions
|
||||
|
||||
|
||||
/** tests if the given service is missing
|
||||
*/
|
||||
|
||||
int
|
||||
of_test(const char *service)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
const char *service;
|
||||
int missing;
|
||||
} args = {"test", 1, 1, service, 0};
|
||||
|
||||
if (gCallOpenFirmware(&args) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return args.missing;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the millisecond counter
|
||||
*/
|
||||
|
||||
int
|
||||
of_milliseconds(void)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
int milliseconds;
|
||||
} args = {"milliseconds", 0, 1, 0};
|
||||
|
||||
gCallOpenFirmware(&args);
|
||||
|
||||
return args.milliseconds;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
of_exit(void)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
int num_args;
|
||||
int num_returns;
|
||||
} args = {"exit", 0, 0};
|
||||
|
||||
gCallOpenFirmware(&args);
|
||||
}
|
||||
|
57
src/kernel/boot/platform/openfirmware/openfirmware.h
Normal file
57
src/kernel/boot/platform/openfirmware/openfirmware.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
#ifndef OPEN_FIRMWARE_H
|
||||
#define OPEN_FIRMWARE_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#define OF_FAILED (-1)
|
||||
|
||||
/* global device tree/properties access */
|
||||
extern int gChosen;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void of_init(int (*openFirmwareEntry)(void *));
|
||||
|
||||
/* device tree functions */
|
||||
extern int of_finddevice(const char *device);
|
||||
extern int of_child(int node);
|
||||
extern int of_peer(int node);
|
||||
extern int of_parent(int node);
|
||||
extern int of_instance_to_path(int instance, char *pathBuffer, int bufferSize);
|
||||
extern int of_instance_to_package(int instance);
|
||||
extern int of_getprop(int package, const char *property, void *buffer, int bufferSize);
|
||||
extern int of_setprop(int package, const char *property, const void *buffer, int bufferSize);
|
||||
extern int of_nextprop(int package, const char *previousProperty, char *nextProperty);
|
||||
extern int of_getproplen(int package, const char *property);
|
||||
extern int of_package_to_path(int package, char *pathBuffer, int bufferSize);
|
||||
|
||||
/* I/O functions */
|
||||
extern int of_open(const char *nodeName);
|
||||
extern void of_close(int handle);
|
||||
extern int of_read(int handle, void *buffer, int bufferSize);
|
||||
extern int of_write(int handle, const void *buffer, int bufferSize);
|
||||
extern int of_seek(int handle, off_t pos);
|
||||
|
||||
/* memory functions */
|
||||
extern int of_release(void *virtualAddress, int size);
|
||||
extern void *of_claim(void *virtualAddress, int size);
|
||||
|
||||
/* misc functions */
|
||||
extern int of_test(const char *service);
|
||||
extern int of_milliseconds(void);
|
||||
extern void of_exit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OPEN_FIRMWARE_H */
|
71
src/kernel/boot/platform/openfirmware/start.c
Normal file
71
src/kernel/boot/platform/openfirmware/start.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <boot/heap.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "openfirmware.h"
|
||||
#include "console.h"
|
||||
|
||||
|
||||
void _start(uint32 _unused1, uint32 _unused2, void *openFirmwareEntry);
|
||||
void start(void *openFirmwareEntry);
|
||||
int boot(stage2_args *args);
|
||||
|
||||
// GCC defined globals
|
||||
extern void (*__ctor_list)(void);
|
||||
extern void (*__ctor_end)(void);
|
||||
extern uint8 __bss_start;
|
||||
extern uint8 _end;
|
||||
|
||||
|
||||
static void
|
||||
call_ctors(void)
|
||||
{
|
||||
void (**f)(void);
|
||||
|
||||
for (f = &__ctor_list; f < &__ctor_end; f++) {
|
||||
(**f)();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clear_bss(void)
|
||||
{
|
||||
memset(&__bss_start, 0, &_end - &__bss_start);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_start(uint32 _unused1, uint32 _unused3, void *openFirmwareEntry)
|
||||
{
|
||||
// According to the PowerPC bindings, OpenFirmware should have created
|
||||
// a stack of 32kB or higher for us at this point
|
||||
|
||||
clear_bss();
|
||||
call_ctors();
|
||||
// call C++ constructors before doing anything else
|
||||
|
||||
start(openFirmwareEntry);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
start(void *openFirmwareEntry)
|
||||
{
|
||||
of_init(openFirmwareEntry);
|
||||
console_init();
|
||||
|
||||
boot(NULL);
|
||||
// if everything wents fine, boot() never returns
|
||||
|
||||
of_exit();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user