Example #1
0
uint32_t smm_deactivate(void)
{
    uint32_t adr;
    uint32_t ret = SMM_DEFAULT;
    uint32_t smi_en;
    unsigned if_backup;

    if_backup = cli();

    if (pmbase != 0) {
        adr = pmbase+0x30;                          /* SMI_EN I/O register is at pmbase+0x30 */

        /* read current value to return it on end */
        ret = inportl(adr);

        /* set to 0 (only writable bits will be changed...) */
        smi_en = 0; //&= ~1;
        outportl(adr, smi_en);

        /* read again to see what has changed */
        smi_en = inportl(adr);
        IFVV printf("SMI_EN: 0x%x (after setting SMI_EN to 0; bit 0 is GBL_SMI_EN)\n", smi_en);

        /* if GBL_SMI_EN (bit #0) is 0, deactivation was successful */
        if ((smi_en & 0x01) == 0) {
            IFV printf("SMI globally disabled\n");
        } else {
            printf("Warning: SMI was not disabled!\n");
        }
    }

    if (if_backup) sti();
    return ret;
}
Example #2
0
void smm_init(void)
{
    uint32_t adr;
    uint32_t smi_en;
    unsigned if_backup;

    if_backup = cli();

    
    /*
    adr = (1<<31) | (LPC_BUS << 16)  |  (LPC_DEVICE << 11)  |  (LPC_FUNC <<  8)  |  LPC_OFFSET;
    outportl(CONFIG_ADDRESS, adr);
    pmbase = inportl(CONFIG_DATA);
    */
    pmbase = pci_config_read(LPC_BUS, LPC_DEVICE, LPC_FUNC, LPC_OFFSET);
    pmbase &= 0xFF80;
    IFV printf("SMM: located pmbase : 0x%x \n", pmbase);



    if (pmbase != 0) {

        adr = pmbase+0x30;                          /* SMI_EN I/O register is at pmbase+0x30 */

        /* read SMI_EN and display */
        smi_en = inportl(adr);
        bak_smi_en = smi_en;
        IFVV printf("SMI_EN: 0x%x \n", smi_en);
    }

    if (if_backup) sti();
}
Example #3
0
File: pci.c Project: levex/levos5
uint32_t pci_read_dword(uint8_t bus, uint8_t slot,
						uint8_t func, uint32_t offset)
{
	uint32_t id = ((bus) << 16) | ((slot) << 11) | ((func) << 8);
	uint32_t addr = 0x80000000 | id | (offset & 0xfc);
	outportl(0xCF8, addr);
	return inportl(0xCFC);
}
Example #4
0
File: rtl.c Project: Saruta/ToyOS
static int rtl_irq_handler(struct regs *r) {
	uint16_t status = inports(rtl_iobase + RTL_PORT_ISR);
	if (!status) {
		return 0;
	}
	outports(rtl_iobase + RTL_PORT_ISR, status);

	irq_ack(rtl_irq);

	if (status & 0x01 || status & 0x02) {
		/* Receive */
		while((inportb(rtl_iobase + RTL_PORT_CMD) & 0x01) == 0) {
			int offset = cur_rx % 0x2000;

#if 0
			uint16_t buf_addr = inports(rtl_iobase + RTL_PORT_RXADDR);
			uint16_t buf_ptr  = inports(rtl_iobase + RTL_PORT_RXPTR);
			uint8_t  cmd      = inportb(rtl_iobase + RTL_PORT_CMD);
#endif

			uint32_t * buf_start = (uint32_t *)((uintptr_t)rtl_rx_buffer + offset);
			uint32_t rx_status = buf_start[0];
			int rx_size = rx_status >> 16;

			if (rx_status & (0x0020 | 0x0010 | 0x0004 | 0x0002)) {
				debug_print(WARNING, "rx error :(");
			} else {
				uint8_t * buf_8 = (uint8_t *)&(buf_start[1]);

				last_packet = malloc(rx_size);

				uintptr_t packet_end = (uintptr_t)buf_8 + rx_size;
				if (packet_end > (uintptr_t)rtl_rx_buffer + 0x2000) {
					size_t s = ((uintptr_t)rtl_rx_buffer + 0x2000) - (uintptr_t)buf_8;
					memcpy(last_packet, buf_8, s);
					memcpy((void *)((uintptr_t)last_packet + s), rtl_rx_buffer, rx_size - s);
				} else {
					memcpy(last_packet, buf_8, rx_size);
				}

				rtl_enqueue(last_packet);
			}

			cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
			outports(rtl_iobase + RTL_PORT_RXPTR, cur_rx - 16);
		}
		wakeup_queue(rx_wait);
	}

	if (status & 0x08 || status & 0x04) {
		unsigned int i = inportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * dirty_tx);
		(void)i;
		dirty_tx++;
		if (dirty_tx == 5) dirty_tx = 0;
	}

	return 1;
}
Example #5
0
File: pci.c Project: juur/FailOS
uint32 pci_read_conf32(uint8 bus, uint8 dev, uint8 func, uint8 reg)
{
	uint32 ret;
	uint32 port = (0x80000000U)|(bus<<16)|(dev<<11)|(func<<8)|(reg);

	outportl(0xcf8, port);

	ret = inportl(0xcfc);
	return ret;
}
Example #6
0
static unsigned long pci_dev_read_dw(pci_dev *pdev, unsigned int index)
{
  unsigned long tmp;
  unsigned long pci_config_addr32 = 0x80000000L |
                       (((unsigned long)pdev->bus) << 16) |
                       (((unsigned long)pdev->dev) << 11) |
                       (((unsigned long)pdev->func) << 8) |
                       index;
  outportl(0x0cf8, pci_config_addr32);				   
  tmp = inportl(0x0cfc);
  
  return tmp;
}
Example #7
0
uint32_t pci_read_field(uint32_t device, int field, int size) {
	outportl(PCI_ADDRESS_PORT, pci_get_addr(device, field));

	if (size == 4) {
		uint32_t t = inportl(PCI_VALUE_PORT);
		return t;
	} else if (size == 2) {
		uint16_t t = inports(PCI_VALUE_PORT + (field & 2));
		return t;
	} else if (size == 1) {
		uint8_t t = inportb(PCI_VALUE_PORT + (field & 3));
		return t;
	}
	return 0xFFFF;
}
Example #8
0
uint32_t smm_restore(uint32_t value)
{
    unsigned if_backup;
    uint32_t ret = SMM_DEFAULT;

    if_backup = cli();

    if (pmbase != 0) {
        /* read current value to return it on end */
        ret = inportl(pmbase+0x30);
        /* restore */
        outportl(pmbase+0x30, (value==SMM_DEFAULT)?bak_smi_en:value);
    }

    if (if_backup) sti();
    return ret;
}
Example #9
0
File: pcnet.c Project: juur/FailOS
uint32 readBCR(uint32 base, uint32 index)
{
    outportl(base + RAP, index);
    return inportl(base + BDP);
}
Example #10
0
uint32_t pci_read32(uint32_t id, uint32_t reg)
{
	uint32_t addr = 0x80000000 | id | (reg & 0xfc);
	outportl(PCI_CONFIG_ADDR, addr);
	return inportl(PCI_CONFIG_DATA);
}
Example #11
0
static uint32_t rddm32(CMI8738_Driver_t* ds, uint32_t offset)
{
    return inportl(ds->base_addr + offset);
}
Example #12
0
int vm86_emulate(struct vm86_context *vm86ctx)
{
    int eaten = 1;
    int data32 = 0, addr32 = 0, rep = 0, segp = 0;
    int done = 0;

    uint16_t ip = LOWORD(vm86ctx->eip),
             sp = LOWORD(vm86ctx->esp);

    do {
        switch(*(uint8_t *)LADDR(vm86ctx->cs, ip)) {
        case 0x66: /*32-bit data*/ data32=1; break;
        case 0x67: /*32-bit addr*/ addr32=1; break;
        case 0xf2: /*REPNZ/REPNE*/    rep=1; break;
        case 0xf3: /*REP/REPZ/REPE*/  rep=1; break;
        case 0x2e: /*CS*/           segp=56; break;
        case 0x3e: /*DS*/           segp=76; break;
        case 0x26: /*ES*/           segp=72; break;
        case 0x36: /*SS*/           segp=68; break;
        case 0x65: /*GS*/           segp=84; break;
        case 0x64: /*FS*/           segp=80; break;
        case 0xf0: /*LOCK*/                  break;
        default: done = 1;                   break;
        }
        if(done)
            break;
        ip++;
    } while(1);

    switch(*(uint8_t *)LADDR(vm86ctx->cs, ip)) {
    case 0xfa: /*CLI*/
        vm86ctx->eflags &= ~EFLAGS_IF;
        ip++;
        break;
    case 0xfb: /*STI*/
        vm86ctx->eflags |= EFLAGS_IF;
        ip++;
        break;
    case 0x9c: /*PUSHF*/
        if(data32) {
            sp -= 4;
            *(uint32_t *)LADDR(vm86ctx->ss, sp) = vm86ctx->eflags & 0x001cffff;
        } else {
            sp -= 2;
            *(uint16_t *)LADDR(vm86ctx->ss, sp) = (uint16_t)vm86ctx->eflags;
        }
        ip++;
        break;
    case 0x9d: /*POPF*/
        if(data32) {
            uint32_t eflags = *(uint32_t *)LADDR(vm86ctx->ss, sp);
            vm86ctx->eflags &= 0x1b3000/*VM, RF, IOPL, VIP, VIF*/;
            eflags &= ~0x1b3000;
            vm86ctx->eflags |= eflags;
            sp += 4;
        } else {
            uint32_t eflags = *(uint16_t *)LADDR(vm86ctx->ss, sp);
            vm86ctx->eflags &= 0xffff3000/*IOPL*/;
            eflags &= ~0xffff3000;
            vm86ctx->eflags |= eflags;
            sp += 2;
        }
        ip++;
        break;
    case 0xcd: /*INT*/
        sp -= 2;
        *(uint16_t *)LADDR(vm86ctx->ss, sp) = (uint16_t)vm86ctx->eflags;
        sp -= 2;
        *(uint16_t *)LADDR(vm86ctx->ss, sp) = vm86ctx->cs;
        sp -= 2;
        *(uint16_t *)LADDR(vm86ctx->ss, sp) = ip + 2;

        {
            uint16_t *ivt = (uint16_t *)0;
            uint8_t x = *(uint8_t *)LADDR(vm86ctx->cs, ip + 1);
            ip = ivt[x * 2 + 0];
            vm86ctx->cs = ivt[x * 2 + 1];
        }
        break;
    case 0xcf: /*IRET*/
        if(data32) {
            ip = *(uint32_t *)LADDR(vm86ctx->ss, sp);
            sp += 4;

            vm86ctx->cs = *(uint32_t *)LADDR(vm86ctx->ss, sp);
            sp += 4;

            uint32_t eflags = *(uint32_t *)LADDR(vm86ctx->ss, sp);
            vm86ctx->eflags &= 0x1a3000/*VM, IOPL, VIP, VIF*/;
            eflags &= ~0x1a3000;
            vm86ctx->eflags |= eflags;
            sp += 4;
        } else {
            ip = *(uint16_t *)LADDR(vm86ctx->ss, sp);
            sp += 2;

            vm86ctx->cs = *(uint16_t *)LADDR(vm86ctx->ss, sp);
            sp += 2;

            uint32_t eflags = *(uint16_t *)LADDR(vm86ctx->ss, sp);
            vm86ctx->eflags &= 0xffff3000/*IOPL*/;
            eflags &= ~0xffff3000;
            vm86ctx->eflags |= eflags;
            sp += 2;
        }
        break;
    case 0xe6:/*OUT imm8, AL*/
        outportb(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1),
                LOBYTE(LOWORD(vm86ctx->eax)));
        ip += 2;
        break;
    case 0xe7:/*OUT imm8, (E)AX*/
        if(data32) {
            outportl(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1),
                     vm86ctx->eax);
        } else {
            outportw(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1),
                     LOWORD(vm86ctx->eax));
        }
        ip += 2;
        break;
    case 0xee:/*OUT DX, AL*/
        outportb(LOWORD(vm86ctx->edx), LOBYTE(LOWORD(vm86ctx->eax)));
        ip++;
        break;
    case 0xef:/*OUT DX, (E)AX*/
        if(data32) {
            outportl(LOWORD(vm86ctx->edx), vm86ctx->eax);
        } else {
            outportw(LOWORD(vm86ctx->edx), LOWORD(vm86ctx->eax));
        }
        ip++;
        break;
    case 0xe4:/*IN AL, imm8*/
        {
            uint8_t al  = inportb(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1));
            vm86ctx->eax = (vm86ctx->eax & 0xffffff00) | al;
        }
        ip += 2;
        break;
    case 0xe5:/*IN (E)AX, imm8*/
        if(data32) {
            vm86ctx->eax = inportl(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1));
        } else {
            uint16_t ax  = inportw(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1));
            vm86ctx->eax = (vm86ctx->eax & 0xffff0000) | ax;
        }
        ip += 2;
        break;
    case 0xec:/*IN AL, DX*/
        {
            uint8_t al  = inportb(LOWORD(vm86ctx->edx));
            vm86ctx->eax = (vm86ctx->eax & 0xffffff00) | al;
        }
        ip += 1;
        break;
    case 0xed:/*IN (E)AX, DX*/
        if(data32) {
            vm86ctx->eax = inportl(LOWORD(vm86ctx->edx));
        } else {
            uint16_t ax  = inportw(LOWORD(vm86ctx->edx));
            vm86ctx->eax = (vm86ctx->eax & 0xffff0000) | ax;
        }
        ip++;
        break;
    case 0x6c:/*INSB; INS m8, DX*/
        {
            if(addr32) {
                uint32_t ecx = rep ? vm86ctx->ecx : 1;

                while(ecx) {
                    *(uint8_t *)LADDR(vm86ctx->es, vm86ctx->edi/*XXX*/) =
                        inportb(LOWORD(vm86ctx->edx));
                    ecx--;
                    vm86ctx->edi += (vm86ctx->eflags & 0x400)?-1:1;
                }

                if(rep)
                    vm86ctx->ecx = ecx;
            } else {
                uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1,
                         di=LOWORD(vm86ctx->edi);
                while(cx) {
                    *(uint8_t *)LADDR(vm86ctx->es, di) =
                        inportb(LOWORD(vm86ctx->edx));
                    cx--;
                    di += (vm86ctx->eflags & 0x400)?-1:1;
                }
                if(rep)
                    vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx;
                vm86ctx->edi = (vm86ctx->edi & 0xffff0000) | di;
            }
        }
        ip++;
        break;
    case 0x6d:/*INSW; INSD; INS m16/m32, DX*/
        {
            if(addr32) {
                uint32_t ecx = rep ? vm86ctx->ecx : 1;

                while(ecx) {
                    if(data32) {
                        *(uint32_t *)LADDR(vm86ctx->es, vm86ctx->edi/*XXX*/) =
                            inportl(LOWORD(vm86ctx->edx));
                        vm86ctx->edi += (vm86ctx->eflags & 0x400)?-4:4;
                    } else {
                        *(uint16_t *)LADDR(vm86ctx->es, vm86ctx->edi/*XXX*/) =
                            inportw(LOWORD(vm86ctx->edx));
                        vm86ctx->edi += (vm86ctx->eflags & 0x400)?-2:2;
                    }
                    ecx--;
                }
                if(rep)
                    vm86ctx->ecx = ecx;
            } else {
                uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1,
                         di=LOWORD(vm86ctx->edi);
                while(cx) {
                    if(data32) {
                        *(uint32_t *)LADDR(vm86ctx->es, di) =
                            inportl(LOWORD(vm86ctx->edx));
                        di += (vm86ctx->eflags & 0x400)?-4:4;
                    } else {
                        *(uint16_t *)LADDR(vm86ctx->es, di) =
                            inportw(LOWORD(vm86ctx->edx));
                        di += (vm86ctx->eflags & 0x400)?-2:2;
                    }
                    cx--;
                }
                if(rep)
                    vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx;
                vm86ctx->edi = (vm86ctx->edi & 0xffff0000) | di;
            }
        }
        ip++;
        break;
    case 0x6e:/*OUTSB; OUTS DX, m8*/
        {
            uint16_t seg = vm86ctx->ds;

            if(segp)
                seg = *(uint16_t *)(((uint8_t *)vm86ctx)+segp);

            if(addr32) {
                uint32_t ecx = rep ? vm86ctx->ecx : 1;

                while(ecx) {
                    outportb(LOWORD(vm86ctx->edx),
                             *(uint8_t *)LADDR(seg, vm86ctx->esi/*XXX*/));
                    ecx--;
                    vm86ctx->esi += (vm86ctx->eflags & 0x400)?-1:1;
                }
                if(rep)
                    vm86ctx->ecx = ecx;
            } else {
                uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1,
                         si=LOWORD(vm86ctx->esi);
                while(cx) {
                    outportb(LOWORD(vm86ctx->edx), *(uint8_t *)LADDR(seg, si));
                    cx--;
                    si += (vm86ctx->eflags & 0x400)?-1:1;
                }
                if(rep)
                    vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx;
                vm86ctx->esi = (vm86ctx->esi & 0xffff0000) | si;
            }
        }
        ip++;
        break;
    case 0x6f:/*OUTSW; OUTSD; OUTS DX, m16/32*/
        {
            uint16_t seg = vm86ctx->ds;

            if(segp)
                seg = *(uint16_t *)(((uint8_t *)vm86ctx)+segp);

            if(addr32) {
                uint32_t ecx = rep ? vm86ctx->ecx : 1;

                while(ecx) {
                    if(data32) {
                        outportl(LOWORD(vm86ctx->edx),
                                 *(uint32_t *)LADDR(seg, vm86ctx->esi/*XXX*/));
                        vm86ctx->esi += (vm86ctx->eflags & 0x400)?-4:4;
                    } else {
                        outportw(LOWORD(vm86ctx->edx),
                                 *(uint16_t *)LADDR(seg, vm86ctx->esi/*XXX*/));
                        vm86ctx->esi += (vm86ctx->eflags & 0x400)?-2:2;
                    }
                    ecx--;
                }
                if(rep)
                    vm86ctx->ecx = ecx;
            } else {
                uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1,
                         si=LOWORD(vm86ctx->esi);
                while(cx) {
                    if(data32) {
                        outportl(LOWORD(vm86ctx->edx), *(uint32_t *)LADDR(seg, si));
                        si += (vm86ctx->eflags & 0x400)?-4:4;
                    } else {
                        outportw(LOWORD(vm86ctx->edx), *(uint16_t *)LADDR(seg, si));
                        si += (vm86ctx->eflags & 0x400)?-2:2;
                    }
                    cx--;
                }
                if(rep)
                    vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx;
                vm86ctx->esi = (vm86ctx->esi & 0xffff0000) | si;
            }
        }
        ip++;
        break;
    default:
        eaten = 0;
        break;
    }

    vm86ctx->eip = (vm86ctx->eip & 0xffff0000) | ip;
    vm86ctx->esp = (vm86ctx->esp & 0xffff0000) | sp;

    return eaten;
}