blob: 95ce21f8f2b5bf9a24f03f75274f3b479d3364d7 [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
Kevin O'Connor0c3068d2008-12-21 17:51:36 -05007#include "config.h" // BUILD_BIOS_ADDR
8#include "farptr.h" // SET_FARVAR
Kevin O'Connor2d2fa312013-09-14 21:55:26 -04009#include "output.h" // dprintf
Kevin O'Connor4f790aa2013-09-14 23:04:08 -040010#include "std/pnpbios.h" // PNP_SIGNATURE
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040011#include "string.h" // checksum
Kevin O'Connor2d2fa312013-09-14 21:55:26 -040012#include "util.h" // pnp_init
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050013
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050014extern struct pnpheader PNPHEADER;
Kevin O'Connor9e91c7b2009-01-17 02:30:21 -050015extern char pnp_string[];
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050016
Kevin O'Connor4a754b32008-12-28 21:37:27 -050017#if CONFIG_PNPBIOS
Kevin O'Connor89a2f962013-02-18 23:36:03 -050018struct pnpheader PNPHEADER __aligned(16) VARFSEG = {
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050019 .signature = PNP_SIGNATURE,
20 .version = 0x10,
21 .length = sizeof(PNPHEADER),
22 .real_cs = SEG_BIOS,
23 .prot_base = BUILD_BIOS_ADDR,
24 .real_ds = SEG_BIOS,
25 .prot_database = BUILD_BIOS_ADDR,
26};
Kevin O'Connor4a754b32008-12-28 21:37:27 -050027#else
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050028// We need a copy of this string in the 0xf000 segment, but we are not
29// actually a PnP BIOS, so make sure it is *not* aligned, so OSes will
30// not see it if they scan.
Kevin O'Connor89a2f962013-02-18 23:36:03 -050031char pnp_string[] __aligned(2) VARFSEG = " $PnP";
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050032#endif
33
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050034// BBS - Get Version and Installation Check
35static u16
36handle_pnp60(u16 *args)
37{
38 u16 version_ptr = args[1];
39 u16 version_seg = args[2];
40 SET_FARVAR(version_seg, *(u16*)(version_ptr+0), 0x0101);
41 return 0;
42}
43
44static u16
45handle_pnpXX(u16 *args)
46{
47 return FUNCTION_NOT_SUPPORTED;
48}
49
50u16 VISIBLE16
51handle_pnp(u16 *args)
52{
53 if (! CONFIG_PNPBIOS)
54 return FUNCTION_NOT_SUPPORTED;
55
56 u16 arg1 = args[0];
57 dprintf(DEBUG_HDL_pnp, "pnp call arg1=%x\n", arg1);
58
59 switch (arg1) {
60 case 0x60: return handle_pnp60(args);
61 default: return handle_pnpXX(args);
62 }
63}
64
65u16
Kevin O'Connor1ca05b02010-01-03 17:43:37 -050066get_pnp_offset(void)
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050067{
68 if (! CONFIG_PNPBIOS)
69 return (u32)pnp_string + 1 - BUILD_BIOS_ADDR;
70 return (u32)&PNPHEADER - BUILD_BIOS_ADDR;
71}
72
73// romlayout.S
Kevin O'Connor1ca05b02010-01-03 17:43:37 -050074extern void entry_pnp_real(void);
75extern void entry_pnp_prot(void);
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050076
77void
Kevin O'Connord83c87b2013-01-21 01:14:12 -050078pnp_init(void)
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050079{
80 if (! CONFIG_PNPBIOS)
81 return;
82
83 dprintf(3, "init PNPBIOS table\n");
84
85 PNPHEADER.real_ip = (u32)entry_pnp_real - BUILD_BIOS_ADDR;
86 PNPHEADER.prot_ip = (u32)entry_pnp_prot - BUILD_BIOS_ADDR;
Kevin O'Connor523e5a92009-07-04 13:46:33 -040087 PNPHEADER.checksum -= checksum(&PNPHEADER, sizeof(PNPHEADER));
Kevin O'Connor0c3068d2008-12-21 17:51:36 -050088}