| /* |
| * Copyright 1999 Egbert Eich |
| * |
| * Permission to use, copy, modify, distribute, and sell this software and its |
| * documentation for any purpose is hereby granted without fee, provided that |
| * the above copyright notice appear in all copies and that both that |
| * copyright notice and this permission notice appear in supporting |
| * documentation, and that the name of the authors not be used in |
| * advertising or publicity pertaining to distribution of the software without |
| * specific, written prior permission. The authors makes no representations |
| * about the suitability of this software for any purpose. It is provided |
| * "as is" without express or implied warranty. |
| * |
| * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
| * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
| * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
| * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
| * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| #include "debug.h" |
| #if defined(__alpha__) || defined (__ia64__) |
| #include <sys/io.h> |
| #endif |
| |
| #include "v86bios.h" |
| #include "AsmMacros.h" |
| #include "pci.h" |
| |
| static int int1A_handler(struct regs86 *regs); |
| static int int42_handler(int num, struct regs86 *regs); |
| |
| int |
| int_handler(int num, struct regs86 *regs) |
| { |
| switch (num) { |
| case 0x10: |
| case 0x42: |
| return (int42_handler(num,regs)); |
| case 0x1A: |
| return (int1A_handler(regs)); |
| default: |
| return 0; |
| } |
| return 0; |
| } |
| |
| static int |
| int42_handler(int num,struct regs86 *regs) |
| { |
| unsigned char c; |
| CARD32 val; |
| |
| i_printf("int 0x%x: ax:0x%lx bx:0x%lx cx:0x%lx dx:0x%lx\n",num, |
| regs->eax,regs->ebx, regs->ecx, regs->edx); |
| |
| /* |
| * video bios has modified these - |
| * leave it to the video bios to do this |
| */ |
| |
| val = getIntVect(num); |
| if (val != 0xF000F065) |
| return 0; |
| |
| if ((regs->ebx & 0xff) == 0x32) { |
| switch (regs->eax & 0xFFFF) { |
| case 0x1200: |
| i_printf("enabling video\n"); |
| c = inb(0x3cc); |
| c |= 0x02; |
| outb(0x3c2,c); |
| return 1; |
| case 0x1201: |
| i_printf("disabling video\n"); |
| c = inb(0x3cc); |
| c &= ~0x02; |
| outb(0x3c2,c); |
| return 1; |
| default: |
| } |
| } |
| if (num == 0x42) |
| return 1; |
| else |
| return 0; |
| } |
| |
| #define SUCCESSFUL 0x00 |
| #define DEVICE_NOT_FOUND 0x86 |
| #define BAD_REGISTER_NUMBER 0x87 |
| |
| static int |
| int1A_handler(struct regs86 *regs) |
| { |
| CARD32 Slot; |
| PciStructPtr pPci; |
| |
| if (! CurrentPci) return 0; /* oops */ |
| |
| i_printf("int 0x1a: ax=0x%lx bx=0x%lx cx=0x%lx dx=0x%lx di=0x%lx" |
| " si=0x%lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx, |
| regs->edi,regs->esi); |
| switch (regs->eax & 0xFFFF) { |
| case 0xb101: |
| regs->eax &= 0xFF00; /* no config space/special cycle support */ |
| regs->edx = 0x20494350; /* " ICP" */ |
| regs->ebx = 0x0210; /* Version 2.10 */ |
| regs->ecx &= 0xFF00; |
| regs->ecx |= (pciMaxBus & 0xFF); /* Max bus number in system */ |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| i_printf("ax=0x%lx dx=0x%lx bx=0x%lx cx=0x%lx flags=0x%lx\n", |
| regs->eax,regs->edx,regs->ebx,regs->ecx,regs->eflags); |
| return 1; |
| case 0xb102: |
| if (((regs->edx & 0xFFFF) == CurrentPci->VendorID) && |
| ((regs->ecx & 0xFFFF) == CurrentPci->DeviceID) && |
| (regs->esi == 0)) { |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| regs->ebx = pciSlotBX(CurrentPci); |
| } |
| else if (Config.ShowAllDev && |
| (pPci = findPciDevice(regs->edx,regs->ecx,regs->esi)) != NULL) { |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| regs->ebx = pciSlotBX(pPci); |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (DEVICE_NOT_FOUND << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx bx=0x%lx flags=0x%lx\n", |
| regs->eax,regs->ebx,regs->eflags); |
| return 1; |
| case 0xb103: |
| if (((regs->ecx & 0xFF) == CurrentPci->Interface) && |
| (((regs->ecx & 0xFF00) >> 8) == CurrentPci->SubClass) && |
| (((regs->ecx & 0xFFFF0000) >> 16) == CurrentPci->BaseClass) && |
| ((regs->esi & 0xff) == 0)) { |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->ebx = pciSlotBX(CurrentPci); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } |
| else if (Config.ShowAllDev |
| && (pPci = findPciClass(regs->ecx & 0xFF, (regs->ecx & 0xff00) >> 8, |
| (regs->ecx & 0xffff0000) >> 16, regs->esi)) != NULL) { |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->ebx = pciSlotBX(pPci); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (DEVICE_NOT_FOUND << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx flags=0x%lx\n",regs->eax,regs->eflags); |
| return 1; |
| case 0xb108: |
| i_printf("Slot=0x%x\n",CurrentPci->Slot.l); |
| if ((Slot = findPci(regs->ebx))) { |
| regs->ecx &= 0xFFFFFF00; |
| regs->ecx |= PciRead8(regs->edi,Slot); |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx cx=0x%lx flags=0x%lx\n", |
| regs->eax,regs->ecx,regs->eflags); |
| return 1; |
| case 0xb109: |
| i_printf("Slot=0x%x\n",CurrentPci->Slot.l); |
| if ((Slot = findPci(regs->ebx))) { |
| regs->ecx &= 0xFFFF0000; |
| regs->ecx |= PciRead16(regs->edi,Slot); |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx cx=0x%lx flags=0x%lx\n", |
| regs->eax,regs->ecx,regs->eflags); |
| return 1; |
| case 0xb10a: |
| i_printf("Slot=0x%x\n",CurrentPci->Slot.l); |
| if ((Slot = findPci(regs->ebx))) { |
| regs->ecx &= 0; |
| regs->ecx |= PciRead32(regs->edi,Slot); |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx cx=0x%lx flags=0x%lx\n", |
| regs->eax,regs->ecx,regs->eflags); |
| return 1; |
| case 0xb10b: |
| i_printf("Slot=0x%x\n",CurrentPci->Slot.l); |
| if ((Slot = findPci(regs->ebx))) { |
| PciWrite8(regs->edi,(CARD8)regs->ecx,Slot); |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx flags=0x%lx\n", regs->eax,regs->eflags); |
| return 1; |
| case 0xb10c: |
| i_printf("Slot=0x%x\n",CurrentPci->Slot.l); |
| if ((Slot = findPci(regs->ebx))) { |
| PciWrite16(regs->edi,(CARD16)regs->ecx,Slot); |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx flags=0x%lx\n", regs->eax,regs->eflags); |
| return 1; |
| case 0xb10d: |
| i_printf("Slot=0x%x\n",CurrentPci->Slot.l); |
| if ((Slot = findPci(regs->ebx))) { |
| PciWrite32(regs->edi,(CARD32)regs->ecx,Slot); |
| regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8); |
| regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */ |
| } else { |
| regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8); |
| regs->eflags |= ((unsigned long)0x01); /* set carry flag */ |
| } |
| i_printf("ax=0x%lx flags=0x%lx\n", regs->eax,regs->eflags); |
| return 1; |
| default: |
| return 0; |
| } |
| } |