Mega-patch for OpenFirmware loader support.

- Flesh out ofw_readin routine.
- Add OpenFirmware load and exec routines.
- Make sure memory allocation for the kernel is done correctly.
- Change the way the heap is allocated so as to make it easier to deallocate
  when we hand over.
- Add a command to print memory maps similar to the one for ia64.

With this patch, I can now load and hand over to a kernel on my iMac.  There
are some problems with OpenFirmware routines failing after the hand over that
still need to be addressed.
This commit is contained in:
Benno Rice 2001-10-07 13:22:25 +00:00
parent f2eeb19063
commit cae2c81dc2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84617
13 changed files with 135 additions and 55 deletions

View File

@ -41,48 +41,30 @@ extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];
struct ofw_reg
{
uint32_t base;
uint32_t size;
};
phandle_t chosen;
#define HEAP_SIZE 0x40000
void
init_heap(void)
{
ihandle_t meminstance;
phandle_t chosen, memory;
struct ofw_reg available;
void * aligned_end;
void *base;
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "memory", &meminstance, sizeof(meminstance));
memory = OF_instance_to_package(meminstance);
OF_getprop(memory, "available", &available, sizeof(available));
printf("available.base = 0x%08x\n", available.base);
printf("available.size = 0x%08x\n", available.size);
if (OF_claim((void *)available.base, 0x00040000, 0) ==
(void *) 0xffffffff) {
if ((base = ofw_alloc_heap(HEAP_SIZE)) == (void *)0xffffffff) {
printf("Heap memory claim failed!\n");
OF_enter();
}
aligned_end = (void *)(((int)end + sizeof(int) - 1) &
~(sizeof(int) - 1));
printf("end = 0x%08x, aligned_end = 0x%08x\n", (uint32_t)end,
(uint32_t)aligned_end);
setheap((void *)aligned_end, (void *)(available.base + available.size));
setheap(base, base + (HEAP_SIZE / sizeof(base)));
}
uint32_t
memsize(void)
{
ihandle_t meminstance;
phandle_t chosen, memory;
phandle_t memory;
struct ofw_reg reg;
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "memory", &meminstance, sizeof(meminstance));
memory = OF_instance_to_package(meminstance);
@ -95,7 +77,6 @@ int
main(int (*openfirm)(void *))
{
int i;
phandle_t chosen;
char bootpath[64];
char *ch;
@ -104,6 +85,8 @@ main(int (*openfirm)(void *))
*/
OF_init(openfirm);
chosen = OF_finddevice("/chosen");
/*
* Set up console.
*/
@ -133,7 +116,6 @@ main(int (*openfirm)(void *))
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
printf("Memory: %dKB\n", memsize() / 1024);
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "bootpath", bootpath, 64);
ch = index(bootpath, ':');
*ch = '\0';
@ -183,6 +165,7 @@ main(int (*openfirm)(void *))
archsw.arch_copyin = ofw_copyin;
archsw.arch_copyout = ofw_copyout;
archsw.arch_readin = ofw_readin;
archsw.arch_autoload = ofw_autoload;
interact(); /* doesn't return */
@ -200,3 +183,13 @@ command_halt(int argc, char *argv[])
OF_exit();
return (CMD_OK);
}
COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
int
command_memmap(int argc, char **argv)
{
ofw_memmap();
return (CMD_OK);
}

View File

@ -6,8 +6,9 @@ NOPROFILE= true
INTERNALLIB= true
INTERNALSTATICLIB= true
SRCS= devicename.c ofw_copy.c ofw_module.c ofw_disk.c ofw_net.c \
ofw_console.c ofw_time.c ofw_devsearch.c ofw_reboot.c openfirm.c
SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_devsearch.c \
ofw_disk.c ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \
ofw_time.c openfirm.c
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/

View File

