Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Mar 2002 20:11:26 -0600
From:      "Seth Henry" <jshamlet@hotmail.com>
To:        freebsd-questions@freebsd.org
Subject:   Need help porting linux code to FreeBSD
Message-ID:  <F164S2kUfbGRJvoYAMx00010cb1@hotmail.com>

next in thread | raw e-mail | index | archive | help
Hello all,
This is my first time doing any real "hardware" coding, but I have written a 
lot of C code for other things.

I am working on turning a Compaq IA-1 internet appliance into a useable 
X-terminal. A great deal of work has gone into porting Linux to this device, 
but less so on the FreeBSD side. Since I prefer FreeBSD, I thought I would 
tackle customizing it to fit the hardware. The IA-1 has a number of 
functions that are available through the VIA chipset by way of setting bits 
in the chipset registers. A linux program exists to poke and prod this 
register into turning these functions on and off (in this case, the panel 
lights and the display backlight). It uses the io.h library, and calls outl, 
outb, and inl.

I would like to rewrite this code so that I can embed it in things like the 
screen blanker (since the LCD doesn't respond to DPMS), and other user-land 
programs to control the lights. (the power light alone would be nice).

So, where would I need to start looking to translate this code from Linux to 
FreeBSD? In particular, where can I dig up information on the equivalent to 
io.h (or is there an io.h in FreeBSD?) I haven't installed all of the source 
trees, but I did install the headers. However, I haven't found this file.

Any help would be appreciated, though I would like to learn how to do this. 
The original source code is included below.

Thanks,
Seth Henry

<ia1led.c>
#include <asm/io.h>

// Example User Space program to Set and Clear the IA-1 front LEDs and the 
Backlight
//
// Copyright (c)2002 Neptune.
//
// Thanks to Robert Rose and Steven M. Doyle for their pioneering iopener
// work and for posting the details so I could figure it out the IA-1.
//
// This code has been released under GPL.  See http://www.gnu.org for more
// information.
//
// Notes: Must compile with optimization ie: gcc -O -o ia1led ia1led.c
//        Must run as root
//        Probably will work with non-standard IA-1 bios (ACPI I/O Base != 
0xEE00)


#define PCI_CFG_ADDR  0xCF8
#define PCI_CFG_DATA  0xCFC
#define PCI_CMD(busn, devn, funcn, regn)   (0x80000000 | (busn << 16) | 
(devn << 11) | (funcn << 8) | (regn << 2))


// Prototypes
void tog_bit(int bit);
void set_bit(int bit);
void clr_bit(int bit);

// Globals
unsigned int GPO_ADDR = 0xEE4C; // VT82C686 Gen Purpose Output port address 
- Initialized to expected value



int main(int argc, char **argv)
{
unsigned long i;
char *s;

  if(argc!=2)
   {
    printf("\nUsage: %s nnnn...\n\n",argv[0]);
    printf(" where nnnn consists of one or more of the following chars:\n");
    printf("   0 - Turn left LED off\n");
    printf("   1 - Turn left LED on\n");
    printf("   2 - Turn center LED off\n");
    printf("   3 - Turn center LED on\n");
    printf("   4 - Turn right LED off\n");
    printf("   5 - Turn right LED on\n");
    printf("   6 - Turn backlight off\n");
    printf("   7 - Turn backlight on\n\n");
    exit(0);
   }


  iopl(3); // Give Access to all ports - Be careful....


  // Check that the VIA VT82C686 PCI cfg is responding
   outb (0x01, PCI_CFG_ADDR+3);
   i = inl (PCI_CFG_ADDR);
   outl (0x80000000, PCI_CFG_ADDR);
   if (inl (PCI_CFG_ADDR) != 0x80000000)
    {
     printf("PCI config test: Fail\n");
     exit(1);
    }
   outl (i, 0xCF8);


  // Check the vendor ID and Device
   outl(PCI_CMD(0x0,0x7,0x4,0x0),PCI_CFG_ADDR);
   i = inl(PCI_CFG_DATA);

   if(i != 0x30571106)
    {
     printf("Error: Incorrect Vendor and Device IDs found:\n");
     printf("Found Vendor ID = %04x, Device = %04x\n",i&0x0FFFF, i>>16);
     exit(2);
    }


  // Get the Power Management I/O Base Add Offset (Reg Offset 48)
   outl(PCI_CMD(0x0,0x7,0x4,0x12),PCI_CFG_ADDR);
   i = inl(PCI_CFG_DATA) & 0x0FF80; // Clear bits 0-6


   if(i!=0xEE00)
    printf("Unusual I/O Base Offset found = %08x\n",i);


   GPO_ADDR = i | 0x4C;  // Set the General Purpose Output port address


  // Scan the arg string and take action
  for(s=argv[1];*s!='\0';s++)
   {
    switch(*s)
     {
      case '0': set_bit(0); break;
      case '1': clr_bit(0); break; // Left LED (on/off) is active low

      case '2': clr_bit(8); break;
      case '3': set_bit(8); break;

      case '4': clr_bit(14); break;
      case '5': set_bit(14); break;

      case '6': clr_bit(7); break;
      case '7': set_bit(7); break;

      default:  break;  // Ignore everything else
     }
   }


  exit(0); // Success
}


// Bit Toggle, Set and Clear routines

void tog_bit(int bit)
{
unsigned long i;

   i = inl(GPO_ADDR);
   i = i ^ (0x1 << bit);  // Toggle the bit
   outl(i,GPO_ADDR);
}

void set_bit(int bit)
{
unsigned long i;

   i = inl(GPO_ADDR);
   i = i | (0x1 << bit);  // Set the bit
   outl(i,GPO_ADDR);
}

void clr_bit(int bit)
{
unsigned long i;

   i = inl(GPO_ADDR);
   i = i & ~(0x1 << bit);  // Clear the bit
   outl(i,GPO_ADDR);
}


_________________________________________________________________
Join the world’s largest e-mail service with MSN Hotmail. 
http://www.hotmail.com


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?F164S2kUfbGRJvoYAMx00010cb1>