summaryrefslogtreecommitdiff
path: root/util/x86emu/yabel/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/x86emu/yabel/io.c')
-rw-r--r--util/x86emu/yabel/io.c574
1 files changed, 0 insertions, 574 deletions
diff --git a/util/x86emu/yabel/io.c b/util/x86emu/yabel/io.c
deleted file mode 100644
index 38a5d32c7c..0000000000
--- a/util/x86emu/yabel/io.c
+++ /dev/null
@@ -1,574 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation
- * Copyright (c) 2009 Pattrick Hueper <phueper@hueper.net>
- * All rights reserved.
- * This program and the accompanying materials
- * are made available under the terms of the BSD License
- * which accompanies this distribution, and is available at
- * http://www.opensource.org/licenses/bsd-license.php
- *
- * Contributors:
- * IBM Corporation - initial implementation
- *****************************************************************************/
-
-#include <types.h>
-#include "compat/rtas.h"
-#include "compat/time.h"
-#include "device.h"
-#include "debug.h"
-#include <x86emu/x86emu.h>
-#include "io.h"
-
-#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#endif
-
-static unsigned int
-read_io(void *addr, size_t sz)
-{
- unsigned int ret;
- /* since we are using inb instructions, we need the port number as 16bit value */
- u16 port = (u16)(u32) addr;
-
- switch (sz) {
- case 1:
- asm volatile ("inb %1, %b0" : "=a"(ret) : "d" (port));
- break;
- case 2:
- asm volatile ("inw %1, %w0" : "=a"(ret) : "d" (port));
- break;
- case 4:
- asm volatile ("inl %1, %0" : "=a"(ret) : "d" (port));
- break;
- default:
- ret = 0;
- }
-
- return ret;
-}
-
-static int
-write_io(void *addr, unsigned int value, size_t sz)
-{
- u16 port = (u16)(u32) addr;
- switch (sz) {
- /* since we are using inb instructions, we need the port number as 16bit value */
- case 1:
- asm volatile ("outb %b0, %1" : : "a"(value), "d" (port));
- break;
- case 2:
- asm volatile ("outw %w0, %1" : : "a"(value), "d" (port));
- break;
- case 4:
- asm volatile ("outl %0, %1" : : "a"(value), "d" (port));
- break;
- default:
- return -1;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_ARCH_X86
-#include <arch/io.h>
-#else
-// these are not used, only needed for linking, must be overridden using X86emu_setupPioFuncs
-// with the functions and struct below
-void
-outb(u8 val, u16 port)
-{
- printf("WARNING: outb not implemented!\n");
- HALT_SYS();
-}
-
-void
-outw(u16 val, u16 port)
-{
- printf("WARNING: outw not implemented!\n");
- HALT_SYS();
-}
-
-void
-outl(u32 val, u16 port)
-{
- printf("WARNING: outl not implemented!\n");
- HALT_SYS();
-}
-
-u8
-inb(u16 port)
-{
- printf("WARNING: inb not implemented!\n");
- HALT_SYS();
- return 0;
-}
-
-u16
-inw(u16 port)
-{
- printf("WARNING: inw not implemented!\n");
- HALT_SYS();
- return 0;
-}
-
-u32
-inl(u16 port)
-{
- printf("WARNING: inl not implemented!\n");
- HALT_SYS();
- return 0;
-}
-#endif
-
-#if defined(CONFIG_YABEL_DIRECTHW) && (CONFIG_YABEL_DIRECTHW == 1)
-u8 my_inb(X86EMU_pioAddr addr)
-{
- u8 val;
-
- val = inb(addr);
- DEBUG_PRINTF_IO("inb(0x%04x) = 0x%02x\n", addr, val);
-
- return val;
-}
-
-u16 my_inw(X86EMU_pioAddr addr)
-{
- u16 val;
-
- val = inw(addr);
- DEBUG_PRINTF_IO("inw(0x%04x) = 0x%04x\n", addr, val);
-
- return val;
-}
-
-u32 my_inl(X86EMU_pioAddr addr)
-{
- u32 val;
-
- val = inl(addr);
- DEBUG_PRINTF_IO("inl(0x%04x) = 0x%08x\n", addr, val);
-
- return val;
-}
-
-void my_outb(X86EMU_pioAddr addr, u8 val)
-{
- DEBUG_PRINTF_IO("outb(0x%02x, 0x%04x)\n", val, addr);
- outb(val, addr);
-}
-
-void my_outw(X86EMU_pioAddr addr, u16 val)
-{
- DEBUG_PRINTF_IO("outw(0x%04x, 0x%04x)\n", val, addr);
- outw(val, addr);
-}
-
-void my_outl(X86EMU_pioAddr addr, u32 val)
-{
- DEBUG_PRINTF_IO("outl(0x%08x, 0x%04x)\n", val, addr);
- outl(val, addr);
-}
-
-#else
-
-u32 pci_cfg_read(X86EMU_pioAddr addr, u8 size);
-void pci_cfg_write(X86EMU_pioAddr addr, u32 val, u8 size);
-u8 handle_port_61h(void);
-
-u8
-my_inb(X86EMU_pioAddr addr)
-{
- u8 rval = 0xFF;
- unsigned long translated_addr = addr;
- u8 translated = biosemu_dev_translate_address(&translated_addr);
- if (translated != 0) {
- //translation successfull, access Device I/O (BAR or Legacy...)
- DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __func__,
- addr);
- //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __func__, addr, translated_addr);
- rval = read_io((void *)translated_addr, 1);
- DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %02x\n", __func__,
- addr, rval);
- return rval;
- } else {
- switch (addr) {
- case 0x61:
- //8254 KB Controller / Timer Port
- // rval = handle_port_61h();
- rval = inb(0x61);
- //DEBUG_PRINTF_IO("%s(%04x) KB / Timer Port B --> %02x\n", __func__, addr, rval);
- return rval;
- break;
- case 0xCFC:
- case 0xCFD:
- case 0xCFE:
- case 0xCFF:
- // PCI Config Mechanism 1 Ports
- return (u8) pci_cfg_read(addr, 1);
- break;
- case 0x0a:
- CHECK_DBG(DEBUG_INTR) {
- X86EMU_trace_on();
- }
- M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
- //HALT_SYS();
- // no break, intentional fall-through to default!!
- default:
- DEBUG_PRINTF_IO
- ("%s(%04x) reading from bios_device.io_buffer\n",
- __func__, addr);
- rval = *((u8 *) (bios_device.io_buffer + addr));
- DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %02x\n",
- __func__, addr, rval);
- return rval;
- break;
- }
- }
-}
-
-u16
-my_inw(X86EMU_pioAddr addr)
-{
- unsigned long translated_addr = addr;
- u8 translated = biosemu_dev_translate_address(&translated_addr);
- if (translated != 0) {
- //translation successfull, access Device I/O (BAR or Legacy...)
- DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __func__,
- addr);
- //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __func__, addr, translated_addr);
- u16 rval;
- if ((translated_addr & (u64) 0x1) == 0) {
- // 16 bit aligned access...
- u16 tempval = read_io((void *)translated_addr, 2);
- //little endian conversion
- rval = in16le((void *) &tempval);
- } else {
- // unaligned access, read single bytes, little-endian
- rval = (read_io((void *)translated_addr, 1) << 8)
- | (read_io((void *)(translated_addr + 1), 1));
- }
- DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %04x\n", __func__,
- addr, rval);
- return rval;
- } else {
- switch (addr) {
- case 0xCFC:
- case 0xCFE:
- //PCI Config Mechanism 1
- return (u16) pci_cfg_read(addr, 2);
- break;
- default:
- DEBUG_PRINTF_IO
- ("%s(%04x) reading from bios_device.io_buffer\n",
- __func__, addr);
- u16 rval =
- in16le((void *) bios_device.io_buffer + addr);
- DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %04x\n",
- __func__, addr, rval);
- return rval;
- break;
- }
- }
-}
-
-u32
-my_inl(X86EMU_pioAddr addr)
-{
- unsigned long translated_addr = addr;
- u8 translated = biosemu_dev_translate_address(&translated_addr);
- if (translated != 0) {
- //translation successfull, access Device I/O (BAR or Legacy...)
- DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __func__,
- addr);
- //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __func__, addr, translated_addr);
- u32 rval;
- if ((translated_addr & (u64) 0x3) == 0) {
- // 32 bit aligned access...
- u32 tempval = read_io((void *) translated_addr, 4);
- //little endian conversion
- rval = in32le((void *) &tempval);
- } else {
- // unaligned access, read single bytes, little-endian
- rval = (read_io((void *)(translated_addr), 1) << 24)
- | (read_io((void *)(translated_addr + 1), 1) << 16)
- | (read_io((void *)(translated_addr + 2), 1) << 8)
- | (read_io((void *)(translated_addr + 3), 1));
- }
- DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %08x\n", __func__,
- addr, rval);
- return rval;
- } else {
- switch (addr) {
- case 0xCFC:
- //PCI Config Mechanism 1
- return pci_cfg_read(addr, 4);
- break;
- default:
- DEBUG_PRINTF_IO
- ("%s(%04x) reading from bios_device.io_buffer\n",
- __func__, addr);
- u32 rval =
- in32le((void *) bios_device.io_buffer + addr);
- DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %08x\n",
- __func__, addr, rval);
- return rval;
- break;
- }
- }
-}
-
-void
-my_outb(X86EMU_pioAddr addr, u8 val)
-{
- unsigned long translated_addr = addr;
- u8 translated = biosemu_dev_translate_address(&translated_addr);
- if (translated != 0) {
- //translation successfull, access Device I/O (BAR or Legacy...)
- DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n",
- __func__, addr, val);
- //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __func__, addr, translated_addr);
- write_io((void *) translated_addr, val, 1);
- DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %02x\n", __func__,
- addr, val);
- } else {
- switch (addr) {
- case 0xCFC:
- case 0xCFD:
- case 0xCFE:
- case 0xCFF:
- // PCI Config Mechanism 1 Ports
- pci_cfg_write(addr, val, 1);
- break;
- default:
- DEBUG_PRINTF_IO
- ("%s(%04x,%02x) writing to bios_device.io_buffer\n",
- __func__, addr, val);
- *((u8 *) (bios_device.io_buffer + addr)) = val;
- break;
- }
- }
-}
-
-void
-my_outw(X86EMU_pioAddr addr, u16 val)
-{
- unsigned long translated_addr = addr;
- u8 translated = biosemu_dev_translate_address(&translated_addr);
- if (translated != 0) {
- //translation successfull, access Device I/O (BAR or Legacy...)
- DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n",
- __func__, addr, val);
- //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __func__, addr, translated_addr);
- if ((translated_addr & (u64) 0x1) == 0) {
- // little-endian conversion
- u16 tempval = in16le((void *) &val);
- // 16 bit aligned access...
- write_io((void *) translated_addr, tempval, 2);
- } else {
- // unaligned access, write single bytes, little-endian
- write_io(((void *) (translated_addr + 1)),
- (u8) ((val & 0xFF00) >> 8), 1);
- write_io(((void *) translated_addr),
- (u8) (val & 0x00FF), 1);
- }
- DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %04x\n", __func__,
- addr, val);
- } else {
- switch (addr) {
- case 0xCFC:
- case 0xCFE:
- // PCI Config Mechanism 1 Ports
- pci_cfg_write(addr, val, 2);
- break;
- default:
- DEBUG_PRINTF_IO
- ("%s(%04x,%04x) writing to bios_device.io_buffer\n",
- __func__, addr, val);
- out16le((void *) bios_device.io_buffer + addr, val);
- break;
- }
- }
-}
-
-void
-my_outl(X86EMU_pioAddr addr, u32 val)
-{
- unsigned long translated_addr = addr;
- u8 translated = biosemu_dev_translate_address(&translated_addr);
- if (translated != 0) {
- //translation successfull, access Device I/O (BAR or Legacy...)
- DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n",
- __func__, addr, val);
- //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __func__, addr, translated_addr);
- if ((translated_addr & (u64) 0x3) == 0) {
- // little-endian conversion
- u32 tempval = in32le((void *) &val);
- // 32 bit aligned access...
- write_io((void *) translated_addr, tempval, 4);
- } else {
- // unaligned access, write single bytes, little-endian
- write_io(((void *) translated_addr + 3),
- (u8) ((val & 0xFF000000) >> 24), 1);
- write_io(((void *) translated_addr + 2),
- (u8) ((val & 0x00FF0000) >> 16), 1);
- write_io(((void *) translated_addr + 1),
- (u8) ((val & 0x0000FF00) >> 8), 1);
- write_io(((void *) translated_addr),
- (u8) (val & 0x000000FF), 1);
- }
- DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %08x\n", __func__,
- addr, val);
- } else {
- switch (addr) {
- case 0xCFC:
- // PCI Config Mechanism 1 Ports
- pci_cfg_write(addr, val, 4);
- break;
- default:
- DEBUG_PRINTF_IO
- ("%s(%04x,%08x) writing to bios_device.io_buffer\n",
- __func__, addr, val);
- out32le((void *) bios_device.io_buffer + addr, val);
- break;
- }
- }
-}
-
-u32
-pci_cfg_read(X86EMU_pioAddr addr, u8 size)
-{
- u32 rval = 0xFFFFFFFF;
- struct device * dev;
- if ((addr >= 0xCFC) && ((addr + size) <= 0xD00)) {
- // PCI Configuration Mechanism 1 step 1
- // write to 0xCF8, sets bus, device, function and Config Space offset
- // later read from 0xCFC-0xCFF returns the value...
- u8 bus, devfn, offs;
- u32 port_cf8_val = my_inl(0xCF8);
- if ((port_cf8_val & 0x80000000) != 0) {
- //highest bit enables config space mapping
- bus = (port_cf8_val & 0x00FF0000) >> 16;
- devfn = (port_cf8_val & 0x0000FF00) >> 8;
- offs = (port_cf8_val & 0x000000FF);
- offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly
- DEBUG_PRINTF_INTR("%s(): PCI Config Read from device: bus: %02x, devfn: %02x, offset: %02x\n",
- __func__, bus, devfn, offs);
-#if defined(CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES) && CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES==1
- dev = dev_find_slot(bus, devfn);
- DEBUG_PRINTF_INTR("%s(): dev_find_slot() returned: %s\n",
- __func__, dev_path(dev));
- if (dev == 0) {
- // fail accesses to non-existent devices...
-#else
- dev = bios_device.dev;
- if ((bus != bios_device.bus)
- || (devfn != bios_device.devfn)) {
- // fail accesses to any device but ours...
-#endif
- printf
- ("%s(): Config read access invalid device! bus: %02x (%02x), devfn: %02x (%02x), offs: %02x\n",
- __func__, bus, bios_device.bus, devfn,
- bios_device.devfn, offs);
- SET_FLAG(F_CF);
- HALT_SYS();
- return 0;
- } else {
-#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
- switch (size) {
- case 1:
- rval = pci_read_config8(dev, offs);
- break;
- case 2:
- rval = pci_read_config16(dev, offs);
- break;
- case 4:
- rval = pci_read_config32(dev, offs);
- break;
- }
-#else
- rval =
- (u32) rtas_pci_config_read(bios_device.
- puid, size,
- bus, devfn,
- offs);
-#endif
- DEBUG_PRINTF_IO
- ("%s(%04x) PCI Config Read @%02x, size: %d --> 0x%08x\n",
- __func__, addr, offs, size, rval);
- }
- }
- }
- return rval;
-}
-
-void
-pci_cfg_write(X86EMU_pioAddr addr, u32 val, u8 size)
-{
- if ((addr >= 0xCFC) && ((addr + size) <= 0xD00)) {
- // PCI Configuration Mechanism 1 step 1
- // write to 0xCF8, sets bus, device, function and Config Space offset
- // later write to 0xCFC-0xCFF sets the value...
- u8 bus, devfn, offs;
- u32 port_cf8_val = my_inl(0xCF8);
- if ((port_cf8_val & 0x80000000) != 0) {
- //highest bit enables config space mapping
- bus = (port_cf8_val & 0x00FF0000) >> 16;
- devfn = (port_cf8_val & 0x0000FF00) >> 8;
- offs = (port_cf8_val & 0x000000FF);
- offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly
- if ((bus != bios_device.bus)
- || (devfn != bios_device.devfn)) {
- // fail accesses to any device but ours...
- printf
- ("Config write access invalid! PCI device %x:%x.%x, offs: %x\n",
- bus, devfn >> 3, devfn & 7, offs);
- HALT_SYS();
- } else {
-#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
- switch (size) {
- case 1:
- pci_write_config8(bios_device.dev, offs, val);
- break;
- case 2:
- pci_write_config16(bios_device.dev, offs, val);
- break;
- case 4:
- pci_write_config32(bios_device.dev, offs, val);
- break;
- }
-#else
- rtas_pci_config_write(bios_device.puid,
- size, bus, devfn, offs,
- val);
-#endif
- DEBUG_PRINTF_IO
- ("%s(%04x) PCI Config Write @%02x, size: %d <-- 0x%08x\n",
- __func__, addr, offs, size, val);
- }
- }
- }
-}
-
-u8
-handle_port_61h(void)
-{
- static u64 last_time = 0;
- u64 curr_time = get_time();
- u64 time_diff; // time since last call
- u32 period_ticks; // length of a period in ticks
- u32 nr_periods; //number of periods passed since last call
- // bit 4 should toggle with every (DRAM) refresh cycle... (66kHz??)
- time_diff = curr_time - last_time;
- // at 66kHz a period is ~ 15 ns long, converted to ticks: (tb_freq is ticks/second)
- // TODO: as long as the frequency does not change, we should not calculate this every time
- period_ticks = (15 * tb_freq) / 1000000;
- nr_periods = time_diff / period_ticks;
- // if the number if ticks passed since last call is odd, we toggle bit 4
- if ((nr_periods % 2) != 0) {
- *((u8 *) (bios_device.io_buffer + 0x61)) ^= 0x10;
- }
- //finally read the value from the io_buffer
- return *((u8 *) (bios_device.io_buffer + 0x61));
-}
-#endif