@ -82,6 +82,24 @@ int ofw_devicetype(char *);
extern int ofw_boot(void);
extern int ofw_autoload(void);
void ofw_memmap(void);
void *ofw_alloc_heap(unsigned int);
void ofw_release_heap(void);
struct preloaded_file;
struct file_format;
int ofw_elf_loadfile(char *, vm_offset_t, struct preloaded_file **);
int ofw_elf_exec(struct preloaded_file *);
extern struct file_format ofw_elf;
extern void reboot(void);
extern int main(int (*openfirm)(void *));
struct ofw_reg
{
uint32_t base;
uint32_t size;
};

View File

@ -34,6 +34,8 @@
#include "libofw.h"
#define READIN_BUF (4 * 1024)
ssize_t
ofw_copyin(const void *src, vm_offset_t dest, const size_t len)
{
@ -51,7 +53,32 @@ ofw_copyout(const vm_offset_t src, void *dest, const size_t len)
ssize_t
ofw_readin(const int fd, vm_offset_t dest, const size_t len)
{
return(read(fd, (void *) dest, len));
}
void *buf;
size_t resid, chunk, get;
ssize_t got;
vm_offset_t p;
p = dest;
chunk = min(READIN_BUF, len);
buf = malloc(chunk);
if (buf == NULL) {
printf("ofw_readin: buf malloc failed\n");
return(0);
}
for (resid = len; resid > 0; resid -= got, p += got) {
get = min(chunk, resid);
got = read(fd, buf, get);
if (got <= 0) {
printf("ofw_readin: read failed\n");
break;
}
bcopy(buf, (void *)p, got);
}
free(buf);
return(len - resid);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Benno Rice
* Copyright (c) 2000-2001 Benno Rice
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -45,8 +45,8 @@
static int ofwn_probe(struct netif *, void *);
static int ofwn_match(struct netif *, void *);
static void ofwn_init(struct iodesc *, void *);
static int ofwn_get(struct iodesc *, void *, int, time_t);
static int ofwn_put(struct iodesc *, void *, int);
static int ofwn_get(struct iodesc *, void *, size_t, time_t);
static int ofwn_put(struct iodesc *, void *, size_t);
static void ofwn_end(struct netif *);
extern struct netif_stats ofwn_stats[];
@ -89,7 +89,7 @@ ofwn_probe(struct netif *nif, void *machdep_hint)
}
static int
ofwn_put(struct iodesc *desc, void *pkt, int len)
ofwn_put(struct iodesc *desc, void *pkt, size_t len)
{
struct ether_header *eh;
size_t sendlen;
@ -126,7 +126,7 @@ ofwn_put(struct iodesc *desc, void *pkt, int len)
}
static int
ofwn_get(struct iodesc *desc, void *pkt, int len, time_t timeout)
ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
time_t t;
int length;
@ -196,8 +196,10 @@ ofwn_init(struct iodesc *desc, void *machdep_hint)
printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));
if ((netinstance = OF_open(path)) == -1)
if ((netinstance = OF_open(path)) == -1) {
printf("Could not open network device.\n");
goto punt;
}
#if defined(NETIF_DEBUG)
printf("ofwn_init: OpenFirmware instance handle: %08x\n", netinstance);
@ -218,7 +220,7 @@ ofwn_init(struct iodesc *desc, void *machdep_hint)
punt:
printf("\n");
printf("Could not boot from %s.\n", path);
OF_exit();
OF_enter();
}
static void

View File

@ -67,12 +67,25 @@ static int (*openfirmware)(void *);
static ihandle_t stdin;
static ihandle_t stdout;
static ihandle_t mmu;
static ihandle_t memory;
/* Initialiaser */
void
OF_init(int (*openfirm)(void *))
{
phandle_t chosen;
openfirmware = openfirm;
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "memory", &memory, sizeof(memory));
if (memory == 0)
panic("failed to get memory ihandle");
OF_getprop(chosen, "mmu", &mmu, sizeof(mmu));
if (mmu == 0)
panic("failed to get mmu ihandle");
}
/*
@ -706,7 +719,7 @@ OF_exit()
}
/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */
#ifdef __notyet__
#if 0
void
OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
{
@ -739,9 +752,9 @@ OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
/*
* This is a REALLY dirty hack till the firmware gets this going
*/
#if 0
OF_release(virt, size);
#endif
if (size > 0)
OF_release(virt, size);
entry(0, 0, openfirmware, arg, len);
}
#endif

