blob: 21d140a7eff2bdd9ee760cc68944030ff3d2a0f0 [file] [log] [blame]
Kevin O'Connor0c3068d2008-12-21 17:51:36 -05001// PNP BIOS calls
2//
3// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
4//
5// This file may be distributed under the terms of the GNU GPLv3 license.
6
7#include "util.h" // checksum
8#include "config.h" // BUILD_BIOS_ADDR
9#include "farptr.h" // SET_FARVAR
10
11struct pnpheader {
12 u32 signature;
13 u8 version;
14 u8 length;
15 u16 control;
16 u8 checksum;
17 u32 eventloc;
18 u16 real_ip;
19 u16 real_cs;
20 u16 prot_ip;
21 u32 prot_base;
22 u32 oemid;
23 u16 real_ds;
24 u32 prot_database;
25} PACKED;
26
27extern struct pnpheader PNPHEADER;
28extern const char pnp_string[];
29
Kevin O'Connor4a754b32008-12-28 21:37:27 -050030#if CONFIG_PNPBIOS
31struct pnpheader PNPHEADER __aligned(16) VAR16 = {
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050032 .signature = PNP_SIGNATURE,
33 .version = 0x10,
34 .length = sizeof(PNPHEADER),
35 .real_cs = SEG_BIOS,
36 .prot_base = BUILD_BIOS_ADDR,
37 .real_ds = SEG_BIOS,
38 .prot_database = BUILD_BIOS_ADDR,
39};
Kevin O'Connor4a754b32008-12-28 21:37:27 -050040#else
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050041// We need a copy of this string in the 0xf000 segment, but we are not
42// actually a PnP BIOS, so make sure it is *not* aligned, so OSes will
43// not see it if they scan.
Kevin O'Connor4a754b32008-12-28 21:37:27 -050044const char pnp_string[] __aligned(2) VAR16 = " $PnP";
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050045#endif
46
47#define FUNCTION_NOT_SUPPORTED 0x82
48
49// BBS - Get Version and Installation Check
50static u16
51handle_pnp60(u16 *args)
52{
53 u16 version_ptr = args[1];
54 u16 version_seg = args[2];
55 SET_FARVAR(version_seg, *(u16*)(version_ptr+0), 0x0101);
56 return 0;
57}
58
59static u16
60handle_pnpXX(u16 *args)
61{
62 return FUNCTION_NOT_SUPPORTED;
63}
64
65u16 VISIBLE16
66handle_pnp(u16 *args)
67{
68 if (! CONFIG_PNPBIOS)
69 return FUNCTION_NOT_SUPPORTED;
70
71 u16 arg1 = args[0];
72 dprintf(DEBUG_HDL_pnp, "pnp call arg1=%x\n", arg1);
73
74 switch (arg1) {
75 case 0x60: return handle_pnp60(args);
76 default: return handle_pnpXX(args);
77 }
78}
79
80u16
81get_pnp_offset()
82{
83 if (! CONFIG_PNPBIOS)
84 return (u32)pnp_string + 1 - BUILD_BIOS_ADDR;
85 return (u32)&PNPHEADER - BUILD_BIOS_ADDR;
86}
87
88// romlayout.S
89extern void entry_pnp_real();
90extern void entry_pnp_prot();
91
92void
93pnp_setup()
94{
95 if (! CONFIG_PNPBIOS)
96 return;
97
98 dprintf(3, "init PNPBIOS table\n");
99
100 PNPHEADER.real_ip = (u32)entry_pnp_real - BUILD_BIOS_ADDR;
101 PNPHEADER.prot_ip = (u32)entry_pnp_prot - BUILD_BIOS_ADDR;
102 PNPHEADER.checksum = -checksum((u8*)&PNPHEADER, sizeof(PNPHEADER));
103}