/* $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);
}