Newer
Older
ubix / src / sys / kernel / bios32.c
@hypno hypno on 6 Jul 2002 1 KB *** empty log message ***
/* $Id$ */ 

/*
 * Copyright (c) 2002 Johnny Zackrisson. All rights reserved.
 * 
 * You are free to do whatever you want with this code.
 */

#include <drivers/video.h>
#include <ubixos/bios32.h>

/* These are physical addresses */
#define BIOS32_START 	0xe0000
#define BIOS32_END	0xffff0	 

struct bios32_entry_t bios32_entry;

void
bios32_probe() 
{
	struct bios32_t *bios32 = (struct bios32_t *)BIOS32_START;
	/*
	unsigned char *cp;
	int i;
	*/

	/*
 	 * XXX: phys2vir I/O mapping?
         */
	for (; bios32 <= (struct bios32_t *)BIOS32_END; ++bios32) {
		if ((bios32->sign == BIOS32_MAKESIG('_','3','2','_')) && 
		    (bios32->len == 1) && (bios32->rev == 0)) { 
			
			/* XXX XXX: Checksum calculation here! */
			/* 
			cp = (unsigned char *)bios32;
			for (i=0; i<16; i++) 
				kprintf("%d ",cp[i]);
			if (bios32->cksum != 0) 
				continue;
			*/

                	kprintf("BIOS32 Service Directory found at 0x%p\n"
				"BIOS32 Entry: 0x%x Revision: %d Length: %d\n"
				, bios32, bios32->entry, bios32->rev
				, bios32->len); 
                        	return;
		} 

		if (bios32->entry != 0) {
			bios32_entry.addr = bios32->entry;
			bios32_entry.sel = KERNEL_CS;
		}
	}
}

int
bios32_service(unsigned long service, struct bios32_entry_t *e) 
{
	/* XXX: BSD types */
	unsigned long addr, len, entry;	
	unsigned char ret;

	__asm__ __volatile__("lcall *(%%edi)"
		: "=a" (ret), "=b" (addr), "=c" (len), "=d" (entry)
		: "0" (service), "1" (0), "D" (&bios32_entry)
	);

        /* XXX: care about 0x81? */
	if ((ret & 0xff) != 0) 
		return(-1); 
	else {
		e->addr = (addr + entry);
		e->sel = KERNEL_CS;
	}

	return(0);
}