/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Definitions of interfaces that provide services from the secondary
* boot program to its clients (primarily Solaris, krtld, kmdb and their
* successors.) This interface replaces the bootops (BOP) implementation
* as the interface to be called by boot clients.
*
*/
#include <sys/promimpl.h>
#include <sys/prom_plat.h>
#include <sys/bootconf.h>
#include <sys/bootstat.h>
#include <sys/kobj_impl.h>
/*
* Flag to disable the use of real ramdisks (in the OBP - on Sparc) when
* the associated memory is no longer available.
*/
int bootops_obp_ramdisk_disabled = 0;
struct fakeprop {
char *bootname;
char *promname;
} fakeprops[] = {
};
static void
fakelook_init(void)
{
case FAKE_ROOT:
break;
}
fpp++;
}
}
static struct fakeprop *
{
return (fpp);
fpp++;
}
return (NULL);
}
void
bop_init(void)
{
/* fake bootops - it needs to point to non-NULL */
}
/*
* Implementation of the "open" boot service.
*/
/*ARGSUSED*/
int
{
/*
* Only look underneath archive for /etc files
*/
layered = filter_etc ?
if (afs_ih != OBP_BADNODE) {
return (BOOT_SVC_FAIL);
}
}
if (fd == -1)
return (BOOT_SVC_FAIL);
return (fd);
}
static void
spinner(void)
{
static int pos;
static int blks_read;
if ((blks_read++ & 0x3) == 0)
}
/*
* Implementation of the "read" boot service.
*/
int
{
spinner();
}
/*
* Implementation of the "seek" boot service.
*/
int
{
}
/*
* Implementation of the "close" boot service.
*/
int
{
return (0);
}
/*
* Simple temp memory allocator
*
* >PAGESIZE allocations are gotten directly from prom at bighand
* smaller ones are satisfied from littlehand, which does a
* 1 page bighand allocation when it runs out of memory
*/
static int temp_indx;
#if defined(C_OBP)
#endif /* C_OBP */
/*
* temporary memory storage until bop_tmp_freeall is called
* (after the kernel heap is initialized)
*/
{
/*
* OBP allocs 10MB to boot, which is where virthint = 0
* memory was allocated from. Without boot, we allocate
* from BOOTTMPBASE and free when we're ready to take
* the machine from OBP
*/
ret = littlehand;
littlehand += size;
return (ret);
}
}
prom_panic("boot temp overflow");
/* log it for bop_fini() */
prom_panic("out of bop temp space");
return (ret);
}
void
bop_temp_freeall(void)
{
int i;
/*
* We have to call prom_free() with the same args
* as we used in prom_alloc()
*/
for (i = 0; i < NTMPALLOC; i++) {
break;
#if !defined(C_OBP)
#else /* !C_OBP */
#endif /* !C_OBP */
}
}
/*
* Implementation of the "alloc" boot service.
*/
{
}
/*
* Similar to bop_alloc functionality except that
* it will try to breakup into PAGESIZE chunk allocations
* if the original single chunk request failed.
* This routine does not guarantee physical contig
* allocation.
*/
{
return (ret);
/*
* Normal request to prom_alloc has failed.
* We will attempt to satisfy the request by allocating
* smaller chunks resulting in allocation that
* will be virtually contiguous but potentially
* not physically contiguous. There are additional
* requirements before we want to do this:
* 1. virthirt must be PAGESIZE aligned.
* 2. align must not be greater than PAGESIZE
* 3. size request must be at least PAGESIZE
* Otherwise, we will revert back to the original
* bop_alloc behavior i.e. return failure.
*/
return (ret);
/*
* Now we will break up the allocation
* request in smaller chunks that are
* always PAGESIZE aligned.
*/
while (size) {
do {
/*LINTED E_FUNC_SET_NOT_USED*/
PAGESIZE))) {
break;
}
chunksz >>= 1;
/* Can't really happen.. */
prom_panic("bop_alloc_chunk failed");
}
return (ret);
}
/*
* Implementation of the "alloc_virt" boot service
*/
{
}
/*
* Implementation of the "free" boot service.
*/
/*ARGSUSED*/
void
{
}
/*
* Implementation of the "getproplen" boot service.
*/
/*ARGSUSED*/
int
{
char *prop;
} else {
node = chosennode;
}
}
/*
* Implementation of the "getprop" boot service.
*/
/*ARGSUSED*/
int
{
char *prop;
} else {
node = chosennode;
}
}
/*
* Implementation of the "print" boot service.
*/
/*ARGSUSED*/
void
{
}
/*
* Special routine for kmdb
*/
void
{
}
/*
* panic for krtld only
*/
void
bop_panic(const char *s)
{
prom_panic((char *)s);
}
/*
* Implementation of the "mount" boot service.
*
*/
/*ARGSUSED*/
int
bop_mountroot(void)
{
}
/*
* Implementation of the "unmountroot" boot service.
*/
/*ARGSUSED*/
int
bop_unmountroot(void)
{
if (bfs_ih != OBP_BADNODE) {
(void) prom_close(bfs_ih);
}
if (afs_ih != OBP_BADNODE) {
(void) prom_close(afs_ih);
}
return (BOOT_SVC_OK);
}
/*
* Implementation of the "fstat" boot service.
*/
int
{
}
int
{
}
void
bop_free_archive(void)
{
/*
* If the ramdisk will eventually be root, or we weren't
* booted via the archive, then nothing to do here
*/
if (root_is_ramdisk == B_TRUE ||
return;
if (arph == -1 ||
prom_panic("can't free boot archive");
#if !defined(C_OBP)
if (alloc_size == 0)
else {
arbase += alloc_size;
}
}
#else /* !C_OBP */
#endif /* !C_OBP */
}
#if defined(C_OBP)
/*
* Blech. The C proms have a bug when freeing areas that cross
* page sizes, so we have to break up the free into sections
* bounded by the various pagesizes.
*/
void
{
int i;
/*
* Large pages only used when size > 512k
*/
if (size < MMU_PAGESIZE512K ||
return;
}
for (i = 3; i >= 0; i--) {
pgsz = page_get_pagesize(i);
continue;
}
}
#endif /* C_OBP */
/*
* Implementation of the "enter_mon" boot service.
*/
void
bop_enter_mon(void)
{
}
/*
* free elf info allocated by booter
*/
void
bop_free_elf(void)
{
prom_panic("missing elfheader");
}
/* Simple message to indicate that the bootops pointer has been zeroed */
#ifdef DEBUG
int bootops_gone_on = 0;
#define BOOTOPS_GONE() \
if (bootops_gone_on) \
prom_printf("The bootops vec is zeroed now!\n");
#else
#define BOOTOPS_GONE()
#endif /* DEBUG */
void
bop_fini(void)
{
(void) bop_unmountroot();
bop_free_elf();
BOOTOPS_GONE();
}