/* * cmos.c -- using parts of pwdigit.c by Jan Stohner * A simple interface for accessing cmos/nvram * * Linux programs using outb/inb requires the gcc -O2 option * * Multi-platform support: (modify defines) * % Linux using /dev/port * % Linux using inb and outb * % BSD using inb and outb, accessing /dev/io * % BSD using inb and outb and i386_set_ioperm * % msdos (turbo c) using inp/outp */ /*#if defined ( CMOS_DOT_C )*/ /* * cmos.c has allready been included in the source. stay idle. * I'm alive... again! --pointless duke quote */ /*#else*/ /*#define CMOS_DOT_C*/ /* * fist include; define all cmos functions. * Trust the source, Luke! --pointless starwars quote */ #include #include /*#define CMOS_LINUX_DEVPORT #define CMOS_LINUX_OUTBINB #define CMOS_BSD_OUTBINB #define CMOS_BSD_OUTBINB_IOPERM #define CMOS_DOS_OUTPINP*/ #define CMOS_DOS_OUTPINP #if defined( CMOS_LINUX_DEVPORT ) FILE *cmos_fd; #elif defined( CMOS_LINUX_OUTBINB ) #include #elif defined( CMOS_BSD_OUTBINB ) //#include is also needed by BSD alpha #include FILE *cmos_fd; #elif defined( CMOS_BSD_OUTBINB_IOPERM ) //#include is also needed by BSD alpha #include u_long cmos_iop[32]; u_long cmos_iop_backup[32]; #elif defined( CMOS_DOS_OUTPINP ) #include #include #endif char cmos_inited = 0; typedef unsigned char BYTE; /* void cmos_init() -- requests I/O permission to access cmos/nvram coid cmos_finish() -- resets I/O permission unsigned char cmos_byte(char offs) -- returns (byte) offs unsigned int cmos_byte(char offs) -- returns (word) offs char* cmos_copy (char* str, int offs, int len) -- copies len chars from cmosffs to str, returns str -- str must be of size len+1 or greater */ void cmos_init() { #if defined( CMOS_LINUX_DEVPORT ) cmos_fd = fopen("/dev/port", "w+b"); if(cmos_fd==NULL) { perror("fopen /dev/port failed"); exit(1); } #elif defined( CMOS_LINUX_OUTBINB ) if(setuid(0)==-1) { perror("setuid 0 (needed by ioperm) failed"); exit(1); } ioperm(0x70,2,1); #elif defined( CMOS_BSD_OUTBINB ) cmos_fd = fopen("/dev/io", "r"); if(cmos_fd==NULL){ perror("fopen /dev/io failed"); exit(1); } #elif defined( CMOS_BSD_OUTBINB_IOPERM ) i386_get_ioperm(cmos_iop); bcopy(cmos_iop_backup,cmos_iop,32*sizeof(u_long)); cmos_iop[3]=0; cmos_iop[4]=0; /* here we actually would have to set 16th and 17th bites to 0 but I clen tons, to avoid bites counting, etc */ if(i386_set_ioperm(cmos_iop)!=0){ perror("i386_set_ioperm failed"); exit(1); } #elif defined( CMOS_DOS_OUTPINP ) #endif cmos_inited = 1; } void cmos_finish() { #if defined( CMOS_LINUX_DEVPORT ) fclose(cmos_fd); #elif defined( CMOS_LINUX_OUTBINB ) ioperm(0x70,2,0); #elif defined( CMOS_BSD_OUTBINB ) fclose(cmos_fd); #elif defined( CMOS_BSD_OUTBINB_IOPERM ) i386_set_ioperm(cmos_iop_backup); #elif defined( CMOS_DOS_OUTPINP ) #endif cmos_inited = 0; } unsigned char cmos_byte(char offset) { unsigned char buf,a; if (cmos_inited == 0) cmos_init(); #if defined( CMOS_LINUX_DEVPORT ) fseek(cmos_fd, (long) 0x70, SEEK_SET); buf = offset; fwrite(&buf, 1, 1, cmos_fd); fread(&a, 1, 1, cmos_fd); #elif defined( CMOS_LINUX_OUTBINB ) outb(offset,0x70); a = inb(0x71); #elif defined( CMOS_BSD_OUTBINB ) outb(0x70,offset); a = inb(0x71); #elif defined( CMOS_BSD_OUTBINB_IOPERM ) outb(0x70,offset); a = inb(0x71); #elif defined( CMOS_DOS_OUTPINP ) outp(0x70,offset); a = inp(0x71); #endif return(a); } unsigned int cmos_word(char offs) { unsigned char a,b; a = cmos_byte(offs); b = cmos_byte(offs+1); return((unsigned int)a+256*(unsigned int)b); } char* cmos_copy (char* str, int offset, int len) { /* * cmos_copy copies len characters from cmos offset * str must be of size len+1 */ int cnt; for (cnt=0; cnt