2 #include "../port/lib.h"
8 #define VFLAG(...) if(vflag) print(__VA_ARGS__)
10 #define UPTR2INT(p) ((uintptr)(p))
12 #define l16get(p) (((p)[1]<<8)|(p)[0])
13 #define l32get(p) (((u32int)l16get(p+2)<<16)|l16get(p))
17 typedef struct BIOS32sdh { /* BIOS32 Service Directory Header */
18 u8int signature[4]; /* "_32_" */
19 u8int physaddr[4]; /* physical address of entry point */
21 u8int length; /* of header in paragraphs */
26 typedef struct BIOS32si { /* BIOS32 Service Interface */
27 u8int* base; /* base address of service */
28 int length; /* length of service */
29 u32int offset; /* service entry-point from base */
31 u16int ptr[3]; /* far pointer m16:32 */
34 static Lock bios32lock;
35 static u16int bios32ptr[3];
36 static void* bios32entry;
39 bios32ci(BIOS32si* si, BIOS32ci* ci)
44 r = bios32call(ci, si->ptr);
56 VFLAG("bios32link\n");
57 if((sdh = sigsearch("_32_")) == nil)
59 if(checksum(sdh, sizeof(BIOS32sdh)))
61 VFLAG("sdh @ %#p, entry %#ux\n", sdh, l32get(sdh->physaddr));
63 bios32entry = vmap(l32get(sdh->physaddr), 4096+1);
64 VFLAG("entry @ %#p\n", bios32entry);
65 ptr = UPTR2INT(bios32entry);
66 bios32ptr[0] = ptr & 0xffff;
67 bios32ptr[1] = (ptr>>16) & 0xffff;
69 VFLAG("bios32link: ptr %ux %ux %ux\n",
70 bios32ptr[0], bios32ptr[1], bios32ptr[2]);
76 BIOS32close(BIOS32si* si)
78 vunmap(si->base, si->length);
90 if(bios32ptr[2] == 0 && bios32locate() < 0){
95 VFLAG("bios32si: %s\n", id);
96 memset(&ci, 0, sizeof(BIOS32ci));
97 ci.eax = (id[3]<<24|(id[2]<<16)|(id[1]<<8)|id[0]);
99 bios32call(&ci, bios32ptr);
102 VFLAG("bios32si: eax %ux\n", ci.eax);
105 VFLAG("bios32si: base %#ux length %#ux offset %#ux\n",
106 ci.ebx, ci.ecx, ci.edx);
108 if((si = malloc(sizeof(BIOS32si))) == nil)
110 if((si->base = vmap(ci.ebx, ci.ecx)) == nil){
116 ptr = UPTR2INT(si->base)+ci.edx;
117 si->ptr[0] = ptr & 0xffff;
118 si->ptr[1] = (ptr>>16) & 0xffff;
120 VFLAG("bios32si: eax entry %ux\n", ptr);