e56cdf2111
Add support for the newworld apple macintosh (PPC). This has been tested on the powerbook 2000 only. It only adds support for generic ieee1275 functions, console and disk support. This should be easy to port to other architectures with support for Open Firmware. * configure.ac: Accept the powerpc as host_cpu. In the case of the powerpc cpu set the host_vendor to ieee1275. Make sure the i386 specific tests are only executed while building for the i386. Inverse test for crosscompile. * genmk.rb (Utility): Allow assembler files. * normal/cmdline.c (pupa_tab_complete): Reset pupa_errno. * conf/powerpc-ieee1275.rmk: New file. * disk/powerpc/ieee1275/ofdisk.c: Likewise. * disk/powerpc/ieee1275/partition.c: Likewise. * include/pupa/powerpc/ieee1275/biosdisk.h: Likewise. * include/pupa/powerpc/ieee1275/console.h: Likewise. * include/pupa/powerpc/ieee1275/partition.h: Likewise. * include/pupa/powerpc/ieee1275/time.h: Likewise. * include/pupa/powerpc/ieee1275/util/biosdisk.h: Likewise. * include/pupa/powerpc/ieee1275/multiboot.h: Likewise. * include/pupa/powerpc/ieee1275/loader.h * include/pupa/powerpc/setjmp.h: Likewise. * include/pupa/powerpc/types.h: Likewise. * kern/powerpc/ieee1275/init.c: Likewise. * kern/powerpc/ieee1275/openfw.c: Likewise. * term/powerpc/ieee1275/ofconsole.c: Likewise. These files were written by Johan Rydberg (jrydberg@night.trouble.net) and I only modified them slightly. * boot/powerpc/ieee1275/cmain.c: New file. * boot/powerpc/ieee1275/crt0.S: Likewise. * boot/powerpc/ieee1275/ieee1275.c: Likewise. * include/pupa/powerpc/ieee1275/ieee1275.h: Likewise.
475 lines
11 KiB
C
475 lines
11 KiB
C
/* ieee1275.c - Access the Open Firmware client interface. */
|
||
/*
|
||
* PUPA -- Preliminary Universal Programming Architecture for GRUB
|
||
* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
*/
|
||
|
||
#include <pupa/machine/ieee1275.h>
|
||
|
||
|
||
#define IEEE1275_PHANDLE_ROOT ((pupa_ieee1275_phandle_t) 0)
|
||
#define IEEE1275_PHANDLE_INVALID ((pupa_ieee1275_phandle_t) -1)
|
||
|
||
intptr_t (*pupa_ieee1275_entry_fn) (void *);
|
||
|
||
#ifndef IEEE1275_CALL_ENTRY_FN
|
||
#define IEEE1275_CALL_ENTRY_FN(args) (*pupa_ieee1275_entry_fn) (args)
|
||
#endif
|
||
|
||
/* All backcalls to the firmware is done by calling an entry function
|
||
which was passed to us from the bootloader. When doing the backcall,
|
||
a structure is passed which specifies what the firmware should do.
|
||
NAME is the requested service. NR_INS and NR_OUTS is the number of
|
||
passed arguments and the expected number of return values, resp. */
|
||
struct pupa_ieee1275_common_hdr
|
||
{
|
||
char *name;
|
||
int nr_ins;
|
||
int nr_outs;
|
||
};
|
||
|
||
#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
|
||
(p)->name = xname; (p)->nr_ins = xins; (p)->nr_outs = xouts
|
||
|
||
/* FIXME is this function needed? */
|
||
pupa_uint32_t
|
||
pupa_ieee1275_decode_int_4 (unsigned char *p)
|
||
{
|
||
pupa_uint32_t val = (*p++ << 8);
|
||
val = (val + *p++) << 8;
|
||
val = (val + *p++) << 8;
|
||
return (val + *p);
|
||
}
|
||
|
||
|
||
int
|
||
pupa_ieee1275_finddevice (char *name, pupa_ieee1275_phandle_t *phandlep)
|
||
{
|
||
struct find_device_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
char *device;
|
||
pupa_ieee1275_phandle_t phandle;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1);
|
||
args.device = name;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*phandlep = args.phandle;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_get_property (int handle, const char *property, void *buf,
|
||
pupa_size_t size, pupa_size_t *actual)
|
||
{
|
||
struct get_property_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t phandle;
|
||
const char *prop;
|
||
void *buf;
|
||
int buflen;
|
||
int size;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1);
|
||
args.phandle = handle;
|
||
args.prop = property;
|
||
args.buf = buf;
|
||
args.buflen = size;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
if (actual)
|
||
*actual = args.size;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_next_property (int handle, char *prev_prop, char *prop,
|
||
int *flags)
|
||
{
|
||
struct get_property_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t phandle;
|
||
char *prev_prop;
|
||
char *next_prop;
|
||
int flags;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1);
|
||
args.phandle = handle;
|
||
args.prev_prop = prev_prop;
|
||
args.next_prop = prop;
|
||
args.flags = -1;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
if (flags)
|
||
*flags = args.flags;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_get_property_length (pupa_ieee1275_phandle_t handle,
|
||
const char *prop, pupa_size_t *length)
|
||
{
|
||
struct get_property_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t phandle;
|
||
const char *prop;
|
||
pupa_size_t length;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1);
|
||
args.phandle = handle;
|
||
args.prop = prop;
|
||
args.length = -1;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*length = args.length;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_instance_to_package (pupa_ieee1275_ihandle_t ihandle,
|
||
pupa_ieee1275_phandle_t *phandlep)
|
||
{
|
||
struct instance_to_package_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_ihandle_t ihandle;
|
||
pupa_ieee1275_phandle_t phandle;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
|
||
args.ihandle = ihandle;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*phandlep = args.phandle;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_package_to_path (pupa_ieee1275_phandle_t phandle,
|
||
char *path, pupa_size_t len, pupa_size_t *actual)
|
||
{
|
||
struct instance_to_package_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t phandle;
|
||
char *buf;
|
||
int buflen;
|
||
int actual;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1);
|
||
args.phandle = phandle;
|
||
args.buf = path;
|
||
args.buflen = len;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
if (actual)
|
||
*actual = args.actual;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_instance_to_path (pupa_ieee1275_ihandle_t ihandle,
|
||
char *path, pupa_size_t len,
|
||
pupa_size_t *actual)
|
||
{
|
||
struct instance_to_package_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_ihandle_t ihandle;
|
||
char *buf;
|
||
int buflen;
|
||
int actual;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1);
|
||
args.ihandle = ihandle;
|
||
args.buf = path;
|
||
args.buflen = len;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
if (actual)
|
||
*actual = args.actual;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_write (pupa_ieee1275_ihandle_t ihandle, void *buffer,
|
||
pupa_size_t len, pupa_size_t *actualp)
|
||
{
|
||
struct write_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_ihandle_t ihandle;
|
||
void *buf;
|
||
pupa_size_t len;
|
||
pupa_size_t actual;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "write", 3, 1);
|
||
args.ihandle = ihandle;
|
||
args.buf = buffer;
|
||
args.len = len;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
if (actualp)
|
||
*actualp = args.actual;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_read (pupa_ieee1275_ihandle_t ihandle, void *buffer,
|
||
pupa_size_t len, pupa_size_t *actualp)
|
||
{
|
||
struct write_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_ihandle_t ihandle;
|
||
void *buf;
|
||
pupa_size_t len;
|
||
pupa_size_t actual;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "read", 3, 1);
|
||
args.ihandle = ihandle;
|
||
args.buf = buffer;
|
||
args.len = len;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
if (actualp)
|
||
*actualp = args.actual;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_seek (pupa_ieee1275_ihandle_t ihandle, int pos_hi,
|
||
int pos_lo, int *result)
|
||
{
|
||
struct write_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_ihandle_t ihandle;
|
||
int pos_hi;
|
||
int pos_lo;
|
||
int result;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1);
|
||
args.ihandle = ihandle;
|
||
args.pos_hi = pos_hi;
|
||
args.pos_lo = pos_lo;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
|
||
if (result)
|
||
*result = args.result;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_peer (pupa_ieee1275_phandle_t node,
|
||
pupa_ieee1275_phandle_t *result)
|
||
{
|
||
struct peer_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t node;
|
||
pupa_ieee1275_phandle_t result;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1);
|
||
args.node = node;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*result = args.result;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_child (pupa_ieee1275_phandle_t node,
|
||
pupa_ieee1275_phandle_t *result)
|
||
{
|
||
struct child_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t node;
|
||
pupa_ieee1275_phandle_t result;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "child", 1, 1);
|
||
args.node = node;
|
||
args.result = IEEE1275_PHANDLE_INVALID;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*result = args.result;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_parent (pupa_ieee1275_phandle_t node,
|
||
pupa_ieee1275_phandle_t *result)
|
||
{
|
||
struct parent_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t node;
|
||
pupa_ieee1275_phandle_t result;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1);
|
||
args.node = node;
|
||
args.result = IEEE1275_PHANDLE_INVALID;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*result = args.result;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_exit (void)
|
||
{
|
||
struct exit_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0);
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_open (char *node, pupa_ieee1275_ihandle_t *result)
|
||
{
|
||
struct open_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
char *cstr;
|
||
pupa_ieee1275_ihandle_t result;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "open", 1, 1);
|
||
args.cstr = node;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*result = args.result;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_close (pupa_ieee1275_ihandle_t ihandle)
|
||
{
|
||
struct close_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_ihandle_t ihandle;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "close", 1, 0);
|
||
args.ihandle = ihandle;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_claim (void *p, pupa_size_t size,
|
||
unsigned int align, void **result)
|
||
{
|
||
struct claim_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
void *p;
|
||
pupa_size_t size;
|
||
unsigned int align;
|
||
void *addr;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1);
|
||
args.p = p;
|
||
args.size = size;
|
||
args.align = align;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*result = args.addr;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_set_property (pupa_ieee1275_phandle_t phandle,
|
||
const char *propname, void *buf,
|
||
pupa_size_t size, pupa_size_t *actual)
|
||
{
|
||
struct set_property_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
pupa_ieee1275_phandle_t phandle;
|
||
const char *propname;
|
||
void *buf;
|
||
pupa_size_t size;
|
||
pupa_size_t actual;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1);
|
||
args.size = size;
|
||
args.buf = buf;
|
||
args.propname = propname;
|
||
args.phandle = phandle;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
*actual = args.actual;
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
pupa_ieee1275_set_color (pupa_ieee1275_ihandle_t ihandle,
|
||
int index, int r, int g, int b)
|
||
{
|
||
struct set_color_args {
|
||
struct pupa_ieee1275_common_hdr common;
|
||
char *method;
|
||
pupa_ieee1275_ihandle_t ihandle;
|
||
int index;
|
||
int b;
|
||
int g;
|
||
int r;
|
||
int result;
|
||
} args;
|
||
|
||
INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
|
||
args.method = "color!";
|
||
args.ihandle = ihandle;
|
||
args.index = index;
|
||
args.r = r;
|
||
args.g = g;
|
||
args.b = b;
|
||
|
||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
return -1;
|
||
|
||
return 0;
|
||
}
|