blob: fddcc816603891e729669a25ef254d6dd3f7c721 [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//
Kevin O'Connorb1b7c2a2009-01-15 20:52:58 -05005// This file may be distributed under the terms of the GNU LGPLv3 license.
Kevin O'Connor0c3068d2008-12-21 17:51:36 -05006
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;
Kevin O'Connor9e91c7b2009-01-17 02:30:21 -050028extern char pnp_string[];
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050029
Kevin O'Connor4a754b32008-12-28 21:37:27 -050030#if CONFIG_PNPBIOS
Kevin O'Connor89a2f962013-02-18 23:36:03 -050031struct pnpheader PNPHEADER __aligned(16) VARFSEG = {
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'Connor89a2f962013-02-18 23:36:03 -050044char pnp_string[] __aligned(2) VARFSEG = " $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
Kevin O'Connor1ca05b02010-01-03 17:43:37 -050081get_pnp_offset(void)
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050082{
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
Kevin O'Connor1ca05b02010-01-03 17:43:37 -050089extern void entry_pnp_real(void);
90extern void entry_pnp_prot(void);
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050091
92void
Kevin O'Connord83c87b2013-01-21 01:14:12 -050093pnp_init(void)
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050094{
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;
Kevin O'Connor523e5a92009-07-04 13:46:33 -0400102 PNPHEADER.checksum -= checksum(&PNPHEADER, sizeof(PNPHEADER));
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500103}