View File

@ -67,6 +67,8 @@
typedef int ihandle_t;
typedef int phandle_t;
extern phandle_t chosen;
/*
* This isn't actually an OpenFirmware function, but it seemed like the right
* place for it to go.

View File

@ -11,6 +11,10 @@ INSTALLFLAGS= -b
LOADER_DISK_SUPPORT?= yes
LOADER_NET_SUPPORT?= yes
# load address
RELOC?= 0x6c0000
CFLAGS+= -DRELOC=${RELOC}
# architecture-specific loader code
SRCS= conf.c
@ -45,7 +49,7 @@ CFLAGS+= -I${.CURDIR}/../../.. -I.
CLEANFILES+= vers.c vers.o ${BASE}.list ${BASE}.bin ${BASE}.sym ${BASE}.help
CFLAGS+= -Wall
LDFLAGS= -nostdlib -static -Ttext 6c0000
LDFLAGS= -nostdlib -static -Ttext ${RELOC}
# OpenFirmware standalone support library
LIBOFW= ${.OBJDIR}/../../ofw/libofw/libofw.a

View File

@ -27,7 +27,9 @@
*/
#include <stand.h>
#include "bootstrap.h"
#include "libofw.h"
#include "openfirm.h"
#if defined(LOADER_NET_SUPPORT)
#include "dev_net.h"
@ -82,10 +84,9 @@ struct netif_driver *netif_drivers[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct file_format powerpc_elf;
struct file_format *file_formats[] = {
/* &powerpc_elf,*/
&ofw_elf,
NULL
};
@ -101,3 +102,8 @@ struct console *consoles[] = {
&ofwconsole,
NULL
};
/*
* reloc - our load address
*/
vm_offset_t reloc = RELOC;

View File

@ -37,8 +37,6 @@
void startup(void *, int, int (*)(void *), char *, int);
static int stack[8192/4 + 4];
#ifdef XCOFF_GLUE
asm("
.text
@ -48,7 +46,11 @@ asm("
");
#endif
asm("
__asm("
.data
stack:
.space 16388
.text
.globl _start
_start:

View File

@ -11,6 +11,10 @@ INSTALLFLAGS= -b
LOADER_DISK_SUPPORT?= yes
LOADER_NET_SUPPORT?= yes
# load address
RELOC?= 0x6c0000
CFLAGS+= -DRELOC=${RELOC}
# architecture-specific loader code
SRCS= conf.c
@ -45,7 +49,7 @@ CFLAGS+= -I${.CURDIR}/../../.. -I.
CLEANFILES+= vers.c vers.o ${BASE}.list ${BASE}.bin ${BASE}.sym ${BASE}.help
CFLAGS+= -Wall
LDFLAGS= -nostdlib -static -Ttext 6c0000
LDFLAGS= -nostdlib -static -Ttext ${RELOC}
# OpenFirmware standalone support library
LIBOFW= ${.OBJDIR}/../../ofw/libofw/libofw.a

View File

@ -27,7 +27,9 @@
*/
#include <stand.h>
#include "bootstrap.h"
#include "libofw.h"
#include "openfirm.h"
#if defined(LOADER_NET_SUPPORT)
#include "dev_net.h"
@ -82,10 +84,9 @@ struct netif_driver *netif_drivers[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct file_format powerpc_elf;
struct file_format *file_formats[] = {
/* &powerpc_elf,*/
&ofw_elf,
NULL
};
@ -101,3 +102,8 @@ struct console *consoles[] = {
&ofwconsole,
NULL
};
/*
* reloc - our load address
*/
vm_offset_t reloc = RELOC;

View File

@ -37,8 +37,6 @@
void startup(void *, int, int (*)(void *), char *, int);
static int stack[8192/4 + 4];
#ifdef XCOFF_GLUE
asm("
.text
@ -48,7 +46,11 @@ asm("
");
#endif
asm("
__asm("
.data
stack:
.space 16388
.text
.globl _start
_start: