2004-03-29 Marco Gerards <metgerards@student.han.nl>

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.
This commit is contained in:
marco_g 2004-03-28 21:52:02 +00:00
parent 8c8cc20511
commit e56cdf2111
25 changed files with 2768 additions and 22 deletions

View file

@ -0,0 +1,148 @@
/* cmain.c - Startup code for the PowerPC. */
/*
* 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 <alloca.h>
#include <stdint.h>
#include "pupa/machine/ieee1275.h"
#include "pupa/kernel.h"
struct module_info
{
uint32_t start;
uint32_t end;
};
#define roundup(a, s) (((a) + ((s) - 1)) & ~((s) - 1))
/* OpenFirmware entry point passed to us from the real bootloader. */
intptr_t (*pupa_ieee1275_entry_fn) (void *);
/* Return a help text for this architecture. */
const char *
help_arch (void)
{
/* No special information. */
return "";
}
/* Setup the argument vector and pass control over to the main
function. */
void
cmain (uint32_t firmware_entry)
{
char **argv, args[256];
pupa_ieee1275_phandle_t chosen;
int argc = 0, actual;
long batl, batu;
pupa_ieee1275_entry_fn = (intptr_t (*)(void *)) firmware_entry;
/* Initialize BAT registers to unmapped to not generate overlapping
mappings below. */
asm volatile ("mtibatu 0,%0" :: "r"(0));
asm volatile ("mtibatu 1,%0" :: "r"(0));
asm volatile ("mtibatu 2,%0" :: "r"(0));
asm volatile ("mtibatu 3,%0" :: "r"(0));
asm volatile ("mtdbatu 0,%0" :: "r"(0));
asm volatile ("mtdbatu 1,%0" :: "r"(0));
asm volatile ("mtdbatu 2,%0" :: "r"(0));
asm volatile ("mtdbatu 3,%0" :: "r"(0));
/* Set up initial BAT table to only map the lowest 256 MB area. */
batl = 0x00000000 | 0x10 | 0x02;
batu = 0x00000000 | 0x1ffc | 0x02;
/* IBAT0 used for initial 256 MB segment */
asm volatile ("mtibatl 3,%0; mtibatu 3,%1" :: "r" (batl), "r" (batu));
/* DBAT0 used similar */
asm volatile ("mtdbatl 3,%0; mtdbatu 3,%1" :: "r" (batl), "r" (batu));
asm ("isync");
/* If any argument was passed to the kernel (us), they are
put in the bootargs property of /chosen. The string can
be null (just the nul-character), so check that the size
is actually greater than one. */
pupa_ieee1275_finddevice ("/chosen", &chosen);
if (pupa_ieee1275_get_property (chosen, "bootargs", args,
sizeof args, &actual) == 0
&& actual > 1)
{
/* A command line was passed. */
char *str = args;
int nr = 1;
/* First time around we count the number of arguments. */
argc = 2;
while (*str && *str == ' ')
str++;
while (*str)
if (*(str++) == ' ')
{
while (*str && *str == ' ')
str++;
if (*str)
argc++;
}
argv = alloca (sizeof (char *) * (argc + 2));
/* The bootargs property does not contain the program
name, just the arguments. */
argv[0] = "pupa";
/* Second time around we fill in the argv. */
str = args;
while (*str && *str == ' ')
str++;
argv[nr++] = str;
while (*str)
{
if (*str == ' ')
{
*(str++) = '\0';
while (*str && *str == ' ')
str++;
if (*str)
argv[nr++] = str;
}
else
str++;
}
argv[nr] = 0;
}
else
{
argv = alloca (sizeof (char *) * 2);
argv[0] = "pupa";
argv[1] = 0;
argc = 1;
}
/* Now invoke the main function. */
/* XXX: pupa_main does not parse arguments yet. */
pupa_main ();
/* Never reached. */
}

View file

@ -0,0 +1,55 @@
/* crt0.S - Startup code for the PowerPC. */
/*
* 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.
*/
.section ".note"
.align 2
.note_section_header:
.long 8
.long 24
.long 0x1275
.string "PowerPC"
.note_descriptor:
.long 0x0 /* real-mode */
.long 0xffffffff /* real-base */
.long 0xffffffff /* real-size */
.long 0xffffffff /* virt-base */
.long 0xffffffff /* virt-size */
.long 0x00030000 /* load-base */
.text
.align 2
.globl _start
_start:
lis 1, init_stack@ha
la 1, init_stack@l(1)
addi 1, 1, -32
li 2, 0
li 13, 0
mr 3, 5
bl cmain
1: b 1b
.section ".bss"
.lcomm _ppc_init_stack, 4096*2, 16
init_stack:

View file

@ -0,0 +1,475 @@
/* 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;
}