From bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 Mon Sep 17 00:00:00 2001 From: RajithaY Date: Tue, 25 Apr 2017 03:31:15 -0700 Subject: Adding qemu as a submodule of KVMFORNFV This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY --- qemu/roms/openbios/drivers/Kconfig | 59 - qemu/roms/openbios/drivers/adb_bus.c | 257 ---- qemu/roms/openbios/drivers/adb_bus.h | 104 -- qemu/roms/openbios/drivers/adb_kbd.c | 595 --------- qemu/roms/openbios/drivers/adb_kbd.h | 22 - qemu/roms/openbios/drivers/adb_mouse.c | 67 - qemu/roms/openbios/drivers/adb_mouse.h | 22 - qemu/roms/openbios/drivers/build.xml | 41 - qemu/roms/openbios/drivers/cgthree.fs | 197 --- qemu/roms/openbios/drivers/cuda.c | 439 ------- qemu/roms/openbios/drivers/cuda.h | 17 - qemu/roms/openbios/drivers/escc.c | 552 --------- qemu/roms/openbios/drivers/escc.h | 11 - qemu/roms/openbios/drivers/esp.c | 598 --------- qemu/roms/openbios/drivers/esp.fs | 18 - qemu/roms/openbios/drivers/esp.h | 269 ---- qemu/roms/openbios/drivers/floppy.c | 1179 ------------------ qemu/roms/openbios/drivers/floppy.h | 9 - qemu/roms/openbios/drivers/fw_cfg.c | 76 -- qemu/roms/openbios/drivers/hdreg.h | 289 ----- qemu/roms/openbios/drivers/ide.c | 1701 -------------------------- qemu/roms/openbios/drivers/ide.h | 213 ---- qemu/roms/openbios/drivers/iommu.c | 207 ---- qemu/roms/openbios/drivers/iommu.h | 102 -- qemu/roms/openbios/drivers/kbd.c | 116 -- qemu/roms/openbios/drivers/kbd.h | 108 -- qemu/roms/openbios/drivers/macio.c | 281 ----- qemu/roms/openbios/drivers/macio.h | 5 - qemu/roms/openbios/drivers/obio.c | 459 ------- qemu/roms/openbios/drivers/obio.h | 165 --- qemu/roms/openbios/drivers/pc_kbd.c | 236 ---- qemu/roms/openbios/drivers/pc_serial.c | 208 ---- qemu/roms/openbios/drivers/pci.c | 1600 ------------------------ qemu/roms/openbios/drivers/pci.fs | 40 - qemu/roms/openbios/drivers/pci.h | 96 -- qemu/roms/openbios/drivers/pci_database.c | 1275 ------------------- qemu/roms/openbios/drivers/pci_database.h | 57 - qemu/roms/openbios/drivers/sbus.c | 498 -------- qemu/roms/openbios/drivers/sbus.fs | 94 -- qemu/roms/openbios/drivers/scsi.h | 262 ---- qemu/roms/openbios/drivers/tcx.fs | 280 ----- qemu/roms/openbios/drivers/timer.c | 100 -- qemu/roms/openbios/drivers/timer.h | 62 - qemu/roms/openbios/drivers/usb.c | 587 --------- qemu/roms/openbios/drivers/usb.h | 357 ------ qemu/roms/openbios/drivers/usbhid.c | 579 --------- qemu/roms/openbios/drivers/usbohci.c | 926 -------------- qemu/roms/openbios/drivers/usbohci.h | 45 - qemu/roms/openbios/drivers/usbohci_private.h | 270 ---- qemu/roms/openbios/drivers/usbohci_rh.c | 212 ---- qemu/roms/openbios/drivers/vga.fs | 205 ---- qemu/roms/openbios/drivers/vga.h | 231 ---- qemu/roms/openbios/drivers/vga_load_regs.c | 496 -------- qemu/roms/openbios/drivers/vga_set_mode.c | 148 --- 54 files changed, 17042 deletions(-) delete mode 100644 qemu/roms/openbios/drivers/Kconfig delete mode 100644 qemu/roms/openbios/drivers/adb_bus.c delete mode 100644 qemu/roms/openbios/drivers/adb_bus.h delete mode 100644 qemu/roms/openbios/drivers/adb_kbd.c delete mode 100644 qemu/roms/openbios/drivers/adb_kbd.h delete mode 100644 qemu/roms/openbios/drivers/adb_mouse.c delete mode 100644 qemu/roms/openbios/drivers/adb_mouse.h delete mode 100644 qemu/roms/openbios/drivers/build.xml delete mode 100644 qemu/roms/openbios/drivers/cgthree.fs delete mode 100644 qemu/roms/openbios/drivers/cuda.c delete mode 100644 qemu/roms/openbios/drivers/cuda.h delete mode 100644 qemu/roms/openbios/drivers/escc.c delete mode 100644 qemu/roms/openbios/drivers/escc.h delete mode 100644 qemu/roms/openbios/drivers/esp.c delete mode 100644 qemu/roms/openbios/drivers/esp.fs delete mode 100644 qemu/roms/openbios/drivers/esp.h delete mode 100644 qemu/roms/openbios/drivers/floppy.c delete mode 100644 qemu/roms/openbios/drivers/floppy.h delete mode 100644 qemu/roms/openbios/drivers/fw_cfg.c delete mode 100644 qemu/roms/openbios/drivers/hdreg.h delete mode 100644 qemu/roms/openbios/drivers/ide.c delete mode 100644 qemu/roms/openbios/drivers/ide.h delete mode 100644 qemu/roms/openbios/drivers/iommu.c delete mode 100644 qemu/roms/openbios/drivers/iommu.h delete mode 100644 qemu/roms/openbios/drivers/kbd.c delete mode 100644 qemu/roms/openbios/drivers/kbd.h delete mode 100644 qemu/roms/openbios/drivers/macio.c delete mode 100644 qemu/roms/openbios/drivers/macio.h delete mode 100644 qemu/roms/openbios/drivers/obio.c delete mode 100644 qemu/roms/openbios/drivers/obio.h delete mode 100644 qemu/roms/openbios/drivers/pc_kbd.c delete mode 100644 qemu/roms/openbios/drivers/pc_serial.c delete mode 100644 qemu/roms/openbios/drivers/pci.c delete mode 100644 qemu/roms/openbios/drivers/pci.fs delete mode 100644 qemu/roms/openbios/drivers/pci.h delete mode 100644 qemu/roms/openbios/drivers/pci_database.c delete mode 100644 qemu/roms/openbios/drivers/pci_database.h delete mode 100644 qemu/roms/openbios/drivers/sbus.c delete mode 100644 qemu/roms/openbios/drivers/sbus.fs delete mode 100644 qemu/roms/openbios/drivers/scsi.h delete mode 100644 qemu/roms/openbios/drivers/tcx.fs delete mode 100644 qemu/roms/openbios/drivers/timer.c delete mode 100644 qemu/roms/openbios/drivers/timer.h delete mode 100644 qemu/roms/openbios/drivers/usb.c delete mode 100644 qemu/roms/openbios/drivers/usb.h delete mode 100644 qemu/roms/openbios/drivers/usbhid.c delete mode 100644 qemu/roms/openbios/drivers/usbohci.c delete mode 100644 qemu/roms/openbios/drivers/usbohci.h delete mode 100644 qemu/roms/openbios/drivers/usbohci_private.h delete mode 100644 qemu/roms/openbios/drivers/usbohci_rh.c delete mode 100644 qemu/roms/openbios/drivers/vga.fs delete mode 100644 qemu/roms/openbios/drivers/vga.h delete mode 100644 qemu/roms/openbios/drivers/vga_load_regs.c delete mode 100644 qemu/roms/openbios/drivers/vga_set_mode.c (limited to 'qemu/roms/openbios/drivers') diff --git a/qemu/roms/openbios/drivers/Kconfig b/qemu/roms/openbios/drivers/Kconfig deleted file mode 100644 index 3bebc0293..000000000 --- a/qemu/roms/openbios/drivers/Kconfig +++ /dev/null @@ -1,59 +0,0 @@ - - -menu "Drivers" - -config DRIVER_PCI - bool "PCI driver" - default y - help - Builtin PCI driver - -config DEBUG_PCI - bool "Debug PCI driver" - default n - help - Debug PCI driver - -config DRIVER_IDE - depends X86 || AMD64 || PPC - bool "Legacy IDE" - default y - help - If you want to be able to boot from IDE, enable this option. - -config IDE_NUM_CHANNELS - depends DRIVER_IDE - int "Number of IDE channels to be probed" - default 4 - help - Number of IDE channels to be probed. This should be set to - one or two if you build OpenBIOS for the Total Impact BRIQ. - -config DEBUG_IDE - depends DRIVER_IDE - bool "Debug IDE driver" - default n - help - Debug IDE driver - -config DRIVER_USB - bool "USB Support" - default n - help - If you want to be able to use USB devices, enable this option. - -config DEBUG_USB - depends DRIVER_USB - bool "Debug USB driver" - default n - help - Debug USB driver - -config USB_HID - depends DRIVER_USB - bool "USB driver for HID devices" - default n - help - If you want to be able to use USB keyboard, enable this option. - -endmenu diff --git a/qemu/roms/openbios/drivers/adb_bus.c b/qemu/roms/openbios/drivers/adb_bus.c deleted file mode 100644 index d67d1f1a4..000000000 --- a/qemu/roms/openbios/drivers/adb_bus.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * - * Open Hack'Ware BIOS ADB bus support, ported to OpenBIOS - * - * Copyright (c) 2005 Jocelyn Mayer - * Copyright (c) 2005 Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "libc/vsprintf.h" - -#include "adb_bus.h" -#include "adb_kbd.h" -#include "adb_mouse.h" - -DECLARE_UNNAMED_NODE( adb, INSTALL_OPEN, sizeof(int)); - -static void -adb_initialize (int *idx) -{ - phandle_t ph=get_cur_dev(); - - push_str("adb"); - fword("device-type"); - - set_property(ph, "compatible", "adb", 4); - set_int_property(ph, "#address-cells", 1); - set_int_property(ph, "#size-cells", 0); -} - -static void -adb_open(int *idx) -{ - RET(-1); -} - -static void -adb_close(int *idx) -{ -} - -NODE_METHODS( adb ) = { - { NULL, adb_initialize }, - { "open", adb_open }, - { "close", adb_close }, -}; - -adb_bus_t *adb_bus_new (void *host, - int (*req)(void *host, const uint8_t *snd_buf, - int len, uint8_t *rcv_buf)) -{ - adb_bus_t *new; - - new = malloc(sizeof(adb_bus_t)); - if (new == NULL) - return NULL; - new->host = host; - new->req = req; - - return new; -} - -/* Check and relocate all ADB devices as suggested in - * ADB_manager Apple documentation - */ - -int adb_bus_init (char *path, adb_bus_t *bus) -{ - char buf[64]; - uint8_t buffer[ADB_BUF_SIZE]; - uint8_t adb_addresses[16] = - { 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, 0, }; - adb_dev_t tmp_device, **cur; - int address; - int reloc = 0, next_free = 7; - int keep; - - snprintf(buf, sizeof(buf), "%s/adb", path); - REGISTER_NAMED_NODE( adb, buf); - /* Reset the bus */ - // ADB_DPRINTF("\n"); - adb_reset(bus); - cur = &bus->devices; - memset(&tmp_device, 0, sizeof(adb_dev_t)); - tmp_device.bus = bus; - for (address = 1; address < 8 && adb_addresses[reloc] > 0;) { - if (address == ADB_RES) { - /* Reserved */ - address++; - continue; - } - //ADB_DPRINTF("Check device on ADB address %d\n", address); - tmp_device.addr = address; - switch (adb_reg_get(&tmp_device, 3, buffer)) { - case 0: - //ADB_DPRINTF("No device on ADB address %d\n", address); - /* Register this address as free */ - if (adb_addresses[next_free] != 0) - adb_addresses[next_free++] = address; - /* Check next ADB address */ - address++; - break; - case 2: - /* One device answered : - * make it available and relocate it to a free address - */ - if (buffer[0] == ADB_CHADDR) { - /* device self test failed */ - ADB_DPRINTF("device on ADB address %d self-test failed " - "%02x %02x %02x\n", address, - buffer[0], buffer[1], buffer[2]); - keep = 0; - } else { - //ADB_DPRINTF("device on ADB address %d self-test OK\n", - // address); - keep = 1; - } - ADB_DPRINTF("Relocate device on ADB address %d to %d (%d)\n", - address, adb_addresses[reloc], reloc); - buffer[0] = ((buffer[0] & 0x40) & ~0x90) | adb_addresses[reloc]; - if (keep == 1) - buffer[0] |= 0x20; - buffer[1] = ADB_CHADDR_NOCOLL; - if (adb_reg_set(&tmp_device, 3, buffer, 2) < 0) { - ADB_DPRINTF("ADB device relocation failed\n"); - return -1; - } - if (keep == 1) { - *cur = malloc(sizeof(adb_dev_t)); - if (*cur == NULL) { - return -1; - } - (*cur)->type = address; - (*cur)->bus = bus; - (*cur)->addr = adb_addresses[reloc++]; - /* Flush buffers */ - adb_flush(*cur); - switch ((*cur)->type) { - case ADB_PROTECT: - ADB_DPRINTF("Found one protected device\n"); - break; - case ADB_KEYBD: - ADB_DPRINTF("Found one keyboard on address %d\n", address); - adb_kbd_new(buf, *cur); - break; - case ADB_MOUSE: - ADB_DPRINTF("Found one mouse on address %d\n", address); - adb_mouse_new(buf, *cur); - break; - case ADB_ABS: - ADB_DPRINTF("Found one absolute positioning device\n"); - break; - case ADB_MODEM: - ADB_DPRINTF("Found one modem\n"); - break; - case ADB_RES: - ADB_DPRINTF("Found one ADB res device\n"); - break; - case ADB_MISC: - ADB_DPRINTF("Found one ADB misc device\n"); - break; - } - cur = &((*cur)->next); - } - break; - case 1: - case 3 ... 7: - /* SHOULD NOT HAPPEN : register 3 is always two bytes long */ - ADB_DPRINTF("Invalid returned len for ADB register 3\n"); - return -1; - case -1: - /* ADB ERROR */ - ADB_DPRINTF("error gettting ADB register 3\n"); - return -1; - } - } - - return 0; -} - -int adb_cmd (adb_dev_t *dev, uint8_t cmd, uint8_t reg, - uint8_t *buf, int len) -{ - uint8_t adb_send[ADB_BUF_SIZE], adb_rcv[ADB_BUF_SIZE]; - - //ADB_DPRINTF("cmd: %d reg: %d len: %d\n", cmd, reg, len); - if (dev->bus == NULL || dev->bus->req == NULL) { - ADB_DPRINTF("ERROR: invalid bus !\n"); - for (;;); - } - /* Sanity checks */ - if (cmd != ADB_LISTEN && len != 0) { - /* No buffer transmitted but for LISTEN command */ - ADB_DPRINTF("in buffer for cmd %d\n", cmd); - return -1; - } - if (cmd == ADB_LISTEN && ((len < 2 || len > 8) || buf == NULL)) { - /* Need a buffer with a regular register size for LISTEN command */ - ADB_DPRINTF("no/invalid buffer for ADB_LISTEN (%d)\n", len); - return -1; - } - if ((cmd == ADB_TALK || cmd == ADB_LISTEN) && reg > 3) { - /* Need a valid register number for LISTEN and TALK commands */ - ADB_DPRINTF("invalid reg for TALK/LISTEN command (%d %d)\n", cmd, reg); - return -1; - } - switch (cmd) { - case ADB_SEND_RESET: - adb_send[0] = ADB_SEND_RESET; - break; - case ADB_FLUSH: - adb_send[0] = (dev->addr << 4) | ADB_FLUSH; - break; - case ADB_LISTEN: - memcpy(adb_send + 1, buf, len); - /* No break here */ - case ADB_TALK: - adb_send[0] = (dev->addr << 4) | cmd | reg; - break; - } - memset(adb_rcv, 0, ADB_BUF_SIZE); - len = (*dev->bus->req)(dev->bus->host, adb_send, len + 1, adb_rcv); -#ifdef DEBUG_ADB - //printk("%x %x %x %x\n", adb_rcv[0], adb_rcv[1], adb_rcv[2], adb_rcv[3]); -#endif - switch (len) { - case 0: - /* No data */ - break; - case 2 ... 8: - /* Register transmitted */ - if (buf != NULL) - memcpy(buf, adb_rcv, len); - break; - default: - /* Should never happen */ - //ADB_DPRINTF("Cmd %d returned %d bytes !\n", cmd, len); - return -1; - } - //ADB_DPRINTF("retlen: %d\n", len); - - return len; -} diff --git a/qemu/roms/openbios/drivers/adb_bus.h b/qemu/roms/openbios/drivers/adb_bus.h deleted file mode 100644 index 205b37536..000000000 --- a/qemu/roms/openbios/drivers/adb_bus.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * ADB bus definitions for Open Hack'Ware - * - * Copyright (c) 2004-2005 Jocelyn Mayer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -typedef struct adb_bus_t adb_bus_t; -typedef struct adb_dev_t adb_dev_t; - -#define ADB_BUF_SIZE 8 -struct adb_bus_t { - void *host; - int (*req)(void *host, const uint8_t *snd_buf, int len, uint8_t *rcv_buf); - adb_dev_t *devices; -}; - -struct adb_dev_t { - adb_dev_t *next; - adb_bus_t *bus; - uint8_t addr; - uint8_t type; - void *state; -}; - -#define ADB_BUF_SIZE 8 - -/* ADB commands */ -enum { - ADB_SEND_RESET = 0x00, - ADB_FLUSH = 0x01, - ADB_LISTEN = 0x08, - ADB_TALK = 0x0C, -}; -/* ADB default IDs before relocation */ -enum { - ADB_PROTECT = 0x01, - ADB_KEYBD = 0x02, - ADB_MOUSE = 0x03, - ADB_ABS = 0x04, - ADB_MODEM = 0x05, - ADB_RES = 0x06, - ADB_MISC = 0x07, -}; -/* ADB special device handlers IDs */ -enum { - ADB_CHADDR = 0x00, - ADB_CHADDR_ACTIV = 0xFD, - ADB_CHADDR_NOCOLL = 0xFE, - ADB_SELF_TEST = 0xFF, -}; - -int adb_cmd (adb_dev_t *dev, uint8_t cmd, uint8_t reg, - uint8_t *buf, int len); -void adb_bus_reset (adb_bus_t *bus); -adb_bus_t *adb_bus_new (void *host, - int (*req)(void *host, const uint8_t *snd_buf, - int len, uint8_t *rcv_buf)); -int adb_bus_init (char *path, adb_bus_t *bus); - -static inline int adb_reset (adb_bus_t *bus) -{ - adb_dev_t fake_device; - - memset(&fake_device, 0, sizeof(adb_dev_t)); - fake_device.bus = bus; - - return adb_cmd(&fake_device, ADB_SEND_RESET, 0, NULL, 0); -} - -static inline int adb_flush (adb_dev_t *dev) -{ - return adb_cmd(dev, ADB_FLUSH, 0, NULL, 0); -} - -static inline int adb_reg_get (adb_dev_t *dev, uint8_t reg, uint8_t *buf) -{ - return adb_cmd(dev, ADB_TALK, reg, buf, 0); -} - -static inline int adb_reg_set (adb_dev_t *dev, uint8_t reg, - uint8_t *buf, int len) -{ - return adb_cmd(dev, ADB_LISTEN, reg, buf, len); -} - -#ifdef DEBUG_ADB -#define ADB_DPRINTF(fmt, args...) \ -do { printk("ADB - %s: " fmt, __func__ , ##args); } while (0) -#else -#define ADB_DPRINTF(fmt, args...) do { } while (0) -#endif diff --git a/qemu/roms/openbios/drivers/adb_kbd.c b/qemu/roms/openbios/drivers/adb_kbd.c deleted file mode 100644 index be6099a03..000000000 --- a/qemu/roms/openbios/drivers/adb_kbd.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * - * Open Hack'Ware BIOS ADB keyboard support, ported to OpenBIOS - * - * Copyright (c) 2005 Jocelyn Mayer - * Copyright (c) 2005 Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" -#include "kbd.h" - -#include "adb_bus.h" -#include "adb_kbd.h" - -DECLARE_UNNAMED_NODE( keyboard, INSTALL_OPEN, sizeof(int)); - -static void -keyboard_open(int *idx) -{ - RET(-1); -} - -static void -keyboard_close(int *idx) -{ -} - -static void keyboard_read(void); -static void keyboard_getkeymap(void); - -NODE_METHODS( keyboard ) = { - { "open", keyboard_open }, - { "close", keyboard_close }, - { "read", keyboard_read }, - { "get-key-map", keyboard_getkeymap }, -}; - -/* VT100 escape sequences */ - -enum { - KEY_UP = 0, KEY_DOWN, KEY_RIGHT, KEY_LEFT, KEY_PAGE_UP, KEY_PAGE_DOWN, - KEY_DELETE, KEY_HOME, KEY_END, KEY_HELP, - KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, - KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16 -}; - -#define ADB_MAX_SEQUENCE_LEN 16 - -static const char *ADB_sequences[] = { - [KEY_UP] = "A[", - [KEY_DOWN] = "B[", - [KEY_RIGHT] = "C[", - [KEY_LEFT] = "D[", - [KEY_PAGE_UP] = "~5[", - [KEY_PAGE_DOWN] = "~6[", - [KEY_DELETE] = "~3[", - [KEY_HOME] = "HO", - [KEY_END] = "FO", - [KEY_HELP] = "~2[", - [KEY_F1] = "PO", - [KEY_F2] = "QO", - [KEY_F3] = "RO", - [KEY_F4] = "SO", - [KEY_F5] = "~15[", - [KEY_F6] = "~17[", - [KEY_F7] = "~18[", - [KEY_F8] = "~19[", - [KEY_F9] = "~20[", - [KEY_F10] = "~21[", - [KEY_F11] = "~23[", - [KEY_F12] = "~24[", - [KEY_F13] = "~25[", - [KEY_F14] = "~26[", - [KEY_F15] = "~28[", - [KEY_F15] = "~29[", -}; - -/* ADB US keyboard translation map */ - -static const keymap_t ADB_kbd_us[] = { - /* 0x00 */ - { KBD_SH_CAPS, { 0x61, 0x41, 0x01, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x73, 0x53, 0x13, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x64, 0x44, 0x04, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x66, 0x46, 0x06, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x68, 0x48, 0x08, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x67, 0x47, 0x07, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x7A, 0x5A, 0x1A, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x78, 0x58, 0x18, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x08 */ - { KBD_SH_CAPS, { 0x63, 0x43, 0x03, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x76, 0x56, 0x16, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x60, 0x40, 0x00, -1, -1, -1, -1, -1, /* ? */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x62, 0x42, 0x02, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x71, 0x51, 0x11, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x77, 0x57, 0x17, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x65, 0x45, 0x05, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x72, 0x52, 0x12, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x10 */ - { KBD_SH_CAPS, { 0x79, 0x59, 0x19, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x74, 0x54, 0x14, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x31, 0x21, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x32, 0x40, 0x00, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x33, 0x23, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x34, 0x24, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x36, 0x5E, 0x1E, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x35, 0x25, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x18 */ - { KBD_SH_CAPS, { 0x3D, 0x2B, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x39, 0x28, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x37, 0x26, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x2D, 0x5F, 0x1F, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x38, 0x2A, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x30, 0x29, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x5D, 0x7D, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x6F, 0x4F, 0x0F, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x20 */ - { KBD_SH_CAPS, { 0x75, 0x55, 0x15, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x5B, 0x7B, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x69, 0x49, 0x09, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x70, 0x50, 0x10, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MOD_MAP(0x0D), }, - { KBD_SH_CAPS, { 0x6C, 0x4C, 0x0C, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x6A, 0x4A, 0x0A, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x27, 0x22, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x28 */ - { KBD_SH_CAPS, { 0x6B, 0x4B, 0x0B, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x3B, 0x3A, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x5C, 0x7C, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x2C, 0x3C, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x2F, 0x3F, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x6E, 0x4E, 0x0E, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x6D, 0x4D, 0x0D, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_CAPS, { 0x2E, 0x3E, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x30 : tab */ - { KBD_MOD_MAP(0x09), }, - /* 0x31 : space */ - { KBD_MOD_MAP(0x20), }, - /* 0x32 : '<' '>' */ - { KBD_SH_CAPS, { 0x3C, 0x3E, -1, -1, -1, -1, -1, -1, /* ? */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x33 : backspace */ - { KBD_MOD_MAP(0x08), }, - { KBD_MAP_NONE, }, - /* 0x35 : ESC */ - { KBD_MOD_MAP(0x1B), }, - /* 0x36 : control */ - { KBD_MOD_MAP_LCTRL, }, - /* 0x37 : command */ - { KBD_MOD_MAP_LCMD, }, - /* 0x38 : left shift */ - { KBD_MOD_MAP_LSHIFT, }, - /* 0x39 : caps-lock */ - { KBD_MOD_MAP_CAPS, }, - /* 0x3A : option */ - { KBD_MOD_MAP_LOPT, }, - /* 0x3B : left */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_LEFT)), }, - /* 0x3C : right */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_RIGHT)), }, - /* 0x3D : down */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_DOWN)), }, - /* 0x3E : up */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_UP)), }, - { KBD_MAP_NONE, }, - /* 0x40 */ - { KBD_MAP_NONE, }, - { KBD_SH_NUML, { 0x7F, 0x2E, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MAP_NONE, }, - { KBD_SH_NONE, { 0x2A, 0x2A, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MAP_NONE, }, - { KBD_SH_NONE, { 0x2B, 0x2B, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MAP_NONE, }, - { KBD_MOD_MAP(0x7F), }, - /* 0x48 */ - { KBD_MAP_NONE, }, - { KBD_MAP_NONE, }, - { KBD_MAP_NONE, }, - { KBD_SH_NONE, { 0x2F, 0x2F, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MOD_MAP(0x0D), }, - { KBD_MAP_NONE, }, - { KBD_SH_NONE, { 0x2D, 0x2D, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MAP_NONE, }, - /* 0x50 */ - { KBD_MAP_NONE, }, - { KBD_SH_NONE, { 0x3D, 0x3D, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x30, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x31, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x32, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x33, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x34, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x35, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - /* 0x58 */ - { KBD_SH_NUML, { -1, 0x36, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x37, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MAP_NONE, }, - { KBD_SH_NUML, { -1, 0x38, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_SH_NUML, { -1, 0x39, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, }, }, - { KBD_MAP_NONE, }, - { KBD_MOD_MAP(0x2F), }, - { KBD_MAP_NONE, }, - /* 0x60 : F5 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F5)), }, - /* 0x61 : F6 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F6)), }, - /* 0x62 : F7 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F7)), }, - /* 0x63 : F3 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F3)), }, - /* 0x64 : F8 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F8)), }, - /* 0x65 : F9 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F9)), }, - { KBD_MAP_NONE, }, - /* 0x67 : F11 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F11)), }, - /* 0x68 */ - { KBD_MAP_NONE, }, - /* 0x69 : F13 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F13)), }, - { KBD_MAP_NONE, }, - /* 0x6B : F14 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F14)), }, - { KBD_MAP_NONE, }, - /* 0x6D : F10 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F10)), }, - { KBD_MAP_NONE, }, - /* 0x6F : F12 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F12)), }, - /* 0x70 */ - { KBD_MAP_NONE, }, - /* 0x71 : F15 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F15)), }, - /* 0x72 : help */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_HELP)), }, - /* 0x73 : home */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_HOME)), }, - /* 0x74 : page up */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_PAGE_UP)), }, - /* 0x75 : del */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_DELETE)), }, - /* 0x76 : F4 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F4)), }, - /* 0x77 : end */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_END)), }, - /* 0x78 : F2 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F2)), }, - /* 0x79 : page down */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_PAGE_UP)), }, - /* 0x7A : F1 */ - { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F1)), }, - /* 0x7B : right shift */ - { KBD_MOD_MAP_RSHIFT, }, - /* 0x7C : right option */ - { KBD_MOD_MAP_ROPT, }, - /* 0x7D : right control */ - { KBD_MOD_MAP_RCTRL, }, - { KBD_MAP_NONE, }, - /* 0x7F : power */ - { KBD_MAP_NONE, }, -}; - -typedef struct adb_kbd_t adb_kbd_t; -struct adb_kbd_t { - kbd_t kbd; - int next_key; - char sequence[ADB_MAX_SEQUENCE_LEN]; - int len; - char keytable[32]; -}; - -static adb_dev_t *my_adb_dev = NULL; - -static int adb_kbd_read (void *private) -{ - uint8_t buffer[ADB_BUF_SIZE]; - adb_dev_t *dev = private; - adb_kbd_t *kbd; - int key; - int ret; - - kbd = dev->state; - - if (kbd->len > 0) { - ret = kbd->sequence[kbd->len-- - 1]; - ADB_DPRINTF("Buffered %d (%02x)\n", ret, ret); - return ret; - } - - /* Get saved state */ - ret = -1; - for (key = -1; key == -1; ) { - if (kbd->next_key != -1) { - key = kbd->next_key; - kbd->next_key = -1; - } else { - if (adb_reg_get(dev, 0, buffer) != 2) - break; - kbd->next_key = buffer[1] == 0xFF ? -1 : buffer[1]; - key = buffer[0]; - } - ret = kbd_translate_key(&kbd->kbd, key & 0x7F, key >> 7, kbd->sequence); - if (ret > 0) { - kbd->len = ret; - ret = kbd->sequence[kbd->len-- - 1]; - } - - ADB_DPRINTF("Translated %d (%02x) into %d (%02x)\n", - key, key, ret, ret); - } - - return ret; -} - - -void *adb_kbd_new (char *path, void *private) -{ - char buf[64]; - int props[1]; - phandle_t ph, aliases; - adb_kbd_t *kbd; - adb_dev_t *dev = private; - kbd = (adb_kbd_t*)malloc(sizeof(adb_kbd_t)); - if (kbd != NULL) { - memset(kbd, 0, sizeof(adb_kbd_t)); - kbd_set_keymap(&kbd->kbd, sizeof(ADB_kbd_us) / sizeof(keymap_t), - ADB_kbd_us, ADB_sequences); - kbd->next_key = -1; - kbd->len = 0; - - /* Debugging BootX: the lines below force get-key-map to report that - * cmd-V is being held down, which forces BootX to run in verbose mode - * for debugging. - * - * TODO: if we can find a mapping between the get-key-map bitmap and - * ADB scancodes, the keyboard driver should be altered to update this - * accordingly. - */ - - /* - kbd->keytable[3] = 0x40; - kbd->keytable[28] = 0x10; - */ - - dev->state = kbd; - my_adb_dev = dev; - } - - snprintf(buf, sizeof(buf), "%s/keyboard", path); - REGISTER_NAMED_NODE( keyboard, buf); - - ph = find_dev(buf); - - set_property(ph, "device_type", "keyboard", 9); - props[0] = __cpu_to_be32(dev->addr); - set_property(ph, "reg", (char *)&props, sizeof(props)); - - aliases = find_dev("/aliases"); - set_property(aliases, "adb-keyboard", buf, strlen(buf) + 1); - - return kbd; -} - -/* ( addr len -- actual ) */ -static void keyboard_read(void) -{ - char *addr; - int len, key, i; - len=POP(); - addr=(char *)cell2pointer(POP()); - - for (i = 0; i < len; i++) { - key = adb_kbd_read(my_adb_dev); - if (key == -1 || key == -2) - break; - *addr++ = (char)key; - } - PUSH(i); -} - -/* ( -- keymap ) (?) */ -/* should return a pointer to an array with 32 bytes (256 bits) */ -static void keyboard_getkeymap(void) -{ - adb_kbd_t *kbd = my_adb_dev->state; - - PUSH( pointer2cell(kbd->keytable) ); -} diff --git a/qemu/roms/openbios/drivers/adb_kbd.h b/qemu/roms/openbios/drivers/adb_kbd.h deleted file mode 100644 index b219c12e7..000000000 --- a/qemu/roms/openbios/drivers/adb_kbd.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * - * Open Hack'Ware BIOS ADB keyboard support, ported to OpenBIOS - * - * Copyright (c) 2005 Jocelyn Mayer - * Copyright (c) 2005 Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -void *adb_kbd_new (char *path, void *private); diff --git a/qemu/roms/openbios/drivers/adb_mouse.c b/qemu/roms/openbios/drivers/adb_mouse.c deleted file mode 100644 index b94a34420..000000000 --- a/qemu/roms/openbios/drivers/adb_mouse.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Open Hack'Ware BIOS ADB mouse support, ported to OpenBIOS - * - * Copyright (c) 2005 Jocelyn Mayer - * Copyright (c) 2005 Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "adb_bus.h" -#include "adb_mouse.h" - -DECLARE_UNNAMED_NODE( mouse, INSTALL_OPEN, sizeof(int)); - -static void -mouse_open(int *idx) -{ - RET(-1); -} - -static void -mouse_close(int *idx) -{ -} - -NODE_METHODS( mouse ) = { - { "open", mouse_open }, - { "close", mouse_close }, -}; - -void adb_mouse_new (char *path, void *private) -{ - char buf[64]; - int props[1]; - phandle_t ph, aliases; - adb_dev_t *dev = private; - - snprintf(buf, sizeof(buf), "%s/mouse", path); - REGISTER_NAMED_NODE( mouse, buf); - - ph = find_dev(buf); - - set_property(ph, "device_type", "mouse", 6); - props[0] = __cpu_to_be32(dev->addr); - set_property(ph, "reg", (char *)&props, sizeof(props)); - set_int_property(ph, "#buttons", 3); - - aliases = find_dev("/aliases"); - set_property(aliases, "adb-mouse", buf, strlen(buf) + 1); -} diff --git a/qemu/roms/openbios/drivers/adb_mouse.h b/qemu/roms/openbios/drivers/adb_mouse.h deleted file mode 100644 index 1f37dac7c..000000000 --- a/qemu/roms/openbios/drivers/adb_mouse.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * - * Open Hack'Ware BIOS ADB mouse support, ported to OpenBIOS - * - * Copyright (c) 2005 Jocelyn Mayer - * Copyright (c) 2005 Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -void adb_mouse_new (char *path, void *private); diff --git a/qemu/roms/openbios/drivers/build.xml b/qemu/roms/openbios/drivers/build.xml deleted file mode 100644 index bd1abd358..000000000 --- a/qemu/roms/openbios/drivers/build.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/qemu/roms/openbios/drivers/cgthree.fs b/qemu/roms/openbios/drivers/cgthree.fs deleted file mode 100644 index aa0c90cdd..000000000 --- a/qemu/roms/openbios/drivers/cgthree.fs +++ /dev/null @@ -1,197 +0,0 @@ -\ -\ Fcode payload for QEMU CG3 graphics card -\ -\ This is the Forth source for an Fcode payload to initialise -\ the QEMU CG3 graphics card. -\ -\ (C) Copyright 2013 Mark Cave-Ayland -\ - -fcode-version3 - -\ -\ Instead of using fixed values for the framebuffer address and the width -\ and height, grab the ones passed in by QEMU/generated by OpenBIOS -\ - -: (find-xt) \ ( str len -- xt | -1 ) - $find if - exit - else - 2drop - -1 - then -; - -: (is-openbios) \ ( -- true | false ) - " openbios-video-width" (find-xt) -1 <> if - -1 - else - 0 - then -; - -" openbios-video-width" (find-xt) cell+ value openbios-video-width-xt -" openbios-video-height" (find-xt) cell+ value openbios-video-height-xt -" depth-bits" (find-xt) cell+ value depth-bits-xt -" line-bytes" (find-xt) cell+ value line-bytes-xt -" debug-type" (find-xt) value debug-type-xt - -: openbios-video-width - (is-openbios) if - openbios-video-width-xt @ - else - h# 400 - then -; - -: openbios-video-height - (is-openbios) if - openbios-video-height-xt @ - else - h# 300 - then -; - -: depth-bits - (is-openbios) if - depth-bits-xt @ - else - h# 8 - then -; - -: line-bytes - (is-openbios) if - line-bytes-xt @ - else - h# 400 - then -; - -: debug-type debug-type-xt execute ; - -\ -\ Registers -\ - -h# 400000 constant cg3-off-dac -h# 20 constant /cg3-off-dac - -h# 800000 constant cg3-off-fb -h# c0000 constant /cg3-off-fb - -: >cg3-reg-spec ( offset size -- encoded-reg ) - >r 0 my-address d+ my-space encode-phys r> encode-int encode+ -; - -: cg3-reg - \ A real cg3 rom appears to just map the entire region with a - \ single entry - h# 0 h# 1000000 >cg3-reg-spec - " reg" property -; - -: do-map-in ( offset size -- virt ) - >r my-space r> " map-in" $call-parent -; - -: do-map-out ( virt size ) - " map-out" $call-parent -; - -\ -\ DAC -\ - --1 value cg3-dac --1 value fb-addr - -: dac! ( data reg# -- ) - cg3-dac + c! -; - -external - -: color! ( r g b c# -- ) - 0 dac! ( r g b ) - swap rot ( b g r ) - 4 dac! ( b g ) - 4 dac! ( b ) - 4 dac! ( ) -; - -headerless - -\ -\ Mapping -\ - -: dac-map - cg3-off-dac /cg3-off-dac do-map-in to cg3-dac -; - -: fb-map - cg3-off-fb h# c0000 do-map-in to fb-addr -; - -: map-regs - dac-map fb-map -; - -\ -\ Installation -\ - -" cgthree" device-name -" display" device-type -" SUNW,501-1415" model - -: qemu-cg3-driver-install ( -- ) - cg3-dac -1 = if - map-regs - - \ Initial pallette taken from Sun's "Writing FCode Programs" - h# ff h# ff h# ff h# 0 color! \ Background white - h# 0 h# 0 h# 0 h# ff color! \ Foreground black - h# 64 h# 41 h# b4 h# 1 color! \ SUN-blue logo - - fb-addr to frame-buffer-adr - default-font set-font - - frame-buffer-adr encode-int " address" property - - openbios-video-width openbios-video-height over char-width / over char-height / - fb8-install - then -; - -: qemu-cg3-driver-init - - cg3-reg - - openbios-video-height encode-int " height" property - openbios-video-width encode-int " width" property - line-bytes encode-int " linebytes" property - - h# 39 encode-int 0 encode-int encode+ " intr" property - - \ Monitor sense. Some searching suggests that this is - \ 5 for 1024x768 and 7 for 1152x900 - openbios-video-width h# 480 = if - h# 7 - else - h# 5 - then - encode-int " monitor-sense" property - - " SUNW" encode-string " manufacturer" property - " ISO8859-1" encode-string " character-set" property - h# c encode-int " cursorshift" property - - ['] qemu-cg3-driver-install is-install -; - -qemu-cg3-driver-init - -end0 diff --git a/qemu/roms/openbios/drivers/cuda.c b/qemu/roms/openbios/drivers/cuda.c deleted file mode 100644 index ff5d22de2..000000000 --- a/qemu/roms/openbios/drivers/cuda.c +++ /dev/null @@ -1,439 +0,0 @@ -#include "config.h" -#include "libopenbios/bindings.h" -#include "drivers/drivers.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "macio.h" -#include "cuda.h" - -//#define DEBUG_CUDA -#ifdef DEBUG_CUDA -#define CUDA_DPRINTF(fmt, args...) \ - do { printk("CUDA - %s: " fmt, __func__ , ##args); } while (0) -#else -#define CUDA_DPRINTF(fmt, args...) do { } while (0) -#endif - -#define IO_CUDA_OFFSET 0x00016000 -#define IO_CUDA_SIZE 0x00002000 - -/* VIA registers - spaced 0x200 bytes apart */ -#define RS 0x200 /* skip between registers */ -#define B 0 /* B-side data */ -#define A RS /* A-side data */ -#define DIRB (2*RS) /* B-side direction (1=output) */ -#define DIRA (3*RS) /* A-side direction (1=output) */ -#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ -#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ -#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ -#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ -#define T2CL (8*RS) /* Timer 2 ctr/latch (low 8 bits) */ -#define T2CH (9*RS) /* Timer 2 counter (high 8 bits) */ -#define SR (10*RS) /* Shift register */ -#define ACR (11*RS) /* Auxiliary control register */ -#define PCR (12*RS) /* Peripheral control register */ -#define IFR (13*RS) /* Interrupt flag register */ -#define IER (14*RS) /* Interrupt enable register */ -#define ANH (15*RS) /* A-side data, no handshake */ - -/* Bits in B data register: all active low */ -#define TREQ 0x08 /* Transfer request (input) */ -#define TACK 0x10 /* Transfer acknowledge (output) */ -#define TIP 0x20 /* Transfer in progress (output) */ - -/* Bits in ACR */ -#define SR_CTRL 0x1c /* Shift register control bits */ -#define SR_EXT 0x0c /* Shift on external clock */ -#define SR_OUT 0x10 /* Shift out if 1 */ - -/* Bits in IFR and IER */ -#define IER_SET 0x80 /* set bits in IER */ -#define IER_CLR 0 /* clear bits in IER */ -#define SR_INT 0x04 /* Shift register full/empty */ - -#define CUDA_BUF_SIZE 16 - -#define ADB_PACKET 0 -#define CUDA_PACKET 1 - -/* CUDA commands (2nd byte) */ -#define CUDA_GET_TIME 0x03 -#define CUDA_SET_TIME 0x09 -#define CUDA_POWERDOWN 0x0a -#define CUDA_RESET_SYSTEM 0x11 - -static uint8_t cuda_readb (cuda_t *dev, int reg) -{ - return *(volatile uint8_t *)(dev->base + reg); -} - -static void cuda_writeb (cuda_t *dev, int reg, uint8_t val) -{ - *(volatile uint8_t *)(dev->base + reg) = val; -} - -static void cuda_wait_irq (cuda_t *dev) -{ - int val; - -// CUDA_DPRINTF("\n"); - for(;;) { - val = cuda_readb(dev, IFR); - cuda_writeb(dev, IFR, val & 0x7f); - if (val & SR_INT) - break; - } -} - - - -static int cuda_request (cuda_t *dev, uint8_t pkt_type, const uint8_t *buf, - int buf_len, uint8_t *obuf) -{ - int i, obuf_len, val; - - cuda_writeb(dev, ACR, cuda_readb(dev, ACR) | SR_OUT); - cuda_writeb(dev, SR, pkt_type); - cuda_writeb(dev, B, cuda_readb(dev, B) & ~TIP); - if (buf) { - //CUDA_DPRINTF("Send buf len: %d\n", buf_len); - /* send 'buf' */ - for(i = 0; i < buf_len; i++) { - cuda_wait_irq(dev); - cuda_writeb(dev, SR, buf[i]); - cuda_writeb(dev, B, cuda_readb(dev, B) ^ TACK); - } - } - cuda_wait_irq(dev); - cuda_writeb(dev, ACR, cuda_readb(dev, ACR) & ~SR_OUT); - cuda_readb(dev, SR); - cuda_writeb(dev, B, cuda_readb(dev, B) | TIP | TACK); - - obuf_len = 0; - if (obuf) { - cuda_wait_irq(dev); - cuda_readb(dev, SR); - cuda_writeb(dev, B, cuda_readb(dev, B) & ~TIP); - for(;;) { - cuda_wait_irq(dev); - val = cuda_readb(dev, SR); - if (obuf_len < CUDA_BUF_SIZE) - obuf[obuf_len++] = val; - if (cuda_readb(dev, B) & TREQ) - break; - cuda_writeb(dev, B, cuda_readb(dev, B) ^ TACK); - } - cuda_writeb(dev, B, cuda_readb(dev, B) | TIP | TACK); - - cuda_wait_irq(dev); - cuda_readb(dev, SR); - } -// CUDA_DPRINTF("Got len: %d\n", obuf_len); - - return obuf_len; -} - - - -static int cuda_adb_req (void *host, const uint8_t *snd_buf, int len, - uint8_t *rcv_buf) -{ - uint8_t buffer[CUDA_BUF_SIZE], *pos; - - // CUDA_DPRINTF("len: %d %02x\n", len, snd_buf[0]); - len = cuda_request(host, ADB_PACKET, snd_buf, len, buffer); - if (len > 1 && buffer[0] == ADB_PACKET) { - /* We handle 2 types of ADB packet here: - Normal: ... - Error : ( ...) - Ideally we should use buffer[1] (status) to determine whether this - is a normal or error packet but this requires a corresponding fix - in QEMU <= 2.4. Hence we temporarily handle it this way to ease - the transition. */ - if (len > 2 && buffer[2] == snd_buf[0]) { - /* Error */ - pos = buffer + 3; - len -= 3; - } else { - /* Normal */ - pos = buffer + 2; - len -= 2; - } - } else { - pos = buffer + 1; - len = -1; - } - memcpy(rcv_buf, pos, len); - - return len; -} - - -DECLARE_UNNAMED_NODE(ob_cuda, INSTALL_OPEN, sizeof(int)); - -static cuda_t *main_cuda; - -static void -ppc32_reset_all(void) -{ - uint8_t cmdbuf[2], obuf[64]; - - cmdbuf[0] = CUDA_RESET_SYSTEM; - cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf); -} - -static void -ppc32_poweroff(void) -{ - uint8_t cmdbuf[2], obuf[64]; - - cmdbuf[0] = CUDA_POWERDOWN; - cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf); -} - -static void -ob_cuda_initialize (int *idx) -{ - phandle_t ph=get_cur_dev(); - int props[2]; - - push_str("via-cuda"); - fword("device-type"); - - set_int_property(ph, "#address-cells", 1); - set_int_property(ph, "#size-cells", 0); - - set_property(ph, "compatible", "cuda", 5); - - props[0] = __cpu_to_be32(IO_CUDA_OFFSET); - props[1] = __cpu_to_be32(IO_CUDA_SIZE); - - set_property(ph, "reg", (char *)&props, sizeof(props)); - - /* on newworld machines the cuda is on interrupt 0x19 */ - - props[0] = 0x19; - props[1] = 0; - NEWWORLD(set_property(ph, "interrupts", (char *)props, sizeof(props))); - NEWWORLD(set_int_property(ph, "#interrupt-cells", 2)); - - /* we emulate an oldworld hardware, so we must use - * non-standard oldworld property (needed by linux 2.6.18) - */ - - OLDWORLD(set_int_property(ph, "AAPL,interrupts", 0x12)); - - bind_func("ppc32-reset-all", ppc32_reset_all); - push_str("' ppc32-reset-all to reset-all"); - fword("eval"); -} - -static void -ob_cuda_open(int *idx) -{ - RET(-1); -} - -static void -ob_cuda_close(int *idx) -{ -} - -NODE_METHODS(ob_cuda) = { - { NULL, ob_cuda_initialize }, - { "open", ob_cuda_open }, - { "close", ob_cuda_close }, -}; - -DECLARE_UNNAMED_NODE(rtc, INSTALL_OPEN, sizeof(int)); - -static void -rtc_open(int *idx) -{ - RET(-1); -} - -/* - * get-time ( -- second minute hour day month year ) - * - */ - -static const int days_month[12] = - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -static const int days_month_leap[12] = - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -static inline int is_leap(int year) -{ - return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); -} - -static void -rtc_get_time(int *idx) -{ - uint8_t cmdbuf[2], obuf[64]; - ucell second, minute, hour, day, month, year; - uint32_t now; - int current; - const int *days; - - cmdbuf[0] = CUDA_GET_TIME; - cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf); - - /* seconds since 01/01/1904 */ - - now = (obuf[3] << 24) + (obuf[4] << 16) + (obuf[5] << 8) + obuf[6]; - - second = now % 60; - now /= 60; - - minute = now % 60; - now /= 60; - - hour = now % 24; - now /= 24; - - year = now * 100 / 36525; - now -= year * 36525 / 100; - year += 1904; - - days = is_leap(year) ? days_month_leap : days_month; - - current = 0; - month = 0; - while (month < 12) { - if (now <= current + days[month]) { - break; - } - current += days[month]; - month++; - } - month++; - - day = now - current; - - PUSH(second); - PUSH(minute); - PUSH(hour); - PUSH(day); - PUSH(month); - PUSH(year); -} - -/* - * set-time ( second minute hour day month year -- ) - * - */ - -static void -rtc_set_time(int *idx) -{ - uint8_t cmdbuf[5], obuf[3]; - ucell second, minute, hour, day, month, year; - const int *days; - uint32_t now; - unsigned int nb_days; - int i; - - year = POP(); - month = POP(); - day = POP(); - hour = POP(); - minute = POP(); - second = POP(); - - days = is_leap(year) ? days_month_leap : days_month; - nb_days = (year - 1904) * 36525 / 100 + day; - for (i = 0; i < month - 1; i++) - nb_days += days[i]; - - now = (((nb_days * 24) + hour) * 60 + minute) * 60 + second; - - cmdbuf[0] = CUDA_SET_TIME; - cmdbuf[1] = now >> 24; - cmdbuf[2] = now >> 16; - cmdbuf[3] = now >> 8; - cmdbuf[4] = now; - - cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf); -} - -NODE_METHODS(rtc) = { - { "open", rtc_open }, - { "get-time", rtc_get_time }, - { "set-time", rtc_set_time }, -}; - -static void -rtc_init(char *path) -{ - phandle_t ph, aliases; - char buf[64]; - - snprintf(buf, sizeof(buf), "%s/rtc", path); - REGISTER_NAMED_NODE(rtc, buf); - - ph = find_dev(buf); - set_property(ph, "device_type", "rtc", 4); - set_property(ph, "compatible", "rtc", 4); - - aliases = find_dev("/aliases"); - set_property(aliases, "rtc", buf, strlen(buf) + 1); - -} - -static void -powermgt_init(char *path) -{ - phandle_t ph; - char buf[64]; - - snprintf(buf, sizeof(buf), "%s/power-mgt", path); - REGISTER_NAMED_NODE(rtc, buf); - - ph = find_dev(buf); - set_property(ph, "device_type", "power-mgt", 10); - set_property(ph, "mgt-kind", "min-consumption-pwm-led", strlen("min-consumption-pwm-led") + 1); - set_property(ph, "compatible", "cuda", strlen("cuda") + 1); -} - -cuda_t *cuda_init (const char *path, phys_addr_t base) -{ - cuda_t *cuda; - char buf[64]; - phandle_t aliases; - - base += IO_CUDA_OFFSET; - CUDA_DPRINTF(" base=" FMT_plx "\n", base); - cuda = malloc(sizeof(cuda_t)); - if (cuda == NULL) - return NULL; - - snprintf(buf, sizeof(buf), "%s/via-cuda", path); - REGISTER_NAMED_NODE(ob_cuda, buf); - - aliases = find_dev("/aliases"); - set_property(aliases, "via-cuda", buf, strlen(buf) + 1); - - cuda->base = base; - cuda_writeb(cuda, B, cuda_readb(cuda, B) | TREQ | TIP); -#ifdef CONFIG_DRIVER_ADB - cuda->adb_bus = adb_bus_new(cuda, &cuda_adb_req); - if (cuda->adb_bus == NULL) { - free(cuda); - return NULL; - } - adb_bus_init(buf, cuda->adb_bus); -#endif - - rtc_init(buf); - powermgt_init(buf); - - main_cuda = cuda; - - device_end(); - bind_func("poweroff", ppc32_poweroff); - - return cuda; -} diff --git a/qemu/roms/openbios/drivers/cuda.h b/qemu/roms/openbios/drivers/cuda.h deleted file mode 100644 index d3818c03c..000000000 --- a/qemu/roms/openbios/drivers/cuda.h +++ /dev/null @@ -1,17 +0,0 @@ -#include "adb_bus.h" - -struct cuda_t { - phys_addr_t base; - adb_bus_t *adb_bus; -}; -typedef struct cuda_t cuda_t; - -enum { - CHARDEV_KBD = 0, - CHARDEV_MOUSE, - CHARDEV_SERIAL, - CHARDEV_DISPLAY, - CHARDEV_LAST, -}; - -cuda_t *cuda_init (const char *path, phys_addr_t base); diff --git a/qemu/roms/openbios/drivers/escc.c b/qemu/roms/openbios/drivers/escc.c deleted file mode 100644 index 1990e798d..000000000 --- a/qemu/roms/openbios/drivers/escc.c +++ /dev/null @@ -1,552 +0,0 @@ -#include "config.h" -#include "libopenbios/bindings.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" -#include "drivers/drivers.h" -#include "libopenbios/ofmem.h" - -#include "escc.h" - -/* ****************************************************************** - * serial console functions - * ****************************************************************** */ - -static volatile unsigned char *escc_serial_dev; - -#define CTRL(addr) (*(volatile unsigned char *)(uintptr_t)(addr)) -#ifdef CONFIG_DRIVER_ESCC_SUN -#define DATA(addr) (*(volatile unsigned char *)(uintptr_t)(addr + 2)) -#else -#define DATA(addr) (*(volatile unsigned char *)(uintptr_t)(addr + 16)) -#endif - -/* Conversion routines to/from brg time constants from/to bits - * per second. - */ -#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) - -#ifdef CONFIG_DRIVER_ESCC_SUN -#define ESCC_CLOCK 4915200 /* Zilog input clock rate. */ -#else -#define ESCC_CLOCK 3686400 -#endif -#define ESCC_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ - -/* Write Register 3 */ -#define RxENAB 0x1 /* Rx Enable */ -#define Rx8 0xc0 /* Rx 8 Bits/Character */ - -/* Write Register 4 */ -#define SB1 0x4 /* 1 stop bit/char */ -#define X16CLK 0x40 /* x16 clock mode */ - -/* Write Register 5 */ -#define RTS 0x2 /* RTS */ -#define TxENAB 0x8 /* Tx Enable */ -#define Tx8 0x60 /* Tx 8 bits/character */ -#define DTR 0x80 /* DTR */ - -/* Write Register 14 (Misc control bits) */ -#define BRENAB 1 /* Baud rate generator enable */ -#define BRSRC 2 /* Baud rate generator source */ - -/* Read Register 0 */ -#define Rx_CH_AV 0x1 /* Rx Character Available */ -#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ - -int escc_uart_charav(uintptr_t port) -{ - return (CTRL(port) & Rx_CH_AV) != 0; -} - -char escc_uart_getchar(uintptr_t port) -{ - while (!escc_uart_charav(port)) - ; - return DATA(port) & 0177; -} - -static void escc_uart_port_putchar(uintptr_t port, unsigned char c) -{ - if (!escc_serial_dev) - return; - - if (c == '\n') - escc_uart_port_putchar(port, '\r'); - while (!(CTRL(port) & Tx_BUF_EMP)) - ; - DATA(port) = c; -} - -static void uart_init_line(volatile unsigned char *port, unsigned long baud) -{ - CTRL(port) = 4; // reg 4 - CTRL(port) = SB1 | X16CLK; // no parity, async, 1 stop bit, 16x - // clock - - baud = BPS_TO_BRG(baud, ESCC_CLOCK / ESCC_CLOCK_DIVISOR); - - CTRL(port) = 12; // reg 12 - CTRL(port) = baud & 0xff; - CTRL(port) = 13; // reg 13 - CTRL(port) = (baud >> 8) & 0xff; - CTRL(port) = 14; // reg 14 - CTRL(port) = BRSRC | BRENAB; - - CTRL(port) = 3; // reg 3 - CTRL(port) = RxENAB | Rx8; // enable rx, 8 bits/char - - CTRL(port) = 5; // reg 5 - CTRL(port) = RTS | TxENAB | Tx8 | DTR; // enable tx, 8 bits/char, - // set RTS & DTR - -} - -int escc_uart_init(phys_addr_t port, unsigned long speed) -{ -#ifdef CONFIG_DRIVER_ESCC_SUN - escc_serial_dev = (unsigned char *)ofmem_map_io(port & ~7ULL, ZS_REGS); - escc_serial_dev += port & 7ULL; -#else - escc_serial_dev = (unsigned char *)(uintptr_t)port; -#endif - uart_init_line(escc_serial_dev, speed); - return -1; -} - -void escc_uart_putchar(int c) -{ - escc_uart_port_putchar((uintptr_t)escc_serial_dev, (unsigned char) (c & 0xff)); -} - -void serial_cls(void) -{ - escc_uart_putchar(27); - escc_uart_putchar('['); - escc_uart_putchar('H'); - escc_uart_putchar(27); - escc_uart_putchar('['); - escc_uart_putchar('J'); -} - -/* ( addr len -- actual ) */ -static void -escc_read(ucell *address) -{ - char *addr; - int len; - - len = POP(); - addr = (char *)cell2pointer(POP()); - - if (len < 1) - printk("escc_read: bad len, addr %p len %x\n", addr, len); - - if (escc_uart_charav(*address)) { - *addr = (char)escc_uart_getchar(*address); - PUSH(1); - } else { - PUSH(0); - } -} - -/* ( addr len -- actual ) */ -static void -escc_write(ucell *address) -{ - unsigned char *addr; - int i, len; - - len = POP(); - addr = (unsigned char *)cell2pointer(POP()); - - for (i = 0; i < len; i++) { - escc_uart_port_putchar(*address, addr[i]); - } - PUSH(len); -} - -static void -escc_close(void) -{ -} - -static void -escc_open(ucell *address) -{ -#ifdef CONFIG_DRIVER_ESCC_SUN - int len; - phandle_t ph; - unsigned long *prop; - char *args; - - fword("my-self"); - fword("ihandle>phandle"); - ph = (phandle_t)POP(); - prop = (unsigned long *)get_property(ph, "address", &len); - *address = *prop; - fword("my-args"); - args = pop_fstr_copy(); - if (args) { - if (args[0] == 'a') - *address += 4; - //printk("escc_open: address %lx, args %s\n", *address, args); - free(args); - } -#else - *address = (unsigned long)escc_serial_dev; // XXX -#endif - RET ( -1 ); -} - -DECLARE_UNNAMED_NODE(escc, INSTALL_OPEN, sizeof(ucell)); - -NODE_METHODS(escc) = { - { "open", escc_open }, - { "close", escc_close }, - { "read", escc_read }, - { "write", escc_write }, -}; - -#ifdef CONFIG_DRIVER_ESCC_SUN -static volatile unsigned char *kbd_dev; - -void kbd_init(phys_addr_t base) -{ - kbd_dev = (unsigned char *)ofmem_map_io(base, 2 * 4); - kbd_dev += 4; -} - -static const unsigned char sunkbd_keycode[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '\\', 13, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ' ', -}; - -static const unsigned char sunkbd_keycode_shifted[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '|', 13, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ' ', -}; - -static int shiftstate; - -int -keyboard_dataready(void) -{ - return ((kbd_dev[0] & 1) == 1); -} - -unsigned char -keyboard_readdata(void) -{ - unsigned char ch; - - while (!keyboard_dataready()) { } - - do { - ch = kbd_dev[2] & 0xff; - if (ch == 99) - shiftstate |= 1; - else if (ch == 110) - shiftstate |= 2; - else if (ch == 227) - shiftstate &= ~1; - else if (ch == 238) - shiftstate &= ~2; - //printk("getch: %d\n", ch); - } // If release, wait for key press - while ((ch & 0x80) == 0x80 || ch == 238 || ch == 227); - //printk("getch rel: %d\n", ch); - ch &= 0x7f; - if (shiftstate) - ch = sunkbd_keycode_shifted[ch]; - else - ch = sunkbd_keycode[ch]; - //printk("getch xlate: %d\n", ch); - - return ch; -} - -/* ( addr len -- actual ) */ -static void -escc_read_keyboard(void) -{ - unsigned char *addr; - int len; - - len = POP(); - addr = (unsigned char *)POP(); - - if (len < 1) - printk("escc_read: bad len, addr %p len %x\n", addr, len); - - if (keyboard_dataready()) { - *addr = keyboard_readdata(); - PUSH(1); - } else { - PUSH(0); - } -} - -DECLARE_UNNAMED_NODE(escc_keyboard, INSTALL_OPEN, sizeof(ucell)); - -NODE_METHODS(escc_keyboard) = { - { "open", escc_open }, - { "close", escc_close }, - { "read", escc_read_keyboard }, -}; - -void -ob_zs_init(phys_addr_t base, uint64_t offset, int intr, int slave, int keyboard) -{ - char nodebuff[256]; - phandle_t aliases; - - ob_new_obio_device("zs", "serial"); - - ob_reg(base, offset, ZS_REGS, 1); - - PUSH(slave); - fword("encode-int"); - push_str("slave"); - fword("property"); - - if (keyboard) { - PUSH(0); - PUSH(0); - push_str("keyboard"); - fword("property"); - - PUSH(0); - PUSH(0); - push_str("mouse"); - fword("property"); - } - - ob_intr(intr); - - PUSH(0); - PUSH(0); - push_str("port-a-ignore-cd"); - fword("property"); - - PUSH(0); - PUSH(0); - push_str("port-b-ignore-cd"); - fword("property"); - - fword("finish-device"); - - snprintf(nodebuff, sizeof(nodebuff), "/obio/zs@0,%x", - (int)offset & 0xffffffff); - if (keyboard) { - REGISTER_NODE_METHODS(escc_keyboard, nodebuff); - - aliases = find_dev("/aliases"); - set_property(aliases, "keyboard", nodebuff, strlen(nodebuff) + 1); - } else { - REGISTER_NODE_METHODS(escc, nodebuff); - - aliases = find_dev("/aliases"); - snprintf(nodebuff, sizeof(nodebuff), "/obio/zs@0,%x:a", - (int)offset & 0xffffffff); - set_property(aliases, "ttya", nodebuff, strlen(nodebuff) + 1); - - snprintf(nodebuff, sizeof(nodebuff), "/obio/zs@0,%x:b", - (int)offset & 0xffffffff); - set_property(aliases, "ttyb", nodebuff, strlen(nodebuff) + 1); - - } -} - -#else - -static void -escc_add_channel(const char *path, const char *node, phys_addr_t addr, - int esnum) -{ - char buf[64], tty[32]; - phandle_t dnode, aliases; - - cell props[10]; - ucell offset; - int index; - int legacy; - - int dbdma_offsets[2][2] = { - /* ch-b */ - { 0x6, 0x7 }, - /* ch-a */ - { 0x4, 0x5 } - }; - - int reg_offsets[2][2][3] = { - { - /* ch-b */ - { 0x00, 0x10, 0x40 }, - /* ch-a */ - { 0x20, 0x30, 0x50 } - },{ - /* legacy ch-b */ - { 0x0, 0x2, 0x8 }, - /* legacy ch-a */ - { 0x4, 0x6, 0xa } - } - }; - - switch (esnum) { - case 2: index = 1; legacy = 0; break; - case 3: index = 0; legacy = 0; break; - case 4: index = 1; legacy = 1; break; - case 5: index = 0; legacy = 1; break; - default: return; - } - - /* add device */ - - snprintf(buf, sizeof(buf), "%s/ch-%s", path, node); - - REGISTER_NAMED_NODE(escc, buf); - - activate_device(buf); - - /* add aliases */ - - aliases = find_dev("/aliases"); - - snprintf(buf, sizeof(buf), "%s/ch-%s", path, node); - OLDWORLD(snprintf(tty, sizeof(tty), "tty%s", node)); - OLDWORLD(set_property(aliases, tty, buf, strlen(buf) + 1)); - snprintf(tty, sizeof(tty), "scc%s", node); - set_property(aliases, tty, buf, strlen(buf) + 1); - - /* add properties */ - - dnode = find_dev(buf); - set_property(dnode, "device_type", "serial", - strlen("serial") + 1); - - snprintf(buf, sizeof(buf), "chrp,es%d", esnum); - set_property(dnode, "compatible", buf, 9); - - if (legacy) { - offset = IO_ESCC_LEGACY_OFFSET; - } else { - offset = IO_ESCC_OFFSET; - } - - props[0] = offset + reg_offsets[legacy][index][0]; - props[1] = 0x1; - props[2] = offset + reg_offsets[legacy][index][1]; - props[3] = 0x1; - props[4] = offset + reg_offsets[legacy][index][2]; - props[5] = 0x1; - props[6] = 0x8000 + dbdma_offsets[index][0] * 0x100; - props[7] = 0x100; - props[8] = 0x8000 + dbdma_offsets[index][1] * 0x100; - props[9] = 0x100; - set_property(dnode, "reg", (char *)&props, 10 * sizeof(cell)); - - props[0] = addr + offset + reg_offsets[legacy][index][0]; - OLDWORLD(set_property(dnode, "AAPL,address", - (char *)&props, 1 * sizeof(cell))); - - props[0] = 0x10 - index; - OLDWORLD(set_property(dnode, "AAPL,interrupts", - (char *)&props, 1 * sizeof(cell))); - - props[0] = (0x24) + index; - props[1] = 0x1; - props[2] = dbdma_offsets[index][0]; - props[3] = 0x0; - props[4] = dbdma_offsets[index][1]; - props[5] = 0x0; - NEWWORLD(set_property(dnode, "interrupts", - (char *)&props, 6 * sizeof(cell))); - - set_int_property(dnode, "slot-names", 0); - - device_end(); - - uart_init_line((unsigned char*)addr + offset + reg_offsets[legacy][index][0], - CONFIG_SERIAL_SPEED); -} - -void -escc_init(const char *path, phys_addr_t addr) -{ - char buf[64]; - int props[2]; - phandle_t dnode; - - push_str(path); - fword("find-device"); - fword("new-device"); - - push_str("escc"); - fword("device-name"); - - snprintf(buf, sizeof(buf), "%s/escc", path); - - dnode = find_dev(buf); - - set_int_property(dnode, "#address-cells", 1); - props[0] = __cpu_to_be32(IO_ESCC_OFFSET); - props[1] = __cpu_to_be32(IO_ESCC_SIZE); - set_property(dnode, "reg", (char *)&props, sizeof(props)); - set_property(dnode, "device_type", "escc", - strlen("escc") + 1); - set_property(dnode, "compatible", "escc\0CHRP,es0", 14); - set_property(dnode, "ranges", "", 0); - - fword("finish-device"); - - escc_add_channel(buf, "a", addr, 2); - escc_add_channel(buf, "b", addr, 3); - - escc_serial_dev = (unsigned char *)addr + IO_ESCC_OFFSET + - (CONFIG_SERIAL_PORT ? 0 : 0x20); - - push_str(path); - fword("find-device"); - fword("new-device"); - - push_str("escc-legacy"); - fword("device-name"); - - snprintf(buf, sizeof(buf), "%s/escc-legacy", path); - - dnode = find_dev(buf); - - set_int_property(dnode, "#address-cells", 1); - props[0] = __cpu_to_be32(IO_ESCC_LEGACY_OFFSET); - props[1] = __cpu_to_be32(IO_ESCC_LEGACY_SIZE); - set_property(dnode, "reg", (char *)&props, sizeof(props)); - set_property(dnode, "device_type", "escc-legacy", - strlen("escc-legacy") + 1); - set_property(dnode, "compatible", "chrp,es1", 9); - set_property(dnode, "ranges", "", 0); - - fword("finish-device"); - - escc_add_channel(buf, "a", addr, 4); - escc_add_channel(buf, "b", addr, 5); -} -#endif diff --git a/qemu/roms/openbios/drivers/escc.h b/qemu/roms/openbios/drivers/escc.h deleted file mode 100644 index e73f267b2..000000000 --- a/qemu/roms/openbios/drivers/escc.h +++ /dev/null @@ -1,11 +0,0 @@ - -#define IO_ESCC_SIZE 0x00001000 -#define IO_ESCC_OFFSET 0x00013000 -#define IO_ESCC_LEGACY_SIZE 0x00001000 -#define IO_ESCC_LEGACY_OFFSET 0x00012000 - -#define ZS_REGS 8 - -void escc_init(const char *path, phys_addr_t addr); -void ob_zs_init(phys_addr_t base, uint64_t offset, int intr, int slave, - int keyboard); diff --git a/qemu/roms/openbios/drivers/esp.c b/qemu/roms/openbios/drivers/esp.c deleted file mode 100644 index ad3db280d..000000000 --- a/qemu/roms/openbios/drivers/esp.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * OpenBIOS ESP driver - * - * Copyright (C) 2004 Jens Axboe - * Copyright (C) 2005 Stefan Reinauer - * - * Credit goes to Hale Landis for his excellent ata demo software - * OF node handling and some fixes by Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "kernel/kernel.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "drivers/drivers.h" -#include "asm/io.h" -#include "scsi.h" -#include "asm/dma.h" -#include "esp.h" -#include "libopenbios/ofmem.h" - -#define BUFSIZE 4096 - -#ifdef CONFIG_DEBUG_ESP -#define DPRINTF(fmt, args...) \ - do { printk(fmt , ##args); } while (0) -#else -#define DPRINTF(fmt, args...) -#endif - -struct esp_dma { - volatile struct sparc_dma_registers *regs; - enum dvma_rev revision; -}; - -typedef struct sd_private { - unsigned int bs; - const char *media_str[2]; - uint32_t sectors; - uint8_t media; - uint8_t id; - uint8_t present; - char model[40]; -} sd_private_t; - -struct esp_regs { - unsigned char regs[ESP_REG_SIZE]; -}; - -typedef struct esp_private { - volatile struct esp_regs *ll; - uint32_t buffer_dvma; - unsigned int irq; /* device IRQ number */ - struct esp_dma espdma; - unsigned char *buffer; - sd_private_t sd[8]; -} esp_private_t; - -static esp_private_t *global_esp; - -/* DECLARE data structures for the nodes. */ -DECLARE_UNNAMED_NODE(ob_sd, INSTALL_OPEN, sizeof(sd_private_t *)); -DECLARE_UNNAMED_NODE(ob_esp, INSTALL_OPEN, sizeof(esp_private_t *)); - -#ifdef CONFIG_DEBUG_ESP -static void dump_drive(sd_private_t *drive) -{ - printk("SCSI DRIVE @%lx:\n", (unsigned long)drive); - printk("id: %d\n", drive->id); - printk("media: %s\n", drive->media_str[0]); - printk("media: %s\n", drive->media_str[1]); - printk("model: %s\n", drive->model); - printk("sectors: %d\n", drive->sectors); - printk("present: %d\n", drive->present); - printk("bs: %d\n", drive->bs); -} -#endif - -static int -do_command(esp_private_t *esp, sd_private_t *sd, int cmdlen, int replylen) -{ - int status; - - // Set SCSI target - esp->ll->regs[ESP_BUSID] = sd->id & 7; - // Set DMA address - esp->espdma.regs->st_addr = esp->buffer_dvma; - // Set DMA length - esp->ll->regs[ESP_TCLOW] = cmdlen & 0xff; - esp->ll->regs[ESP_TCMED] = (cmdlen >> 8) & 0xff; - // Set DMA direction and enable DMA - esp->espdma.regs->cond_reg = DMA_ENABLE; - // Set ATN, issue command - esp->ll->regs[ESP_CMD] = ESP_CMD_SELA | ESP_CMD_DMA; - // Wait for DMA to complete. Can this fail? - while ((esp->espdma.regs->cond_reg & DMA_HNDL_INTR) == 0) /* no-op */; - // Check status - status = esp->ll->regs[ESP_STATUS]; - // Clear interrupts to avoid guests seeing spurious interrupts - (void)esp->ll->regs[ESP_INTRPT]; - - DPRINTF("do_command: id %d, cmd[0] 0x%x, status 0x%x\n", sd->id, esp->buffer[1], status); - - /* Target didn't want all command data? */ - if ((status & ESP_STAT_TCNT) != ESP_STAT_TCNT) { - return status; - } - if (replylen == 0) { - return 0; - } - /* Target went to status phase instead of data phase? */ - if ((status & ESP_STAT_PMASK) == ESP_STATP) { - return status; - } - - // Get reply - // Set DMA address - esp->espdma.regs->st_addr = esp->buffer_dvma; - // Set DMA length - esp->ll->regs[ESP_TCLOW] = replylen & 0xff; - esp->ll->regs[ESP_TCMED] = (replylen >> 8) & 0xff; - // Set DMA direction - esp->espdma.regs->cond_reg = DMA_ST_WRITE | DMA_ENABLE; - // Transfer - esp->ll->regs[ESP_CMD] = ESP_CMD_TI | ESP_CMD_DMA; - // Wait for DMA to complete - while ((esp->espdma.regs->cond_reg & DMA_HNDL_INTR) == 0) /* no-op */; - // Check status - status = esp->ll->regs[ESP_STATUS]; - // Clear interrupts to avoid guests seeing spurious interrupts - (void)esp->ll->regs[ESP_INTRPT]; - - DPRINTF("do_command_reply: status 0x%x\n", status); - - if ((status & ESP_STAT_TCNT) != ESP_STAT_TCNT) - return status; - else - return 0; // OK -} - -// offset is in sectors -static int -ob_sd_read_sector(esp_private_t *esp, sd_private_t *sd, int offset) -{ - DPRINTF("ob_sd_read_sector id %d sector=%d\n", - sd->id, offset); - - // Setup command = Read(10) - memset(esp->buffer, 0, 11); - esp->buffer[0] = 0x80; - esp->buffer[1] = READ_10; - - esp->buffer[3] = (offset >> 24) & 0xff; - esp->buffer[4] = (offset >> 16) & 0xff; - esp->buffer[5] = (offset >> 8) & 0xff; - esp->buffer[6] = offset & 0xff; - - esp->buffer[8] = 0; - esp->buffer[9] = 1; - - if (do_command(esp, sd, 11, sd->bs)) - return 0; - - return 0; -} - -static unsigned int -read_capacity(esp_private_t *esp, sd_private_t *sd) -{ - // Setup command = Read Capacity - memset(esp->buffer, 0, 11); - esp->buffer[0] = 0x80; - esp->buffer[1] = READ_CAPACITY; - - if (do_command(esp, sd, 11, 8)) { - sd->sectors = 0; - sd->bs = 0; - DPRINTF("read_capacity id %d failed\n", sd->id); - return 0; - } - sd->bs = (esp->buffer[4] << 24) | (esp->buffer[5] << 16) | (esp->buffer[6] << 8) | esp->buffer[7]; - sd->sectors = ((esp->buffer[0] << 24) | (esp->buffer[1] << 16) | (esp->buffer[2] << 8) | esp->buffer[3]) * (sd->bs / 512); - - DPRINTF("read_capacity id %d bs %d sectors %d\n", sd->id, sd->bs, - sd->sectors); - return 1; -} - -static unsigned int -test_unit_ready(esp_private_t *esp, sd_private_t *sd) -{ - /* Setup command = Test Unit Ready */ - memset(esp->buffer, 0, 7); - esp->buffer[0] = 0x80; - esp->buffer[1] = TEST_UNIT_READY; - - if (do_command(esp, sd, 7, 0)) { - DPRINTF("test_unit_ready id %d failed\n", sd->id); - return 0; - } - - DPRINTF("test_unit_ready id %d success\n", sd->id); - return 1; -} - -static unsigned int -inquiry(esp_private_t *esp, sd_private_t *sd) -{ - const char *media[2] = { "UNKNOWN", "UNKNOWN"}; - - // Setup command = Inquiry - memset(esp->buffer, 0, 7); - esp->buffer[0] = 0x80; - esp->buffer[1] = INQUIRY; - - esp->buffer[5] = 36; - - if (do_command(esp, sd, 7, 36)) { - sd->present = 0; - sd->media = -1; - return 0; - } - sd->present = 1; - sd->media = esp->buffer[0]; - - switch (sd->media) { - case TYPE_DISK: - media[0] = "disk"; - media[1] = "hd"; - break; - case TYPE_ROM: - media[0] = "cdrom"; - media[1] = "cd"; - break; - } - sd->media_str[0] = media[0]; - sd->media_str[1] = media[1]; - memcpy(sd->model, &esp->buffer[16], 16); - sd->model[17] = '\0'; - - return 1; -} - - -static void -ob_sd_read_blocks(sd_private_t **sd) -{ - cell n = POP(), cnt = n; - ucell blk = POP(); - char *dest = (char*)POP(); - int pos, spb, sect_offset; - - DPRINTF("ob_sd_read_blocks id %d %lx block=%d n=%d\n", (*sd)->id, (unsigned long)dest, blk, n ); - - if ((*sd)->bs == 0) { - PUSH(0); - return; - } - spb = (*sd)->bs / 512; - while (n) { - sect_offset = blk / spb; - pos = (blk - sect_offset * spb) * 512; - - if (ob_sd_read_sector(global_esp, *sd, sect_offset)) { - DPRINTF("ob_sd_read_blocks: error\n"); - RET(0); - } - while (n && pos < spb * 512) { - memcpy(dest, global_esp->buffer + pos, 512); - pos += 512; - dest += 512; - n--; - blk++; - } - } - PUSH(cnt); -} - -static void -ob_sd_block_size(__attribute__((unused))sd_private_t **sd) -{ - PUSH(512); -} - -static void -ob_sd_open(__attribute__((unused))sd_private_t **sd) -{ - int ret = 1, id; - phandle_t ph; - - fword("my-unit"); - id = POP(); - POP(); // unit id is 2 ints but we only need one. - *sd = &global_esp->sd[id]; - -#ifdef CONFIG_DEBUG_ESP - { - char *args; - - fword("my-args"); - args = pop_fstr_copy(); - DPRINTF("opening drive %d args %s\n", id, args); - free(args); - } -#endif - - selfword("open-deblocker"); - - /* interpose disk-label */ - ph = find_dev("/packages/disk-label"); - fword("my-args"); - PUSH_ph( ph ); - fword("interpose"); - - RET ( -ret ); -} - -static void -ob_sd_close(__attribute__((unused)) sd_private_t **sd) -{ - selfword("close-deblocker"); -} - -NODE_METHODS(ob_sd) = { - { "open", ob_sd_open }, - { "close", ob_sd_close }, - { "read-blocks", ob_sd_read_blocks }, - { "block-size", ob_sd_block_size }, -}; - - -static int -espdma_init(unsigned int slot, uint64_t base, unsigned long offset, - struct esp_dma *espdma) -{ - espdma->regs = (void *)ofmem_map_io(base + (uint64_t)offset, 0x10); - - if (espdma->regs == NULL) { - DPRINTF("espdma_init: cannot map registers\n"); - return -1; - } - - DPRINTF("dma1: "); - - switch ((espdma->regs->cond_reg) & DMA_DEVICE_ID) { - case DMA_VERS0: - espdma->revision = dvmarev0; - DPRINTF("Revision 0 "); - break; - case DMA_ESCV1: - espdma->revision = dvmaesc1; - DPRINTF("ESC Revision 1 "); - break; - case DMA_VERS1: - espdma->revision = dvmarev1; - DPRINTF("Revision 1 "); - break; - case DMA_VERS2: - espdma->revision = dvmarev2; - DPRINTF("Revision 2 "); - break; - case DMA_VERHME: - espdma->revision = dvmahme; - DPRINTF("HME DVMA gate array "); - break; - case DMA_VERSPLUS: - espdma->revision = dvmarevplus; - DPRINTF("Revision 1 PLUS "); - break; - default: - DPRINTF("unknown dma version %x", - (espdma->regs->cond_reg) & DMA_DEVICE_ID); - /* espdma->allocated = 1; */ - break; - } - DPRINTF("\n"); - - push_str("/iommu/sbus/espdma"); - fword("find-device"); - - /* set reg */ - PUSH(slot); - fword("encode-int"); - PUSH(offset); - fword("encode-int"); - fword("encode+"); - PUSH(0x00000010); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - return 0; -} - -static void -ob_esp_initialize(__attribute__((unused)) esp_private_t **esp) -{ - phandle_t ph = get_cur_dev(); - - set_int_property(ph, "#address-cells", 2); - set_int_property(ph, "#size-cells", 0); - - /* set device type */ - push_str("scsi"); - fword("device-type"); - - /* QEMU's ESP emulation does not support mixing DMA and FIFO messages. By - setting this attribute, we prevent the Solaris ESP kernel driver from - trying to use this feature when booting a disk image (and failing) */ - PUSH(0x58); - fword("encode-int"); - push_str("scsi-options"); - fword("property"); - - PUSH(0x24); - fword("encode-int"); - PUSH(0); - fword("encode-int"); - fword("encode+"); - push_str("intr"); - fword("property"); -} - -static void -ob_esp_decodeunit(__attribute__((unused)) esp_private_t **esp) -{ - fword("decode-unit-scsi"); -} - - -static void -ob_esp_encodeunit(__attribute__((unused)) esp_private_t **esp) -{ - fword("encode-unit-scsi"); -} - -NODE_METHODS(ob_esp) = { - { NULL, ob_esp_initialize }, - { "decode-unit", ob_esp_decodeunit }, - { "encode-unit", ob_esp_encodeunit }, -}; - -static void -add_alias(const char *device, const char *alias) -{ - DPRINTF("add_alias dev \"%s\" = alias \"%s\"\n", device, alias); - push_str("/aliases"); - fword("find-device"); - push_str(device); - fword("encode-string"); - push_str(alias); - fword("property"); -} - -int -ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset, - unsigned long dmaoffset) -{ - int id, diskcount = 0, cdcount = 0, *counter_ptr; - char nodebuff[256], aliasbuff[256]; - esp_private_t *esp; - unsigned int i; - - DPRINTF("Initializing SCSI..."); - - esp = malloc(sizeof(esp_private_t)); - if (!esp) { - DPRINTF("Can't allocate ESP private structure\n"); - return -1; - } - - global_esp = esp; - - if (espdma_init(slot, base, dmaoffset, &esp->espdma) != 0) { - return -1; - } - /* Get the IO region */ - esp->ll = (void *)ofmem_map_io(base + (uint64_t)espoffset, - sizeof(struct esp_regs)); - if (esp->ll == NULL) { - DPRINTF("Can't map ESP registers\n"); - return -1; - } - - esp->buffer = (void *)dvma_alloc(BUFSIZE, &esp->buffer_dvma); - if (!esp->buffer || !esp->buffer_dvma) { - DPRINTF("Can't get a DVMA buffer\n"); - return -1; - } - - // Chip reset - esp->ll->regs[ESP_CMD] = ESP_CMD_RC; - - DPRINTF("ESP at 0x%lx, buffer va 0x%lx dva 0x%lx\n", (unsigned long)esp, - (unsigned long)esp->buffer, (unsigned long)esp->buffer_dvma); - DPRINTF("done\n"); - DPRINTF("Initializing SCSI devices..."); - - for (id = 0; id < 8; id++) { - esp->sd[id].id = id; - if (!inquiry(esp, &esp->sd[id])) { - DPRINTF("Unit %d not present\n", id); - continue; - } - /* Clear Unit Attention condition from reset */ - for (i = 0; i < 5; i++) { - if (test_unit_ready(esp, &esp->sd[id])) { - break; - } - } - if (i == 5) { - DPRINTF("Unit %d present but won't become ready\n", id); - continue; - } - DPRINTF("Unit %d present\n", id); - read_capacity(esp, &esp->sd[id]); - -#ifdef CONFIG_DEBUG_ESP - dump_drive(&esp->sd[id]); -#endif - } - - REGISTER_NAMED_NODE(ob_esp, "/iommu/sbus/espdma/esp"); - device_end(); - /* set reg */ - push_str("/iommu/sbus/espdma/esp"); - fword("find-device"); - PUSH(slot); - fword("encode-int"); - PUSH(espoffset); - fword("encode-int"); - fword("encode+"); - PUSH(0x00000010); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - PUSH(0x02625a00); - fword("encode-int"); - push_str("clock-frequency"); - fword("property"); - - for (id = 0; id < 8; id++) { - if (!esp->sd[id].present) - continue; - push_str("/iommu/sbus/espdma/esp"); - fword("find-device"); - fword("new-device"); - push_str("sd"); - fword("device-name"); - push_str("block"); - fword("device-type"); - fword("is-deblocker"); - PUSH(id); - fword("encode-int"); - PUSH(0); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - fword("finish-device"); - snprintf(nodebuff, sizeof(nodebuff), "/iommu/sbus/espdma/esp/sd@%d,0", - id); - REGISTER_NODE_METHODS(ob_sd, nodebuff); - if (esp->sd[id].media == TYPE_ROM) { - counter_ptr = &cdcount; - } else { - counter_ptr = &diskcount; - } - if (*counter_ptr == 0) { - add_alias(nodebuff, esp->sd[id].media_str[0]); - add_alias(nodebuff, esp->sd[id].media_str[1]); - } - snprintf(aliasbuff, sizeof(aliasbuff), "%s%d", - esp->sd[id].media_str[0], *counter_ptr); - add_alias(nodebuff, aliasbuff); - snprintf(aliasbuff, sizeof(aliasbuff), "%s%d", - esp->sd[id].media_str[1], *counter_ptr); - add_alias(nodebuff, aliasbuff); - snprintf(aliasbuff, sizeof(aliasbuff), "sd(0,%d,0)", id); - add_alias(nodebuff, aliasbuff); - snprintf(aliasbuff, sizeof(aliasbuff), "sd(0,%d,0)@0,0", id); - add_alias(nodebuff, aliasbuff); - (*counter_ptr)++; - } - DPRINTF("done\n"); - - return 0; -} diff --git a/qemu/roms/openbios/drivers/esp.fs b/qemu/roms/openbios/drivers/esp.fs deleted file mode 100644 index 9e37c0a0e..000000000 --- a/qemu/roms/openbios/drivers/esp.fs +++ /dev/null @@ -1,18 +0,0 @@ -\ ------------------------------------------------------------------------- -\ SCSI encode/decode unit -\ ------------------------------------------------------------------------- - -: decode-unit-scsi ( str len -- id lun ) - ascii , left-split - ( addr-R len-R addr-L len-L ) - parse-hex - -rot parse-hex - swap -; - -: encode-unit-scsi ( id lun -- str len) - swap - pocket tohexstr - " ," pocket tmpstrcat >r - rot pocket tohexstr r> tmpstrcat drop -; diff --git a/qemu/roms/openbios/drivers/esp.h b/qemu/roms/openbios/drivers/esp.h deleted file mode 100644 index 2b9bd5e01..000000000 --- a/qemu/roms/openbios/drivers/esp.h +++ /dev/null @@ -1,269 +0,0 @@ -/* $Id: esp.h,v 1.28 2000/03/30 01:33:17 davem Exp $ - * esp.h: Defines and structures for the Sparc ESP (Enhanced SCSI - * Processor) driver under Linux. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef _SPARC_ESP_H -#define _SPARC_ESP_H - -/* For dvma controller register definitions. */ -#include "asm/dma.h" - -/* The ESP SCSI controllers have their register sets in three - * "classes": - * - * 1) Registers which are both read and write. - * 2) Registers which are read only. - * 3) Registers which are write only. - * - * Yet, they all live within the same IO space. - */ - -/* All the ESP registers are one byte each and are accessed longwords - * apart with a big-endian ordering to the bytes. - */ - /* Access Description Offset */ -#define ESP_TCLOW 0x00UL /* rw Low bits of the transfer count 0x00 */ -#define ESP_TCMED 0x04UL /* rw Mid bits of the transfer count 0x04 */ -#define ESP_FDATA 0x08UL /* rw FIFO data bits 0x08 */ -#define ESP_CMD 0x0cUL /* rw SCSI command bits 0x0c */ -#define ESP_STATUS 0x10UL /* ro ESP status register 0x10 */ -#define ESP_BUSID ESP_STATUS /* wo Bus ID for select/reselect 0x10 */ -#define ESP_INTRPT 0x14UL /* ro Kind of interrupt 0x14 */ -#define ESP_TIMEO ESP_INTRPT /* wo Timeout value for select/resel 0x14 */ -#define ESP_SSTEP 0x18UL /* ro Sequence step register 0x18 */ -#define ESP_STP ESP_SSTEP /* wo Transfer period per sync 0x18 */ -#define ESP_FFLAGS 0x1cUL /* ro Bits of current FIFO info 0x1c */ -#define ESP_SOFF ESP_FFLAGS /* wo Sync offset 0x1c */ -#define ESP_CFG1 0x20UL /* rw First configuration register 0x20 */ -#define ESP_CFACT 0x24UL /* wo Clock conversion factor 0x24 */ -#define ESP_STATUS2 ESP_CFACT /* ro HME status2 register 0x24 */ -#define ESP_CTEST 0x28UL /* wo Chip test register 0x28 */ -#define ESP_CFG2 0x2cUL /* rw Second configuration register 0x2c */ -#define ESP_CFG3 0x30UL /* rw Third configuration register 0x30 */ -#define ESP_TCHI 0x38UL /* rw High bits of transfer count 0x38 */ -#define ESP_UID ESP_TCHI /* ro Unique ID code 0x38 */ -#define FAS_RLO ESP_TCHI /* rw HME extended counter 0x38 */ -#define ESP_FGRND 0x3cUL /* rw Data base for fifo 0x3c */ -#define FAS_RHI ESP_FGRND /* rw HME extended counter 0x3c */ -#define ESP_REG_SIZE 0x40UL - -/* Various revisions of the ESP board. */ -enum esp_rev { - esp100 = 0x00, /* NCR53C90 - very broken */ - esp100a = 0x01, /* NCR53C90A */ - esp236 = 0x02, - fas236 = 0x03, - fas100a = 0x04, - fast = 0x05, - fashme = 0x06, - espunknown = 0x07 -}; - -/* Bitfield meanings for the above registers. */ - -/* ESP config reg 1, read-write, found on all ESP chips */ -#define ESP_CONFIG1_ID 0x07 /* My BUS ID bits */ -#define ESP_CONFIG1_CHTEST 0x08 /* Enable ESP chip tests */ -#define ESP_CONFIG1_PENABLE 0x10 /* Enable parity checks */ -#define ESP_CONFIG1_PARTEST 0x20 /* Parity test mode enabled? */ -#define ESP_CONFIG1_SRRDISAB 0x40 /* Disable SCSI reset reports */ -#define ESP_CONFIG1_SLCABLE 0x80 /* Enable slow cable mode */ - -/* ESP config reg 2, read-write, found only on esp100a+esp200+esp236 chips */ -#define ESP_CONFIG2_DMAPARITY 0x01 /* enable DMA Parity (200,236) */ -#define ESP_CONFIG2_REGPARITY 0x02 /* enable reg Parity (200,236) */ -#define ESP_CONFIG2_BADPARITY 0x04 /* Bad parity target abort */ -#define ESP_CONFIG2_SCSI2ENAB 0x08 /* Enable SCSI-2 features (tmode only) */ -#define ESP_CONFIG2_HI 0x10 /* High Impedance DREQ ??? */ -#define ESP_CONFIG2_HMEFENAB 0x10 /* HME features enable */ -#define ESP_CONFIG2_BCM 0x20 /* Enable byte-ctrl (236) */ -#define ESP_CONFIG2_DISPINT 0x20 /* Disable pause irq (hme) */ -#define ESP_CONFIG2_FENAB 0x40 /* Enable features (fas100,esp216) */ -#define ESP_CONFIG2_SPL 0x40 /* Enable status-phase latch (esp236) */ -#define ESP_CONFIG2_MKDONE 0x40 /* HME magic feature */ -#define ESP_CONFIG2_HME32 0x80 /* HME 32 extended */ -#define ESP_CONFIG2_MAGIC 0xe0 /* Invalid bits... */ - -/* ESP config register 3 read-write, found only esp236+fas236+fas100a+hme chips */ -#define ESP_CONFIG3_FCLOCK 0x01 /* FAST SCSI clock rate (esp100a/hme) */ -#define ESP_CONFIG3_TEM 0x01 /* Enable thresh-8 mode (esp/fas236) */ -#define ESP_CONFIG3_FAST 0x02 /* Enable FAST SCSI (esp100a/hme) */ -#define ESP_CONFIG3_ADMA 0x02 /* Enable alternate-dma (esp/fas236) */ -#define ESP_CONFIG3_TENB 0x04 /* group2 SCSI2 support (esp100a/hme) */ -#define ESP_CONFIG3_SRB 0x04 /* Save residual byte (esp/fas236) */ -#define ESP_CONFIG3_TMS 0x08 /* Three-byte msg's ok (esp100a/hme) */ -#define ESP_CONFIG3_FCLK 0x08 /* Fast SCSI clock rate (esp/fas236) */ -#define ESP_CONFIG3_IDMSG 0x10 /* ID message checking (esp100a/hme) */ -#define ESP_CONFIG3_FSCSI 0x10 /* Enable FAST SCSI (esp/fas236) */ -#define ESP_CONFIG3_GTM 0x20 /* group2 SCSI2 support (esp/fas236) */ -#define ESP_CONFIG3_IDBIT3 0x20 /* Bit 3 of HME SCSI-ID (hme) */ -#define ESP_CONFIG3_TBMS 0x40 /* Three-byte msg's ok (esp/fas236) */ -#define ESP_CONFIG3_EWIDE 0x40 /* Enable Wide-SCSI (hme) */ -#define ESP_CONFIG3_IMS 0x80 /* ID msg chk'ng (esp/fas236) */ -#define ESP_CONFIG3_OBPUSH 0x80 /* Push odd-byte to dma (hme) */ - -/* ESP command register read-write */ -/* Group 1 commands: These may be sent at any point in time to the ESP - * chip. None of them can generate interrupts 'cept - * the "SCSI bus reset" command if you have not disabled - * SCSI reset interrupts in the config1 ESP register. - */ -#define ESP_CMD_NULL 0x00 /* Null command, ie. a nop */ -#define ESP_CMD_FLUSH 0x01 /* FIFO Flush */ -#define ESP_CMD_RC 0x02 /* Chip reset */ -#define ESP_CMD_RS 0x03 /* SCSI bus reset */ - -/* Group 2 commands: ESP must be an initiator and connected to a target - * for these commands to work. - */ -#define ESP_CMD_TI 0x10 /* Transfer Information */ -#define ESP_CMD_ICCSEQ 0x11 /* Initiator cmd complete sequence */ -#define ESP_CMD_MOK 0x12 /* Message okie-dokie */ -#define ESP_CMD_TPAD 0x18 /* Transfer Pad */ -#define ESP_CMD_SATN 0x1a /* Set ATN */ -#define ESP_CMD_RATN 0x1b /* De-assert ATN */ - -/* Group 3 commands: ESP must be in the MSGOUT or MSGIN state and be connected - * to a target as the initiator for these commands to work. - */ -#define ESP_CMD_SMSG 0x20 /* Send message */ -#define ESP_CMD_SSTAT 0x21 /* Send status */ -#define ESP_CMD_SDATA 0x22 /* Send data */ -#define ESP_CMD_DSEQ 0x23 /* Discontinue Sequence */ -#define ESP_CMD_TSEQ 0x24 /* Terminate Sequence */ -#define ESP_CMD_TCCSEQ 0x25 /* Target cmd cmplt sequence */ -#define ESP_CMD_DCNCT 0x27 /* Disconnect */ -#define ESP_CMD_RMSG 0x28 /* Receive Message */ -#define ESP_CMD_RCMD 0x29 /* Receive Command */ -#define ESP_CMD_RDATA 0x2a /* Receive Data */ -#define ESP_CMD_RCSEQ 0x2b /* Receive cmd sequence */ - -/* Group 4 commands: The ESP must be in the disconnected state and must - * not be connected to any targets as initiator for - * these commands to work. - */ -#define ESP_CMD_RSEL 0x40 /* Reselect */ -#define ESP_CMD_SEL 0x41 /* Select w/o ATN */ -#define ESP_CMD_SELA 0x42 /* Select w/ATN */ -#define ESP_CMD_SELAS 0x43 /* Select w/ATN & STOP */ -#define ESP_CMD_ESEL 0x44 /* Enable selection */ -#define ESP_CMD_DSEL 0x45 /* Disable selections */ -#define ESP_CMD_SA3 0x46 /* Select w/ATN3 */ -#define ESP_CMD_RSEL3 0x47 /* Reselect3 */ - -/* This bit enables the ESP's DMA on the SBus */ -#define ESP_CMD_DMA 0x80 /* Do DMA? */ - - -/* ESP status register read-only */ -#define ESP_STAT_PIO 0x01 /* IO phase bit */ -#define ESP_STAT_PCD 0x02 /* CD phase bit */ -#define ESP_STAT_PMSG 0x04 /* MSG phase bit */ -#define ESP_STAT_PMASK 0x07 /* Mask of phase bits */ -#define ESP_STAT_TDONE 0x08 /* Transfer Completed */ -#define ESP_STAT_TCNT 0x10 /* Transfer Counter Is Zero */ -#define ESP_STAT_PERR 0x20 /* Parity error */ -#define ESP_STAT_SPAM 0x40 /* Real bad error */ -/* This indicates the 'interrupt pending' condition on esp236, it is a reserved - * bit on other revs of the ESP. - */ -#define ESP_STAT_INTR 0x80 /* Interrupt */ - -/* HME only: status 2 register */ -#define ESP_STAT2_SCHBIT 0x01 /* Upper bits 3-7 of sstep enabled */ -#define ESP_STAT2_FFLAGS 0x02 /* The fifo flags are now latched */ -#define ESP_STAT2_XCNT 0x04 /* The transfer counter is latched */ -#define ESP_STAT2_CREGA 0x08 /* The command reg is active now */ -#define ESP_STAT2_WIDE 0x10 /* Interface on this adapter is wide */ -#define ESP_STAT2_F1BYTE 0x20 /* There is one byte at top of fifo */ -#define ESP_STAT2_FMSB 0x40 /* Next byte in fifo is most significant */ -#define ESP_STAT2_FEMPTY 0x80 /* FIFO is empty */ - -/* The status register can be masked with ESP_STAT_PMASK and compared - * with the following values to determine the current phase the ESP - * (at least thinks it) is in. For our purposes we also add our own - * software 'done' bit for our phase management engine. - */ -#define ESP_DOP (0) /* Data Out */ -#define ESP_DIP (ESP_STAT_PIO) /* Data In */ -#define ESP_CMDP (ESP_STAT_PCD) /* Command */ -#define ESP_STATP (ESP_STAT_PCD|ESP_STAT_PIO) /* Status */ -#define ESP_MOP (ESP_STAT_PMSG|ESP_STAT_PCD) /* Message Out */ -#define ESP_MIP (ESP_STAT_PMSG|ESP_STAT_PCD|ESP_STAT_PIO) /* Message In */ - -/* ESP interrupt register read-only */ -#define ESP_INTR_S 0x01 /* Select w/o ATN */ -#define ESP_INTR_SATN 0x02 /* Select w/ATN */ -#define ESP_INTR_RSEL 0x04 /* Reselected */ -#define ESP_INTR_FDONE 0x08 /* Function done */ -#define ESP_INTR_BSERV 0x10 /* Bus service */ -#define ESP_INTR_DC 0x20 /* Disconnect */ -#define ESP_INTR_IC 0x40 /* Illegal command given */ -#define ESP_INTR_SR 0x80 /* SCSI bus reset detected */ - -/* Interrupt status macros */ -#define ESP_SRESET_IRQ(esp) ((esp)->intreg & (ESP_INTR_SR)) -#define ESP_ILLCMD_IRQ(esp) ((esp)->intreg & (ESP_INTR_IC)) -#define ESP_SELECT_WITH_ATN_IRQ(esp) ((esp)->intreg & (ESP_INTR_SATN)) -#define ESP_SELECT_WITHOUT_ATN_IRQ(esp) ((esp)->intreg & (ESP_INTR_S)) -#define ESP_SELECTION_IRQ(esp) ((ESP_SELECT_WITH_ATN_IRQ(esp)) || \ - (ESP_SELECT_WITHOUT_ATN_IRQ(esp))) -#define ESP_RESELECTION_IRQ(esp) ((esp)->intreg & (ESP_INTR_RSEL)) - -/* ESP sequence step register read-only */ -#define ESP_STEP_VBITS 0x07 /* Valid bits */ -#define ESP_STEP_ASEL 0x00 /* Selection&Arbitrate cmplt */ -#define ESP_STEP_SID 0x01 /* One msg byte sent */ -#define ESP_STEP_NCMD 0x02 /* Was not in command phase */ -#define ESP_STEP_PPC 0x03 /* Early phase chg caused cmnd - * bytes to be lost - */ -#define ESP_STEP_FINI4 0x04 /* Command was sent ok */ - -/* Ho hum, some ESP's set the step register to this as well... */ -#define ESP_STEP_FINI5 0x05 -#define ESP_STEP_FINI6 0x06 -#define ESP_STEP_FINI7 0x07 - -/* ESP chip-test register read-write */ -#define ESP_TEST_TARG 0x01 /* Target test mode */ -#define ESP_TEST_INI 0x02 /* Initiator test mode */ -#define ESP_TEST_TS 0x04 /* Tristate test mode */ - -/* ESP unique ID register read-only, found on fas236+fas100a only */ -#define ESP_UID_F100A 0x00 /* ESP FAS100A */ -#define ESP_UID_F236 0x02 /* ESP FAS236 */ -#define ESP_UID_REV 0x07 /* ESP revision */ -#define ESP_UID_FAM 0xf8 /* ESP family */ - -/* ESP fifo flags register read-only */ -/* Note that the following implies a 16 byte FIFO on the ESP. */ -#define ESP_FF_FBYTES 0x1f /* Num bytes in FIFO */ -#define ESP_FF_ONOTZERO 0x20 /* offset ctr not zero (esp100) */ -#define ESP_FF_SSTEP 0xe0 /* Sequence step */ - -/* ESP clock conversion factor register write-only */ -#define ESP_CCF_F0 0x00 /* 35.01MHz - 40MHz */ -#define ESP_CCF_NEVER 0x01 /* Set it to this and die */ -#define ESP_CCF_F2 0x02 /* 10MHz */ -#define ESP_CCF_F3 0x03 /* 10.01MHz - 15MHz */ -#define ESP_CCF_F4 0x04 /* 15.01MHz - 20MHz */ -#define ESP_CCF_F5 0x05 /* 20.01MHz - 25MHz */ -#define ESP_CCF_F6 0x06 /* 25.01MHz - 30MHz */ -#define ESP_CCF_F7 0x07 /* 30.01MHz - 35MHz */ - -/* HME only... */ -#define ESP_BUSID_RESELID 0x10 -#define ESP_BUSID_CTR32BIT 0x40 - -#define ESP_BUS_TIMEOUT 275 /* In milli-seconds */ -#define ESP_TIMEO_CONST 8192 -#define ESP_NEG_DEFP(mhz, cfact) \ - ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact))) -#define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000)) -#define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) - -#endif /* !(_SPARC_ESP_H) */ diff --git a/qemu/roms/openbios/drivers/floppy.c b/qemu/roms/openbios/drivers/floppy.c deleted file mode 100644 index 329987b17..000000000 --- a/qemu/roms/openbios/drivers/floppy.c +++ /dev/null @@ -1,1179 +0,0 @@ -#include "config.h" -#include "libopenbios/bindings.h" -#include "kernel/kernel.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "drivers/drivers.h" - -#include "timer.h" - -/* DECLARE data structures for the nodes. */ -DECLARE_UNNAMED_NODE( ob_floppy, INSTALL_OPEN, 2*sizeof(int) ); - -#ifdef CONFIG_DEBUG_FLOPPY -#define printk_info printk -#define printk_debug printk -#else -#define printk_info(x ...) -#define printk_debug(x ...) -#endif -#define printk_err printk - -#define FD_DRIVE 0 - - -#define FD_STATUS_A (0) /* Status register A */ -#define FD_STATUS_B (1) /* Status register B */ -#define FD_DOR (2) /* Digital Output Register */ -#define FD_TDR (3) /* Tape Drive Register */ -#define FD_STATUS (4) /* Main Status Register */ -#define FD_DSR (4) /* Data Rate Select Register (old) */ -#define FD_DATA (5) /* Data Transfer (FIFO) register */ -#define FD_DIR (7) /* Digital Input Register (read) */ -#define FD_DCR (7) /* Diskette Control Register (write)*/ - -/* Bit of FD_STATUS_A */ -#define STA_INT_PENDING 0x80 /* Interrupt Pending */ - -/* DOR */ -#define DOR_DRIVE0 0x00 -#define DOR_DRIVE1 0x01 -#define DOR_DRIVE2 0x02 -#define DOR_DRIVE3 0x03 -#define DOR_DRIVE_MASK 0x03 -#define DOR_NO_RESET 0x04 -#define DOR_DMA_EN 0x08 -#define DOR_MOT_EN0 0x10 -#define DOR_MOT_EN1 0x20 -#define DOR_MOT_EN2 0x40 -#define DOR_MOT_EN3 0x80 - -/* Bits of main status register */ -#define STATUS_BUSYMASK 0x0F /* drive busy mask */ -#define STATUS_BUSY 0x10 /* FDC busy */ -#define STATUS_NON_DMA 0x20 /* 0- DMA mode */ -#define STATUS_DIR 0x40 /* 0- cpu->fdc */ -#define STATUS_READY 0x80 /* Data reg ready */ - -/* Bits of FD_ST0 */ -#define ST0_DS 0x03 /* drive select mask */ -#define ST0_HA 0x04 /* Head (Address) */ -#define ST0_NR 0x08 /* Not Ready */ -#define ST0_ECE 0x10 /* Equipment check error */ -#define ST0_SE 0x20 /* Seek end */ -#define ST0_INTR 0xC0 /* Interrupt code mask */ -#define ST0_INTR_OK (0 << 6) -#define ST0_INTR_ERROR (1 << 6) -#define ST0_INTR_INVALID (2 << 6) -#define ST0_INTR_POLL_ERROR (3 << 6) - -/* Bits of FD_ST1 */ -#define ST1_MAM 0x01 /* Missing Address Mark */ -#define ST1_WP 0x02 /* Write Protect */ -#define ST1_ND 0x04 /* No Data - unreadable */ -#define ST1_OR 0x10 /* OverRun */ -#define ST1_CRC 0x20 /* CRC error in data or addr */ -#define ST1_EOC 0x80 /* End Of Cylinder */ - -/* Bits of FD_ST2 */ -#define ST2_MAM 0x01 /* Missing Address Mark (again) */ -#define ST2_BC 0x02 /* Bad Cylinder */ -#define ST2_SNS 0x04 /* Scan Not Satisfied */ -#define ST2_SEH 0x08 /* Scan Equal Hit */ -#define ST2_WC 0x10 /* Wrong Cylinder */ -#define ST2_CRC 0x20 /* CRC error in data field */ -#define ST2_CM 0x40 /* Control Mark = deleted */ - -/* Bits of FD_ST3 */ -#define ST3_HA 0x04 /* Head (Address) */ -#define ST3_DS 0x08 /* drive is double-sided */ -#define ST3_TZ 0x10 /* Track Zero signal (1=track 0) */ -#define ST3_RY 0x20 /* drive is ready */ -#define ST3_WP 0x40 /* Write Protect */ -#define ST3_FT 0x80 /* Drive Fault */ - -/* Values for FD_COMMAND */ -#define FD_RECALIBRATE 0x07 /* move to track 0 */ -#define FD_SEEK 0x0F /* seek track */ -#define FD_READ 0xA6 /* read with MT, SKip deleted */ -#define FD_WRITE 0xC5 /* write with MT, MFM */ -#define FD_SENSEI 0x08 /* Sense Interrupt Status */ -#define FD_SPECIFY 0x03 /* specify HUT etc */ -#define FD_FORMAT 0x4D /* format one track */ -#define FD_VERSION 0x10 /* get version code */ -#define FD_CONFIGURE 0x13 /* configure FIFO operation */ -#define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */ -#define FD_GETSTATUS 0x04 /* read ST3 */ -#define FD_DUMPREGS 0x0E /* dump the contents of the fdc regs */ -#define FD_READID 0xEA /* prints the header of a sector */ -#define FD_UNLOCK 0x14 /* Fifo config unlock */ -#define FD_LOCK 0x94 /* Fifo config lock */ -#define FD_RSEEK_OUT 0x8f /* seek out (i.e. to lower tracks) */ -#define FD_RSEEK_IN 0xcf /* seek in (i.e. to higher tracks) */ - - -/* the following commands are new in the 82078. They are not used in the - * floppy driver, except the first three. These commands may be useful for apps - * which use the FDRAWCMD interface. For doc, get the 82078 spec sheets at - * http://www-techdoc.intel.com/docs/periph/fd_contr/datasheets/ */ - -#define FD_PARTID 0x18 /* part id ("extended" version cmd) */ -#define FD_SAVE 0x2e /* save fdc regs for later restore */ -#define FD_DRIVESPEC 0x8e /* drive specification: Access to the - * 2 Mbps data transfer rate for tape - * drives */ - -#define FD_RESTORE 0x4e /* later restore */ -#define FD_POWERDOWN 0x27 /* configure FDC's powersave features */ -#define FD_FORMAT_N_WRITE 0xef /* format and write in one go. */ -#define FD_OPTION 0x33 /* ISO format (which is a clean way to - * pack more sectors on a track) */ - -/* FDC version return types */ -#define FDC_NONE 0x00 -#define FDC_UNKNOWN 0x10 /* DO NOT USE THIS TYPE EXCEPT IF IDENTIFICATION - FAILS EARLY */ -#define FDC_8272A 0x20 /* Intel 8272a, NEC 765 */ -#define FDC_765ED 0x30 /* Non-Intel 1MB-compatible FDC, can't detect */ -#define FDC_82072 0x40 /* Intel 82072; 8272a + FIFO + DUMPREGS */ -#define FDC_82072A 0x45 /* 82072A (on Sparcs) */ -#define FDC_82077_ORIG 0x51 /* Original version of 82077AA, sans LOCK */ -#define FDC_82077 0x52 /* 82077AA-1 */ -#define FDC_82078_UNKN 0x5f /* Unknown 82078 variant */ -#define FDC_82078 0x60 /* 44pin 82078 or 64pin 82078SL */ -#define FDC_82078_1 0x61 /* 82078-1 (2Mbps fdc) */ -#define FDC_S82078B 0x62 /* S82078B (first seen on Adaptec AVA-2825 VLB - * SCSI/EIDE/Floppy controller) */ -#define FDC_87306 0x63 /* National Semiconductor PC 87306 */ - -/* - * Beware: the fdc type list is roughly sorted by increasing features. - * Presence of features is tested by comparing the FDC version id with the - * "oldest" version that has the needed feature. - * If during FDC detection, an obscure test fails late in the sequence, don't - * assign FDC_UNKNOWN. Else the FDC will be treated as a dumb 8272a, or worse. - * This is especially true if the tests are unneeded. - */ - -/* Parameters for a 1.44 3.5" disk */ -#define DISK_H1440_SIZE 2880 -#define DISK_H1440_SECT 18 -#define DISK_H1440_HEAD 2 -#define DISK_H1440_TRACK 80 -#define DISK_H1440_STRETCH 0 -#define DISK_H1440_GAP 0x1B -#define DISK_H1440_RATE 0x00 -#define DISK_H1440_SPEC1 0xCF -#define DISK_H1440_FMT_GAP 0x6C - -/* Parameters for a 1.44 3.5" drive */ -#define DRIVE_H1440_MAX_DTR 500 -#define DRIVE_H1440_HLT 16 /* ms */ -#define DRIVE_H1440_HUT 16 /* ms */ -#define DRIVE_H1440_SRT 4000 /* us */ -#define DRIVE_H1440_SPINUP 400 /* ms */ -#define DRIVE_H1440_SPINDOWN 3000 /* ms */ -#define DRIVE_H1440_SPINDOWN_OFFSET 10 -#define DRIVE_H1440_SELECT_DELAY 20 /* ms */ -#define DRIVE_H1440_RPS 5 -#define DRIVE_H1440_TRACKS 83 -#define DRIVE_H1440_TIMEOUT 3000 /* ms */ -#define DRIVE_H1440_INTERLEAVE_SECT 20 - -/* Floppy drive configuration */ -#define FIFO_DEPTH 10 -#define USE_IMPLIED_SEEK 0 -#define USE_FIFO 1 -#define FIFO_THRESHOLD 10 -#define TRACK_PRECOMPENSATION 0 - -#define SLOW_FLOPPY 0 - -#define FD_RESET_DELAY 20 /* microseconds */ - -/* - * FDC state - */ -static struct drive_state { - unsigned track; -} drive_state[1]; - -static struct floppy_fdc_state { - int in_sync; - int spec1; /* spec1 value last used */ - int spec2; /* spec2 value last used */ - int dtr; - unsigned char dor; - unsigned char version; /* FDC version code */ - void (*fdc_outb)(unsigned char data, unsigned long port); - unsigned char (*fdc_inb)(unsigned long port); - unsigned long io_base; - unsigned long mmio_base; -} fdc_state; - -/* Synchronization of FDC access. */ -#define FD_COMMAND_NONE -1 -#define FD_COMMAND_ERROR 2 -#define FD_COMMAND_OKAY 3 - -/* - * globals used by 'result()' - */ -#define MAX_REPLIES 16 - -static void show_floppy(void); -static void floppy_reset(void); - -/* - * IO port operations - */ -static unsigned char -ob_fdc_inb(unsigned long port) -{ - return inb(fdc_state.io_base + port); -} - -static void -ob_fdc_outb(unsigned char data, unsigned long port) -{ - outb(data, fdc_state.io_base + port); -} - -/* - * MMIO operations - */ -static unsigned char -ob_fdc_mmio_readb(unsigned long port) -{ - return *(unsigned char *)(fdc_state.mmio_base + port); -} - -static void -ob_fdc_mmio_writeb(unsigned char data, unsigned long port) -{ - *(unsigned char *)(fdc_state.mmio_base + port) = data; -} - -static int set_dor(char mask, char data) -{ - unsigned char newdor,olddor; - - olddor = fdc_state.dor; - newdor = (olddor & mask) | data; - if (newdor != olddor){ - fdc_state.dor = newdor; - fdc_state.fdc_outb(newdor, FD_DOR); - } - return olddor; -} - -/* waits until the fdc becomes ready */ -static int wait_til_ready(void) -{ - int counter, status; - for (counter = 0; counter < 10000; counter++) { - status = fdc_state.fdc_inb(FD_STATUS); - if (status & STATUS_READY) { - return status; - } - } - printk_debug("Getstatus times out (%x)\n", status); - show_floppy(); - return -3; -} - - -/* sends a command byte to the fdc */ -static int output_byte(unsigned char byte) -{ - int status; - - if ((status = wait_til_ready()) < 0) - return status; - if ((status & (STATUS_READY|STATUS_DIR|STATUS_NON_DMA)) == STATUS_READY){ - fdc_state.fdc_outb(byte,FD_DATA); - return 0; - } - printk_debug("Unable to send byte %x to FDC_STATE. Status=%x\n", - byte, status); - - show_floppy(); - return -2; -} - -/* gets the response from the fdc */ -static int result(unsigned char *reply_buffer, int max_replies) -{ - int i, status=0; - - for(i=0; i < max_replies; i++) { - if ((status = wait_til_ready()) < 0) - break; - status &= STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_NON_DMA; - if ((status & ~STATUS_BUSY) == STATUS_READY){ - return i; - } - if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) - reply_buffer[i] = fdc_state.fdc_inb(FD_DATA); - else - break; - } - if (i == max_replies) - return i; - printk_debug("get result error. Last status=%x Read bytes=%d\n", - status, i); - show_floppy(); - return -1; -} -#define MORE_OUTPUT -2 -/* does the fdc need more output? */ -static int need_more_output(void) -{ - unsigned char reply_buffer[MAX_REPLIES]; - int status; - if ((status = wait_til_ready()) < 0) - return -1; - if ((status & (STATUS_READY|STATUS_DIR|STATUS_NON_DMA)) == STATUS_READY) - return MORE_OUTPUT; - return result(reply_buffer, MAX_REPLIES); -} - -static int output_command(unsigned char *cmd, int count) -{ - int i, status; - for(i = 0; i < count; i++) { - if ((status = output_byte(cmd[i])) < 0) { - printk_err("full command not acceppted, status =%x\n", - status); - return -1; - } - } - return 0; -} - -static int output_new_command(unsigned char *cmd, int count) -{ - int i, status; - if ((status = output_byte(cmd[0])) < 0) - return -1; - if (need_more_output() != MORE_OUTPUT) - return -1; - for(i = 1; i < count; i++) { - if ((status = output_byte(cmd[i])) < 0) { - printk_err("full new command not acceppted, status =%d\n", - status); - return -1; - } - } - return 0; -} - - -/* Collect pending interrupt status */ -static unsigned char collect_interrupt(void) -{ - unsigned char pcn = 0xff; - unsigned char reply_buffer[MAX_REPLIES]; - int nr; -#ifdef CONFIG_DEBUG_FLOPPY - int i, status; -#endif - nr = result(reply_buffer, MAX_REPLIES); - if (nr != 0) { - printk_debug("SENSEI\n"); - } - else { - int max_sensei = 4; - do { - if (output_byte(FD_SENSEI) < 0) - break; - nr = result(reply_buffer, MAX_REPLIES); - if (nr == 2) { - pcn = reply_buffer[1]; - printk_debug("SENSEI %02x %02x\n", - reply_buffer[0], reply_buffer[1]); - } - max_sensei--; - }while(((reply_buffer[0] & 0x83) != FD_DRIVE) && (nr == 2) && max_sensei); -#ifdef CONFIG_DEBUG_FLOPPY - status = fdc_state.fdc_inb(FD_STATUS); - printk_debug("status = %x, reply_buffer=", status); - for(i = 0; i < nr; i++) { - printk_debug(" %x", - reply_buffer[i]); - } - printk_debug("\n"); -#else - fdc_state.fdc_inb(FD_STATUS); -#endif - } - - return pcn; -} - - -/* selects the fdc and drive, and enables the fdc's input/dma, and it's motor. */ -static void set_drive(int drive) -{ - int fdc = (drive >> 2) & 1; - int status; - unsigned new_dor; - if (drive > 3) { - printk_err("bad drive value\n"); - return; - } - if (fdc != 0) { - printk_err("bad fdc value\n"); - return; - } - drive &= 3; -#if 0 - new_dor = 8; /* Enable the controller */ -#else - new_dor = 0; /* Don't enable DMA on the controller */ -#endif - new_dor |= (1 << (drive + 4)); /* Spinup the selected drive */ - new_dor |= drive; /* Select the drive for commands as well */ - set_dor(0xc, new_dor); - - mdelay(DRIVE_H1440_SPINUP); - - status = fdc_state.fdc_inb(FD_STATUS); - printk_debug("set_drive status = %02x, new_dor = %02x\n", - status, new_dor); - if (status != STATUS_READY) { - printk_err("set_drive bad status\n"); - } -} - - -/* Disable the motor for a given floppy drive */ -static void floppy_motor_off(int drive) -{ - unsigned mask; - printk_debug("floppy_motor_off\n"); - /* fix the number of drives */ - drive &= 3; - /* Clear the bit for the drive we care about */ - mask = 0xff; - mask &= ~(1 << (drive +4)); - /* Now clear the bit in the Digital Output Register */ - set_dor(mask, 0); -} - -/* Set the FDC's data transfer rate on behalf of the specified drive. - * NOTE: with 82072/82077 FDCs, changing the data rate requires a reissue - * of the specify command (i.e. using the fdc_specify function). - */ -static void fdc_dtr(unsigned rate) -{ - rate &= 3; - /* If data rate not already set to desired value, set it. */ - if (fdc_state.in_sync && (rate == fdc_state.dtr)) - return; - - /* Set dtr */ - fdc_state.fdc_outb(rate, FD_DCR); - - /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB) - * need a stabilization period of several milliseconds to be - * enforced after data rate changes before R/W operations. - * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) - */ - fdc_state.dtr = rate & 3; - mdelay(5); -} /* fdc_dtr */ - -static int fdc_configure(int use_implied_seek, int use_fifo, - unsigned fifo_threshold, unsigned precompensation) -{ - unsigned config_bits; - unsigned char cmd[4]; - /* 0 EIS EFIFO POLL FIFOOTHR[4] */ - - /* santize parameters */ - config_bits = fifo_threshold & 0xf; - config_bits |= (1 << 4); /* Always disable background floppy poll */ - config_bits |= (!use_fifo) << 5; - config_bits |= (!!use_implied_seek) << 6; - - precompensation &= 0xff; /* pre-compensation from track 0 upwards */ - - cmd[0] = FD_CONFIGURE; - cmd[1] = 0; - cmd[2] = config_bits; - cmd[3] = precompensation; - - /* Turn on FIFO */ - if (output_new_command(cmd, 4) < 0) - return 0; - return 1; -} - -#define NOMINAL_DTR 500 -/* Issue a "SPECIFY" command to set the step rate time, head unload time, - * head load time, and DMA disable flag to values needed by floppy. - * - * The value "dtr" is the data transfer rate in Kbps. It is needed - * to account for the data rate-based scaling done by the 82072 and 82077 - * FDC types. This parameter is ignored for other types of FDCs (i.e. - * 8272a). - * - * Note that changing the data transfer rate has a (probably deleterious) - * effect on the parameters subject to scaling for 82072/82077 FDCs, so - * fdc_specify is called again after each data transfer rate - * change. - * - * srt: 1000 to 16000 in microseconds - * hut: 16 to 240 milliseconds - * hlt: 2 to 254 milliseconds - * - * These values are rounded up to the next highest available delay time. - */ -static void fdc_specify( - unsigned head_load_time, unsigned head_unload_time, unsigned step_rate) -{ - unsigned char cmd[3]; - unsigned long srt, hlt, hut; - unsigned long dtr = NOMINAL_DTR; - unsigned long scale_dtr = NOMINAL_DTR; - int hlt_max_code = 0x7f; - int hut_max_code = 0xf; - - printk_debug("fdc_specify\n"); - - switch (DISK_H1440_RATE & 0x03) { - case 3: - dtr = 1000; - break; - case 1: - dtr = 300; - if (fdc_state.version >= FDC_82078) { - /* chose the default rate table, not the one - * where 1 = 2 Mbps */ - cmd[0] = FD_DRIVESPEC; - cmd[1] = FD_DRIVE & 3; - cmd[2] = 0xc0; - output_new_command(cmd,3); - /* FIXME how do I handle errors here? */ - } - break; - case 2: - dtr = 250; - break; - } - - - if (fdc_state.version >= FDC_82072) { - scale_dtr = dtr; - hlt_max_code = 0x00; /* 0==256msec*dtr0/dtr (not linear!) */ - hut_max_code = 0x0; /* 0==256msec*dtr0/dtr (not linear!) */ - } - - /* Convert step rate from microseconds to milliseconds and 4 bits */ - srt = 16 - (step_rate*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR; - if (SLOW_FLOPPY) { - srt = srt / 4; - } - if (srt > 0xf) { - srt = 0xf; - } - - hlt = (head_load_time*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR; - if (hlt < 0x01) - hlt = 0x01; - else if (hlt > 0x7f) - hlt = hlt_max_code; - - hut = (head_unload_time*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR; - if (hut < 0x1) - hut = 0x1; - else if (hut > 0xf) - hut = hut_max_code; - - cmd[0] = FD_SPECIFY; - cmd[1] = (srt << 4) | hut; - cmd[2] = (hlt << 1) | 1; /* Always disable DMA */ - - /* If these parameters did not change, just return with success */ - if (!fdc_state.in_sync || fdc_state.spec1 != cmd[1] || fdc_state.spec2 != cmd[2]) { - /* Go ahead and set spec1 and spec2 */ - output_command(cmd, 3); - /* FIXME how do I handle errors here... */ - printk_info("FD_SPECIFY(%02x, %02x)\n", cmd[1], cmd[2]); - } -} /* fdc_specify */ - - -/* - * reset is done by pulling bit 2 of DOR low for a while (old FDCs), - * or by setting the self clearing bit 7 of STATUS (newer FDCs) - */ -static void reset_fdc(void) -{ - unsigned char reply[MAX_REPLIES]; - - fdc_state.in_sync = 0; - - /* Pseudo-DMA may intercept 'reset finished' interrupt. */ - /* Irrelevant for systems with true DMA (i386). */ - - if (fdc_state.version >= FDC_82072A) - fdc_state.fdc_outb(0x80 | (fdc_state.dtr &3), FD_DSR); - else { - fdc_state.fdc_outb(fdc_state.dor & ~DOR_NO_RESET, FD_DOR); - udelay(FD_RESET_DELAY); - fdc_state.fdc_outb(fdc_state.dor, FD_DOR); - } - result(reply, MAX_REPLIES); -} - - - -static void show_floppy(void) -{ - - printk_debug("\n"); - printk_debug("floppy driver state\n"); - printk_debug("-------------------\n"); - - printk_debug("fdc_bytes: %02x %02x xx %02x %02x %02x xx %02x\n", - fdc_state.fdc_inb(FD_STATUS_A), - fdc_state.fdc_inb(FD_STATUS_B), - fdc_state.fdc_inb(FD_TDR), - fdc_state.fdc_inb(FD_STATUS), - fdc_state.fdc_inb(FD_DATA), - fdc_state.fdc_inb(FD_DIR)); - - printk_debug("status=%x\n", fdc_state.fdc_inb(FD_STATUS)); - printk_debug("\n"); -} - -static void floppy_recalibrate(void) -{ - unsigned char cmd[2]; - unsigned char reply[MAX_REPLIES]; - int nr, success; - success = 0; - do { - printk_debug("floppy_recalibrate\n"); - /* Send the recalibrate command to the controller. - * We don't have interrupts or anything we can poll - * so we have to guess when it is done. - */ - cmd[0] = FD_RECALIBRATE; - cmd[1] = 0; - if (output_command(cmd, 2) < 0) - continue; - - /* Sleep for the maximum time the recalibrate command - * can run. - */ - mdelay(80*DRIVE_H1440_SRT/1000); - - /* Now call FD_SENSEI to end the command - * and collect up the reply. - */ - if (output_byte(FD_SENSEI) < 0) - continue; - nr = result(reply, MAX_REPLIES); - - /* Now see if we have succeeded in our seek */ - success = - /* We have the right size result */ - (nr == 2) && - /* The command didn't terminate in error */ - ((reply[0] & ST0_INTR) == ST0_INTR_OK) && - /* We finished a seek */ - (reply[0] & ST0_SE) && - /* We are at cylinder 0 */ - (reply[1] == 0); - } while(!success); - /* Remember we are at track 0 */ - drive_state[FD_DRIVE].track = 0; -} - - -static int floppy_seek(unsigned track) -{ - unsigned char cmd[3]; - unsigned char reply[MAX_REPLIES]; - int nr, success; - unsigned distance, old_track; - - /* Look up the old track and see if we need to - * do anything. - */ - old_track = drive_state[FD_DRIVE].track; - if (old_track == track) { - return 1; - } - - /* Compute the distance we are about to move, - * We need to know this so we know how long to sleep... - */ - distance = (old_track > track)?(old_track - track):(track - old_track); - distance += 1; - - - /* Send the seek command to the controller. - * We don't have interrupts or anything we can poll - * so we have to guess when it is done. - */ - cmd[0] = FD_SEEK; - cmd[1] = FD_DRIVE; - cmd[2] = track; - if (output_command(cmd, 3) < 0) - return 0; - - /* Sleep for the time it takes to step throuhg distance tracks. - */ - mdelay(distance*DRIVE_H1440_SRT/1000); - - /* Now call FD_SENSEI to end the command - * and collect up the reply. - */ - cmd[0] = FD_SENSEI; - if (output_command(cmd, 1) < 0) - return 0; - nr = result(reply, MAX_REPLIES); - - /* Now see if we have succeeded in our seek */ - success = - /* We have the right size result */ - (nr == 2) && - /* The command didn't terminate in error */ - ((reply[0] & ST0_INTR) == ST0_INTR_OK) && - /* We finished a seek */ - (reply[0] & ST0_SE) && - /* We are at cylinder 0 */ - (reply[1] == track); - if (success) - drive_state[FD_DRIVE].track = track; - else { - printk_debug("seek failed\n"); - printk_debug("nr = %d\n", nr); - printk_debug("ST0 = %02x\n", reply[0]); - printk_debug("PCN = %02x\n", reply[1]); - printk_debug("status = %d\n", fdc_state.fdc_inb(FD_STATUS)); - } - return success; -} - -static int read_ok(unsigned head) -{ - unsigned char results[7]; - int result_ok; - int nr; - - /* read back the read results */ - nr = result(results, 7); - - /* Now see if they say we are o.k. */ - result_ok = 0; - /* Are my result bytes o.k.? */ - if (nr == 7) { - /* Are we o.k. */ - if ((results[0] & ST0_INTR) == ST0_INTR_OK) { - result_ok = 1; - } - /* Or did we get just an overflow error */ - else if (((results[0] & ST0_INTR) == ST0_INTR_ERROR) && - (results[1]== ST1_OR) && - (results[2] == 0)) { - result_ok = 1; - } - /* Verify the reply had the correct head */ - if (((results[0] & ST0_HA) >> 2) != head) { - result_ok = 0; - } - /* Verify the reply had the correct drive */ - if (((results[0] & ST0_DS) != FD_DRIVE)) { - result_ok = 0; - } - } - if (!result_ok) { - printk_debug("result_bytes = %d\n", nr); - printk_debug("ST0 = %02x\n", results[0]); - printk_debug("ST1 = %02x\n", results[1]); - printk_debug("ST2 = %02x\n", results[2]); - printk_debug(" C = %02x\n", results[3]); - printk_debug(" H = %02x\n", results[4]); - printk_debug(" R = %02x\n", results[5]); - printk_debug(" N = %02x\n", results[6]); - } - return result_ok; -} - -static int floppy_read_sectors( - char *dest, unsigned byte_offset, unsigned length, - unsigned sector, unsigned head, unsigned track) -{ - /* MT == Multitrack */ - /* MFM == MFM or FM Mode */ - /* SK == Skip deleted data addres Mark */ - /* HDS == Head number select */ - /* DS0 == Disk Drive Select 0 */ - /* DS1 == Disk Drive Select 1 */ - /* C == Cylinder number 0 - 255 */ - /* H == Head number */ - /* R == Record */ - /* N == The number of data bytes written in a sector */ - /* EOT == End of Track */ - /* GPL == Gap Length */ - /* DTL == Data Length */ - /* MT MFM SK 0 1 1 0 0 */ - /* 0 0 0 0 0 HDS DS1 DS0 */ - /* C, H, R, N, EOT, GPL, DTL */ - - int i, status, result_ok; - int max_bytes, bytes_read; - int ret; - unsigned char cmd[9]; - unsigned end_offset; - - end_offset = byte_offset + length; - max_bytes = 512*(DISK_H1440_SECT - sector + 1); - - if (byte_offset >= max_bytes) { - return 0; - } - cmd[0] = FD_READ | (((DISK_H1440_HEAD ==2)?1:0) << 6); - cmd[1] = (head << 2) | FD_DRIVE; - cmd[2] = track; - cmd[3] = head; - cmd[4] = sector; - cmd[5] = 2; /* 2^N *128 == Sector size. Hard coded to 512 bytes */ - cmd[6] = DISK_H1440_SECT; - cmd[7] = DISK_H1440_GAP; - cmd[8] = 0xff; - - /* Output the command bytes */ - if (output_command(cmd, 9) < 0) - return -1; - - /* The execution stage begins when STATUS_READY&STATUS_NON_DMA is set */ - do { - status = fdc_state.fdc_inb(FD_STATUS); - status &= STATUS_READY | STATUS_NON_DMA; - } while(status != (STATUS_READY|STATUS_NON_DMA)); - - for(i = 0; i < max_bytes; i++) { - unsigned char byte; - if ((status = wait_til_ready()) < 0) { - break; - } - status &= STATUS_READY|STATUS_DIR|STATUS_NON_DMA; - if (status != (STATUS_READY|STATUS_DIR|STATUS_NON_DMA)) { - break; - } - byte = fdc_state.fdc_inb(FD_DATA); - if ((i >= byte_offset) && (i < end_offset)) { - dest[i - byte_offset] = byte; - } - } - bytes_read = i; - - /* The result stage begins when STATUS_NON_DMA is cleared */ - while((status = fdc_state.fdc_inb(FD_STATUS)) & STATUS_NON_DMA) { - /* We get extra bytes in the fifo past - * the end of the sector and drop them on the floor. - * Otherwise the fifo is polluted. - */ - fdc_state.fdc_inb(FD_DATA); - } - /* Did I get an error? */ - result_ok = read_ok(head); - /* Did I read enough bytes? */ - ret = -1; - if (result_ok && (bytes_read == max_bytes)) { - ret = bytes_read - byte_offset; - if (ret > length) { - ret = length; - } - } - - if (ret < 0) { - printk_debug("ret = %d\n", ret); - printk_debug("bytes_read = %d\n", bytes_read); - printk_debug("status = %x\n", status); - } - return ret; -} - - -static int __floppy_read(char *dest, unsigned long offset, unsigned long length) -{ - unsigned head, track, sector, byte_offset, sector_offset; - int ret; - - /* break the offset up into sectors and bytes */ - byte_offset = offset % 512; - sector_offset = offset / 512; - - /* Find the disk block we are starting with... */ - sector = (sector_offset % DISK_H1440_SECT) + 1; - head = (sector_offset / DISK_H1440_SECT) % DISK_H1440_HEAD; - track = (sector_offset / (DISK_H1440_SECT *DISK_H1440_HEAD))% DISK_H1440_TRACK; - - /* First seek to our start track */ - if (!floppy_seek(track)) { - return -1; - } - /* Then read the data */ - ret = floppy_read_sectors(dest, byte_offset, length, sector, head, track); - if (ret >= 0) { - return ret; - } - /* If we failed reset the fdc... */ - floppy_reset(); - return -1; -} - -static int floppy_read(char *dest, unsigned long offset, unsigned long length) -{ - int fr_result, bytes_read;; - - printk_debug("floppy_read\n"); - bytes_read = 0; - do { - int max_errors = 3; - do { - fr_result = __floppy_read(dest + bytes_read, offset, - length - bytes_read); - if (max_errors-- == 0) { - return (bytes_read)?bytes_read: -1; - } - } while (fr_result <= 0); - offset += fr_result; - bytes_read += fr_result; - } while(bytes_read < length); - return bytes_read; -} - -/* Determine the floppy disk controller type */ -/* This routine was written by David C. Niemi */ -static char get_fdc_version(void) -{ - int bytes, ret; - unsigned char reply_buffer[MAX_REPLIES]; - - ret = output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */ - if (ret < 0) - return FDC_NONE; - if ((bytes = result(reply_buffer, MAX_REPLIES)) <= 0x00) - return FDC_NONE; /* No FDC present ??? */ - if ((bytes==1) && (reply_buffer[0] == 0x80)){ - printk_info("FDC is an 8272A\n"); - return FDC_8272A; /* 8272a/765 don't know DUMPREGS */ - } - if (bytes != 10) { - printk_debug("init: DUMPREGS: unexpected return of %d bytes.\n", - bytes); - return FDC_UNKNOWN; - } - if (!fdc_configure(USE_IMPLIED_SEEK, USE_FIFO, FIFO_THRESHOLD, - TRACK_PRECOMPENSATION)) { - printk_info("FDC is an 82072\n"); - return FDC_82072; /* 82072 doesn't know CONFIGURE */ - } - - output_byte(FD_PERPENDICULAR); - if (need_more_output() == MORE_OUTPUT) { - output_byte(0); - } else { - printk_info("FDC is an 82072A\n"); - return FDC_82072A; /* 82072A as found on Sparcs. */ - } - - output_byte(FD_UNLOCK); - bytes = result(reply_buffer, MAX_REPLIES); - if ((bytes == 1) && (reply_buffer[0] == 0x80)){ - printk_info("FDC is a pre-1991 82077\n"); - return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know - * LOCK/UNLOCK */ - } - if ((bytes != 1) || (reply_buffer[0] != 0x00)) { - printk_debug("FDC init: UNLOCK: unexpected return of %d bytes.\n", - bytes); - return FDC_UNKNOWN; - } - output_byte(FD_PARTID); - bytes = result(reply_buffer, MAX_REPLIES); - if (bytes != 1) { - printk_debug("FDC init: PARTID: unexpected return of %d bytes.\n", - bytes); - return FDC_UNKNOWN; - } - if (reply_buffer[0] == 0x80) { - printk_info("FDC is a post-1991 82077\n"); - return FDC_82077; /* Revised 82077AA passes all the tests */ - } - switch (reply_buffer[0] >> 5) { - case 0x0: - /* Either a 82078-1 or a 82078SL running at 5Volt */ - printk_info("FDC is an 82078.\n"); - return FDC_82078; - case 0x1: - printk_info("FDC is a 44pin 82078\n"); - return FDC_82078; - case 0x2: - printk_info("FDC is a S82078B\n"); - return FDC_S82078B; - case 0x3: - printk_info("FDC is a National Semiconductor PC87306\n"); - return FDC_87306; - default: - printk_info("FDC init: 82078 variant with unknown PARTID=%d.\n", - reply_buffer[0] >> 5); - return FDC_82078_UNKN; - } -} /* get_fdc_version */ - - -static int floppy_init(unsigned long io_base, unsigned long mmio_base) -{ - printk_debug("floppy_init\n"); - fdc_state.in_sync = 0; - fdc_state.spec1 = -1; - fdc_state.spec2 = -1; - fdc_state.dtr = -1; - fdc_state.dor = DOR_NO_RESET; - fdc_state.version = FDC_UNKNOWN; - if (mmio_base) { - fdc_state.fdc_inb = ob_fdc_mmio_readb; - fdc_state.fdc_outb = ob_fdc_mmio_writeb; - } else { - fdc_state.fdc_inb = ob_fdc_inb; - fdc_state.fdc_outb = ob_fdc_outb; - } - fdc_state.io_base = io_base; - fdc_state.mmio_base = mmio_base; - reset_fdc(); - /* Try to determine the floppy controller type */ - fdc_state.version = get_fdc_version(); - if (fdc_state.version == FDC_NONE) { - return -1; - } - floppy_reset(); - printk_info("fdc_state.version = %04x\n", fdc_state.version); - return 0; -} - -static void floppy_reset(void) -{ - printk_debug("floppy_reset\n"); - floppy_motor_off(FD_DRIVE); - reset_fdc(); - fdc_dtr(DISK_H1440_RATE); - /* program data rate via ccr */ - collect_interrupt(); - fdc_configure(USE_IMPLIED_SEEK, USE_FIFO, FIFO_THRESHOLD, - TRACK_PRECOMPENSATION); - fdc_specify(DRIVE_H1440_HLT, DRIVE_H1440_HUT, DRIVE_H1440_SRT); - set_drive(FD_DRIVE); - floppy_recalibrate(); - fdc_state.in_sync = 1; -} - -static void -ob_floppy_initialize(const char *path) -{ - int props[3]; - phandle_t ph = find_dev(path); - - set_property(ph, "device_type", "block", sizeof("block")); - - // Set dummy reg properties - props[0] = __cpu_to_be32(0); props[1] = __cpu_to_be32(0); props[2] = __cpu_to_be32(0); - set_property(ph, "reg", (char *)&props, 3*sizeof(int)); - - fword("is-deblocker"); -} - - -static void -ob_floppy_open(int *idx) -{ - int ret = 1; - phandle_t ph; - - fword("my-unit"); - idx[0]=POP(); - - fword("my-parent"); - fword("ihandle>phandle"); - ph=(phandle_t)POP(); - - selfword("open-deblocker"); - - /* interpose disk-label */ - ph = find_dev("/packages/disk-label"); - fword("my-args"); - PUSH_ph( ph ); - fword("interpose"); - - RET ( -ret ); -} - -static void -ob_floppy_close(int *idx) -{ - selfword("close-deblocker"); -} - -static void -ob_floppy_read_blocks(int *idx) -{ - cell cnt = POP(); - ucell blk = POP(); - char *dest = (char*)POP(); - floppy_read(dest, blk*512, cnt*512); - PUSH(cnt); -} - - -static void -ob_floppy_block_size(int *idx) -{ - PUSH(512); -} - -static void -ob_floppy_max_transfer(int *idx) -{ - // Fixme - PUSH(18 * 512); -} - -NODE_METHODS(ob_floppy) = { - { "open", ob_floppy_open }, - { "close", ob_floppy_close }, - { "read-blocks", ob_floppy_read_blocks }, - { "block-size", ob_floppy_block_size }, - { "max-transfer", ob_floppy_max_transfer }, -}; - - -int ob_floppy_init(const char *path, const char *dev_name, - unsigned long io_base, unsigned long mmio_base) -{ - char nodebuff[128]; - phandle_t aliases; - - snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name); - if (!mmio_base) { - REGISTER_NAMED_NODE(ob_floppy, nodebuff); - ob_floppy_initialize(nodebuff); - } else { - // Already in tree and mapped - REGISTER_NODE_METHODS(ob_floppy, nodebuff); - } - floppy_init(io_base, mmio_base); - - aliases = find_dev("/aliases"); - set_property(aliases, "floppy", nodebuff, strlen(nodebuff) + 1); - - return 0; -} diff --git a/qemu/roms/openbios/drivers/floppy.h b/qemu/roms/openbios/drivers/floppy.h deleted file mode 100644 index b0f30d555..000000000 --- a/qemu/roms/openbios/drivers/floppy.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef FLOPPY_SUBR_H -#define FLOPPY_SUBR_H - -int floppy_init(void); -int floppy_read(char *dest, unsigned long offset, unsigned long length); -void floppy_fini(void); - - -#endif /* FLOPPY_SUBR_H */ diff --git a/qemu/roms/openbios/drivers/fw_cfg.c b/qemu/roms/openbios/drivers/fw_cfg.c deleted file mode 100644 index 402757070..000000000 --- a/qemu/roms/openbios/drivers/fw_cfg.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "config.h" -#include "libopenbios/bindings.h" -#include "libc/byteorder.h" -#include "libopenbios/ofmem.h" -#define NO_QEMU_PROTOS -#include "arch/common/fw_cfg.h" - -#if !defined(CONFIG_SPARC64) -static volatile uint16_t *fw_cfg_cmd; -static volatile uint8_t *fw_cfg_data; - -void -fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) -{ - unsigned int i; - - *fw_cfg_cmd = cmd; - for (i = 0; i < nbytes; i++) - buf[i] = *fw_cfg_data; -} -#else -// XXX depends on PCI bus location, should be removed -void -fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) -{ - unsigned int i; - - outw(cmd, CONFIG_FW_CFG_ADDR); - for (i = 0; i < nbytes; i++) - buf[i] = inb(CONFIG_FW_CFG_ADDR + 1); -} -#endif - -uint64_t -fw_cfg_read_i64(uint16_t cmd) -{ - uint64_t buf; - - fw_cfg_read(cmd, (char *)&buf, sizeof(uint64_t)); - - return __le64_to_cpu(buf); -} - -uint32_t -fw_cfg_read_i32(uint16_t cmd) -{ - uint32_t buf; - - fw_cfg_read(cmd, (char *)&buf, sizeof(uint32_t)); - - return __le32_to_cpu(buf); -} - -uint16_t -fw_cfg_read_i16(uint16_t cmd) -{ - uint16_t buf; - - fw_cfg_read(cmd, (char *)&buf, sizeof(uint16_t)); - - return __le16_to_cpu(buf); -} - -void -fw_cfg_init(void) -{ -#if defined(CONFIG_SPARC32) - fw_cfg_cmd = (void *)ofmem_map_io(CONFIG_FW_CFG_ADDR, 2); - fw_cfg_data = (uint8_t *)fw_cfg_cmd + 2; -#elif defined(CONFIG_SPARC64) - // Nothing for the port version -#elif defined(CONFIG_PPC) - fw_cfg_cmd = (void *)CONFIG_FW_CFG_ADDR; - fw_cfg_data = (void *)(CONFIG_FW_CFG_ADDR + 2); -#endif -} diff --git a/qemu/roms/openbios/drivers/hdreg.h b/qemu/roms/openbios/drivers/hdreg.h deleted file mode 100644 index 91e4d1ff6..000000000 --- a/qemu/roms/openbios/drivers/hdreg.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * this header holds data structures as dictated by spec - */ -#ifndef HDREG_H -#define HDREG_H - -struct hd_driveid { - unsigned short config; /* lots of obsolete bit flags */ - unsigned short cyls; /* Obsolete, "physical" cyls */ - unsigned short reserved2; /* reserved (word 2) */ - unsigned short heads; /* Obsolete, "physical" heads */ - unsigned short track_bytes; /* unformatted bytes per track */ - unsigned short sector_bytes; /* unformatted bytes per sector */ - unsigned short sectors; /* Obsolete, "physical" sectors per track */ - unsigned short vendor0; /* vendor unique */ - unsigned short vendor1; /* vendor unique */ - unsigned short vendor2; /* Retired vendor unique */ - unsigned char serial_no[20]; /* 0 = not_specified */ - unsigned short buf_type; /* Retired */ - unsigned short buf_size; /* Retired, 512 byte increments - * 0 = not_specified - */ - unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */ - unsigned char fw_rev[8]; /* 0 = not_specified */ - unsigned char model[40]; /* 0 = not_specified */ - unsigned char max_multsect; /* 0=not_implemented */ - unsigned char vendor3; /* vendor unique */ - unsigned short dword_io; /* 0=not_implemented; 1=implemented */ - unsigned char vendor4; /* vendor unique */ - unsigned char capability; /* (upper byte of word 49) - * 3: IORDYsup - * 2: IORDYsw - * 1: LBA - * 0: DMA - */ - unsigned short reserved50; /* reserved (word 50) */ - unsigned char vendor5; /* Obsolete, vendor unique */ - unsigned char tPIO; /* Obsolete, 0=slow, 1=medium, 2=fast */ - unsigned char vendor6; /* Obsolete, vendor unique */ - unsigned char tDMA; /* Obsolete, 0=slow, 1=medium, 2=fast */ - unsigned short field_valid; /* (word 53) - * 2: ultra_ok word 88 - * 1: eide_ok words 64-70 - * 0: cur_ok words 54-58 - */ - unsigned short cur_cyls; /* Obsolete, logical cylinders */ - unsigned short cur_heads; /* Obsolete, l heads */ - unsigned short cur_sectors; /* Obsolete, l sectors per track */ - unsigned short cur_capacity0; /* Obsolete, l total sectors on drive */ - unsigned short cur_capacity1; /* Obsolete, (2 words, misaligned int) */ - unsigned char multsect; /* current multiple sector count */ - unsigned char multsect_valid; /* when (bit0==1) multsect is ok */ - unsigned int lba_capacity; /* Obsolete, total number of sectors */ - unsigned short dma_1word; /* Obsolete, single-word dma info */ - unsigned short dma_mword; /* multiple-word dma info */ - unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */ - unsigned short eide_dma_min; /* min mword dma cycle time (ns) */ - unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */ - unsigned short eide_pio; /* min cycle time (ns), no IORDY */ - unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */ - unsigned short words69_70[2]; /* reserved words 69-70 - * future command overlap and queuing - */ - /* HDIO_GET_IDENTITY currently returns only words 0 through 70 */ - unsigned short words71_74[4]; /* reserved words 71-74 - * for IDENTIFY PACKET DEVICE command - */ - unsigned short queue_depth; /* (word 75) - * 15:5 reserved - * 4:0 Maximum queue depth -1 - */ - unsigned short words76_79[4]; /* reserved words 76-79 */ - unsigned short major_rev_num; /* (word 80) */ - unsigned short minor_rev_num; /* (word 81) */ - unsigned short command_set_1; /* (word 82) supported - * 15: Obsolete - * 14: NOP command - * 13: READ_BUFFER - * 12: WRITE_BUFFER - * 11: Obsolete - * 10: Host Protected Area - * 9: DEVICE Reset - * 8: SERVICE Interrupt - * 7: Release Interrupt - * 6: look-ahead - * 5: write cache - * 4: PACKET Command - * 3: Power Management Feature Set - * 2: Removable Feature Set - * 1: Security Feature Set - * 0: SMART Feature Set - */ - unsigned short command_set_2; /* (word 83) - * 15: Shall be ZERO - * 14: Shall be ONE - * 13: FLUSH CACHE EXT - * 12: FLUSH CACHE - * 11: Device Configuration Overlay - * 10: 48-bit Address Feature Set - * 9: Automatic Acoustic Management - * 8: SET MAX security - * 7: reserved 1407DT PARTIES - * 6: SetF sub-command Power-Up - * 5: Power-Up in Standby Feature Set - * 4: Removable Media Notification - * 3: APM Feature Set - * 2: CFA Feature Set - * 1: READ/WRITE DMA QUEUED - * 0: Download MicroCode - */ - unsigned short cfsse; /* (word 84) - * cmd set-feature supported extensions - * 15: Shall be ZERO - * 14: Shall be ONE - * 13:6 reserved - * 5: General Purpose Logging - * 4: Streaming Feature Set - * 3: Media Card Pass Through - * 2: Media Serial Number Valid - * 1: SMART selt-test supported - * 0: SMART error logging - */ - unsigned short cfs_enable_1; /* (word 85) - * command set-feature enabled - * 15: Obsolete - * 14: NOP command - * 13: READ_BUFFER - * 12: WRITE_BUFFER - * 11: Obsolete - * 10: Host Protected Area - * 9: DEVICE Reset - * 8: SERVICE Interrupt - * 7: Release Interrupt - * 6: look-ahead - * 5: write cache - * 4: PACKET Command - * 3: Power Management Feature Set - * 2: Removable Feature Set - * 1: Security Feature Set - * 0: SMART Feature Set - */ - unsigned short cfs_enable_2; /* (word 86) - * command set-feature enabled - * 15: Shall be ZERO - * 14: Shall be ONE - * 13: FLUSH CACHE EXT - * 12: FLUSH CACHE - * 11: Device Configuration Overlay - * 10: 48-bit Address Feature Set - * 9: Automatic Acoustic Management - * 8: SET MAX security - * 7: reserved 1407DT PARTIES - * 6: SetF sub-command Power-Up - * 5: Power-Up in Standby Feature Set - * 4: Removable Media Notification - * 3: APM Feature Set - * 2: CFA Feature Set - * 1: READ/WRITE DMA QUEUED - * 0: Download MicroCode - */ - unsigned short csf_default; /* (word 87) - * command set-feature default - * 15: Shall be ZERO - * 14: Shall be ONE - * 13:6 reserved - * 5: General Purpose Logging enabled - * 4: Valid CONFIGURE STREAM executed - * 3: Media Card Pass Through enabled - * 2: Media Serial Number Valid - * 1: SMART selt-test supported - * 0: SMART error logging - */ - unsigned short dma_ultra; /* (word 88) */ - unsigned short trseuc; /* time required for security erase */ - unsigned short trsEuc; /* time required for enhanced erase */ - unsigned short CurAPMvalues; /* current APM values */ - unsigned short mprc; /* master password revision code */ - unsigned short hw_config; /* hardware config (word 93) - * 15: Shall be ZERO - * 14: Shall be ONE - * 13: - * 12: - * 11: - * 10: - * 9: - * 8: - * 7: - * 6: - * 5: - * 4: - * 3: - * 2: - * 1: - * 0: Shall be ONE - */ - unsigned short acoustic; /* (word 94) - * 15:8 Vendor's recommended value - * 7:0 current value - */ - unsigned short msrqs; /* min stream request size */ - unsigned short sxfert; /* stream transfer time */ - unsigned short sal; /* stream access latency */ - unsigned int spg; /* stream performance granularity */ - unsigned long long lba_capacity_2;/* 48-bit total number of sectors */ - unsigned short words104_125[22];/* reserved words 104-125 */ - unsigned short last_lun; /* (word 126) */ - unsigned short word127; /* (word 127) Feature Set - * Removable Media Notification - * 15:2 reserved - * 1:0 00 = not supported - * 01 = supported - * 10 = reserved - * 11 = reserved - */ - unsigned short dlf; /* (word 128) - * device lock function - * 15:9 reserved - * 8 security level 1:max 0:high - * 7:6 reserved - * 5 enhanced erase - * 4 expire - * 3 frozen - * 2 locked - * 1 en/disabled - * 0 capability - */ - unsigned short csfo; /* (word 129) - * current set features options - * 15:4 reserved - * 3: auto reassign - * 2: reverting - * 1: read-look-ahead - * 0: write cache - */ - unsigned short words130_155[26];/* reserved vendor words 130-155 */ - unsigned short word156; /* reserved vendor word 156 */ - unsigned short words157_159[3];/* reserved vendor words 157-159 */ - unsigned short cfa_power; /* (word 160) CFA Power Mode - * 15 word 160 supported - * 14 reserved - * 13 - * 12 - * 11:0 - */ - unsigned short words161_175[15];/* Reserved for CFA */ - unsigned short words176_205[30];/* Current Media Serial Number */ - unsigned short words206_254[49];/* reserved words 206-254 */ - unsigned short integrity_word; /* (word 255) - * 15:8 Checksum - * 7:0 Signature - */ -}; - -struct request_sense { -#if defined(CONFIG_BIG_ENDIAN) - u8 valid : 1; - u8 error_code : 7; -#elif defined(CONFIG_LITTLE_ENDIAN) - u8 error_code : 7; - u8 valid : 1; -#endif - u8 segment_number; -#if defined(CONFIG_BIG_ENDIAN) - u8 reserved1 : 2; - u8 ili : 1; - u8 reserved2 : 1; - u8 sense_key : 4; -#elif defined(CONFIG_LITTLE_ENDIAN) - u8 sense_key : 4; - u8 reserved2 : 1; - u8 ili : 1; - u8 reserved1 : 2; -#endif - u8 information[4]; - u8 add_sense_len; - u8 command_info[4]; - u8 asc; - u8 ascq; - u8 fruc; - u8 sks[3]; - u8 asb[46]; -}; - -struct atapi_capacity { - u32 lba; - u32 block_size; -}; - -#endif diff --git a/qemu/roms/openbios/drivers/ide.c b/qemu/roms/openbios/drivers/ide.c deleted file mode 100644 index 1da60c895..000000000 --- a/qemu/roms/openbios/drivers/ide.c +++ /dev/null @@ -1,1701 +0,0 @@ -/* - * OpenBIOS polled ide driver - * - * Copyright (C) 2004 Jens Axboe - * Copyright (C) 2005 Stefan Reinauer - * - * Credit goes to Hale Landis for his excellent ata demo software - * OF node handling and some fixes by Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "kernel/kernel.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "drivers/drivers.h" -#include "ide.h" -#include "hdreg.h" -#include "timer.h" - -#ifdef CONFIG_DEBUG_IDE -#define IDE_DPRINTF(fmt, args...) \ -do { printk("IDE - %s: " fmt, __func__ , ##args); } while (0) -#else -#define IDE_DPRINTF(fmt, args...) do { } while (0) -#endif - -/* DECLARE data structures for the nodes. */ -DECLARE_UNNAMED_NODE( ob_ide, INSTALL_OPEN, sizeof(struct ide_drive*) ); -DECLARE_UNNAMED_NODE( ob_ide_ctrl, INSTALL_OPEN, sizeof(int)); - -/* - * define to 2 for the standard 2 channels only - */ -#ifndef CONFIG_IDE_NUM_CHANNELS -#define IDE_NUM_CHANNELS 4 -#else -#define IDE_NUM_CHANNELS CONFIG_IDE_NUM_CHANNELS -#endif -#define IDE_MAX_CHANNELS 4 - -#ifndef CONFIG_IDE_FIRST_UNIT -#define FIRST_UNIT 0 -#else -#define FIRST_UNIT CONFIG_IDE_FIRST_UNIT -#endif - -#ifndef CONFIG_IDE_DEV_TYPE -#define DEV_TYPE "ide" -#else -#define DEV_TYPE CONFIG_IDE_DEV_TYPE -#endif - -#ifndef CONFIG_IDE_DEV_NAME -#define DEV_NAME "ide%d" -#else -#define DEV_NAME CONFIG_IDE_DEV_NAME -#endif - -static int current_channel = FIRST_UNIT; - -static struct ide_channel *channels = NULL; - -static inline void ide_add_channel(struct ide_channel *chan) -{ - chan->next = channels; - channels = chan; -} - -static struct ide_channel *ide_seek_channel(phandle_t ph) -{ - struct ide_channel *current; - - current = channels; - while (current) { - if (current->ph == ph) - return current; - current = current->next; - } - return NULL; -} - -/* - * don't be pedantic - */ -#undef ATA_PEDANTIC - -static void dump_drive(struct ide_drive *drive) -{ -#ifdef CONFIG_DEBUG_IDE - printk("IDE DRIVE @%lx:\n", (unsigned long)drive); - printk("unit: %d\n",drive->unit); - printk("present: %d\n",drive->present); - printk("type: %d\n",drive->type); - printk("media: %d\n",drive->media); - printk("model: %s\n",drive->model); - printk("nr: %d\n",drive->nr); - printk("cyl: %d\n",drive->cyl); - printk("head: %d\n",drive->head); - printk("sect: %d\n",drive->sect); - printk("bs: %d\n",drive->bs); -#endif -} - -/* - * old style io port operations - */ -static unsigned char -ob_ide_inb(struct ide_channel *chan, unsigned int port) -{ - return inb(chan->io_regs[port]); -} - -static void -ob_ide_outb(struct ide_channel *chan, unsigned char data, unsigned int port) -{ - outb(data, chan->io_regs[port]); -} - -static void -ob_ide_insw(struct ide_channel *chan, - unsigned int port, unsigned char *addr, unsigned int count) -{ - insw(chan->io_regs[port], addr, count); -} - -static void -ob_ide_outsw(struct ide_channel *chan, - unsigned int port, unsigned char *addr, unsigned int count) -{ - outsw(chan->io_regs[port], addr, count); -} - -static inline unsigned char -ob_ide_pio_readb(struct ide_drive *drive, unsigned int offset) -{ - struct ide_channel *chan = drive->channel; - - return chan->obide_inb(chan, offset); -} - -static inline void -ob_ide_pio_writeb(struct ide_drive *drive, unsigned int offset, - unsigned char data) -{ - struct ide_channel *chan = drive->channel; - - chan->obide_outb(chan, data, offset); -} - -static inline void -ob_ide_pio_insw(struct ide_drive *drive, unsigned int offset, - unsigned char *addr, unsigned int len) -{ - struct ide_channel *chan = drive->channel; - - if (len & 1) { - IDE_DPRINTF("%d: command not word aligned\n", drive->nr); - return; - } - - chan->obide_insw(chan, offset, addr, len / 2); -} - -static inline void -ob_ide_pio_outsw(struct ide_drive *drive, unsigned int offset, - unsigned char *addr, unsigned int len) -{ - struct ide_channel *chan = drive->channel; - - if (len & 1) { - IDE_DPRINTF("%d: command not word aligned\n", drive->nr); - return; - } - - chan->obide_outsw(chan, offset, addr, len / 2); -} - -static void -ob_ide_400ns_delay(struct ide_drive *drive) -{ - (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); - (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); - (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); - (void) ob_ide_pio_readb(drive, IDEREG_ASTATUS); - - udelay(1); -} - -static void -ob_ide_error(struct ide_drive *drive, unsigned char stat, const char *msg) -{ -#ifdef CONFIG_DEBUG_IDE - struct ide_channel *chan = drive->channel; - unsigned char err; -#endif - - if (!stat) - stat = ob_ide_pio_readb(drive, IDEREG_STATUS); - - IDE_DPRINTF("ob_ide_error drive<%d>: %s:\n", drive->nr, msg); - IDE_DPRINTF(" cmd=%x, stat=%x", chan->ata_cmd.command, stat); - - if ((stat & (BUSY_STAT | ERR_STAT)) == ERR_STAT) { -#ifdef CONFIG_DEBUG_IDE - err = -#endif - ob_ide_pio_readb(drive, IDEREG_ERROR); - IDE_DPRINTF(", err=%x", err); - } - IDE_DPRINTF("\n"); - -#ifdef CONFIG_DEBUG_IDE - /* - * see if sense is valid and dump that - */ - if (chan->ata_cmd.command == WIN_PACKET) { - struct atapi_command *cmd = &chan->atapi_cmd; - unsigned char old_cdb = cmd->cdb[0]; - - if (cmd->cdb[0] == ATAPI_REQ_SENSE) { - old_cdb = cmd->old_cdb; - - IDE_DPRINTF(" atapi opcode=%02x", old_cdb); - } else { - int i; - - IDE_DPRINTF(" cdb: "); - for (i = 0; i < sizeof(cmd->cdb); i++) - IDE_DPRINTF("%02x ", cmd->cdb[i]); - } - if (cmd->sense_valid) - IDE_DPRINTF(", sense: %02x/%02x/%02x", - cmd->sense.sense_key, cmd->sense.asc, - cmd->sense.ascq); - else - IDE_DPRINTF(", no sense"); - IDE_DPRINTF("\n"); - } -#endif -} - -/* - * wait for 'stat' to be set. returns 1 if failed, 0 if succesful - */ -static int -ob_ide_wait_stat(struct ide_drive *drive, unsigned char ok_stat, - unsigned char bad_stat, unsigned char *ret_stat) -{ - unsigned char stat; - int i; - - ob_ide_400ns_delay(drive); - - for (i = 0; i < 5000; i++) { - stat = ob_ide_pio_readb(drive, IDEREG_STATUS); - if (!(stat & BUSY_STAT)) - break; - - udelay(1000); - } - - if (ret_stat) - *ret_stat = stat; - - if (stat & bad_stat) - return 1; - - if ((stat & ok_stat) || !ok_stat) - return 0; - - return 1; -} - -static int -ob_ide_select_drive(struct ide_drive *drive) -{ - struct ide_channel *chan = drive->channel; - unsigned char control = IDEHEAD_DEV0; - - if (ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL)) { - IDE_DPRINTF("select_drive: timed out\n"); - return 1; - } - - /* - * don't select drive if already active. Note: we always - * wait for BUSY clear - */ - if (drive->unit == chan->selected) - return 0; - - if (drive->unit) - control = IDEHEAD_DEV1; - - ob_ide_pio_writeb(drive, IDEREG_CURRENT, control); - ob_ide_400ns_delay(drive); - - if (ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL)) { - IDE_DPRINTF("select_drive: timed out\n"); - return 1; - } - - chan->selected = drive->unit; - return 0; -} - -static void -ob_ide_write_tasklet(struct ide_drive *drive, struct ata_command *cmd) -{ - ob_ide_pio_writeb(drive, IDEREG_FEATURE, cmd->task[1]); - ob_ide_pio_writeb(drive, IDEREG_NSECTOR, cmd->task[3]); - ob_ide_pio_writeb(drive, IDEREG_SECTOR, cmd->task[7]); - ob_ide_pio_writeb(drive, IDEREG_LCYL, cmd->task[8]); - ob_ide_pio_writeb(drive, IDEREG_HCYL, cmd->task[9]); - - ob_ide_pio_writeb(drive, IDEREG_FEATURE, cmd->task[0]); - ob_ide_pio_writeb(drive, IDEREG_NSECTOR, cmd->task[2]); - ob_ide_pio_writeb(drive, IDEREG_SECTOR, cmd->task[4]); - ob_ide_pio_writeb(drive, IDEREG_LCYL, cmd->task[5]); - ob_ide_pio_writeb(drive, IDEREG_HCYL, cmd->task[6]); - - if (drive->unit) - cmd->device_head |= IDEHEAD_DEV1; - - ob_ide_pio_writeb(drive, IDEREG_CURRENT, cmd->device_head); - - ob_ide_pio_writeb(drive, IDEREG_COMMAND, cmd->command); - ob_ide_400ns_delay(drive); -} - -static void -ob_ide_write_registers(struct ide_drive *drive, struct ata_command *cmd) -{ - /* - * we are _always_ polled - */ - ob_ide_pio_writeb(drive, IDEREG_CONTROL, cmd->control | IDECON_NIEN); - - ob_ide_pio_writeb(drive, IDEREG_FEATURE, cmd->feature); - ob_ide_pio_writeb(drive, IDEREG_NSECTOR, cmd->nsector); - ob_ide_pio_writeb(drive, IDEREG_SECTOR, cmd->sector); - ob_ide_pio_writeb(drive, IDEREG_LCYL, cmd->lcyl); - ob_ide_pio_writeb(drive, IDEREG_HCYL, cmd->hcyl); - - if (drive->unit) - cmd->device_head |= IDEHEAD_DEV1; - - ob_ide_pio_writeb(drive, IDEREG_CURRENT, cmd->device_head); - - ob_ide_pio_writeb(drive, IDEREG_COMMAND, cmd->command); - ob_ide_400ns_delay(drive); -} - -/* - * execute command with "pio non data" protocol - */ -#if 0 -static int -ob_ide_pio_non_data(struct ide_drive *drive, struct ata_command *cmd) -{ - if (ob_ide_select_drive(drive)) - return 1; - - ob_ide_write_registers(drive, cmd); - - if (ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL)) - return 1; - - return 0; -} -#endif - -/* - * execute given command with a pio data-in phase. - */ -static int -ob_ide_pio_data_in(struct ide_drive *drive, struct ata_command *cmd) -{ - unsigned char stat; - unsigned int bytes, timeout; - - if (ob_ide_select_drive(drive)) - return 1; - - /* - * ATA must set ready and seek stat, ATAPI need only clear busy - */ - timeout = 0; - do { - stat = ob_ide_pio_readb(drive, IDEREG_STATUS); - - if (drive->type == ide_type_ata) { - /* - * this is BIOS code, don't be too pedantic - */ -#ifdef ATA_PEDANTIC - if ((stat & (BUSY_STAT | READY_STAT | SEEK_STAT)) == - (READY_STAT | SEEK_STAT)) - break; -#else - if ((stat & (BUSY_STAT | READY_STAT)) == READY_STAT) - break; -#endif - } else { - if (!(stat & BUSY_STAT)) - break; - } - ob_ide_400ns_delay(drive); - } while (timeout++ < 1000); - - if (timeout >= 1000) { - ob_ide_error(drive, stat, "drive timed out"); - cmd->stat = stat; - return 1; - } - - ob_ide_write_registers(drive, cmd); - - /* - * now read the data - */ - bytes = cmd->buflen; - do { - unsigned count = cmd->buflen; - - if (count > drive->bs) - count = drive->bs; - - /* delay 100ms for ATAPI? */ - - /* - * wait for BUSY clear - */ - if (ob_ide_wait_stat(drive, 0, BUSY_STAT | ERR_STAT, &stat)) { - ob_ide_error(drive, stat, "timed out waiting for BUSY clear"); - cmd->stat = stat; - break; - } - - /* - * transfer the data - */ - if ((stat & (BUSY_STAT | DRQ_STAT)) == DRQ_STAT) { - ob_ide_pio_insw(drive, IDEREG_DATA, cmd->buffer, count); - cmd->bytes -= count; - cmd->buffer += count; - bytes -= count; - - ob_ide_400ns_delay(drive); - } - - if (stat & (BUSY_STAT | WRERR_STAT | ERR_STAT)) { - cmd->stat = stat; - break; - } - - if (!(stat & DRQ_STAT)) { - cmd->stat = stat; - break; - } - } while (bytes); - - if (bytes) - IDE_DPRINTF("bytes=%d, stat=%x\n", bytes, stat); - - return bytes ? 1 : 0; -} - -/* - * execute ata command with pio packet protocol - */ -static int -ob_ide_pio_packet(struct ide_drive *drive, struct atapi_command *cmd) -{ - unsigned char stat, reason, lcyl, hcyl; - struct ata_command *acmd = &drive->channel->ata_cmd; - unsigned char *buffer; - unsigned int bytes; - - if (ob_ide_select_drive(drive)) - return 1; - - if (cmd->buflen && cmd->data_direction == atapi_ddir_none) - IDE_DPRINTF("non-zero buflen but no data direction\n"); - - memset(acmd, 0, sizeof(*acmd)); - acmd->lcyl = cmd->buflen & 0xff; - acmd->hcyl = (cmd->buflen >> 8) & 0xff; - acmd->command = WIN_PACKET; - ob_ide_write_registers(drive, acmd); - - /* - * BUSY must be set, _or_ DRQ | ERR - */ - stat = ob_ide_pio_readb(drive, IDEREG_ASTATUS); - if ((stat & BUSY_STAT) == 0) { - if (!(stat & (DRQ_STAT | ERR_STAT))) { - ob_ide_error(drive, stat, "bad stat in atapi cmd"); - cmd->stat = stat; - return 1; - } - } - - if (ob_ide_wait_stat(drive, 0, BUSY_STAT | ERR_STAT, &stat)) { - ob_ide_error(drive, stat, "timeout, ATAPI BUSY clear"); - cmd->stat = stat; - return 1; - } - - if ((stat & (BUSY_STAT | DRQ_STAT | ERR_STAT)) != DRQ_STAT) { - /* - * if command isn't request sense, then we have a problem. if - * we are doing a sense, ERR_STAT == CHECK_CONDITION - */ - if (cmd->cdb[0] != ATAPI_REQ_SENSE) { - IDE_DPRINTF("odd, drive didn't want to transfer %x\n", - stat); - return 1; - } - } - - /* - * transfer cdb - */ - ob_ide_pio_outsw(drive, IDEREG_DATA, cmd->cdb,sizeof(cmd->cdb)); - ob_ide_400ns_delay(drive); - - /* - * ok, cdb was sent to drive, now do data transfer (if any) - */ - bytes = cmd->buflen; - buffer = cmd->buffer; - do { - unsigned int bc; - - if (ob_ide_wait_stat(drive, 0, BUSY_STAT | ERR_STAT, &stat)) { - ob_ide_error(drive, stat, "busy not clear after cdb"); - cmd->stat = stat; - break; - } - - /* - * transfer complete! - */ - if ((stat & (BUSY_STAT | DRQ_STAT)) == 0) - break; - - if ((stat & (BUSY_STAT | DRQ_STAT)) != DRQ_STAT) - break; - - reason = ob_ide_pio_readb(drive, IDEREG_NSECTOR); - lcyl = ob_ide_pio_readb(drive, IDEREG_LCYL); - hcyl = ob_ide_pio_readb(drive, IDEREG_HCYL); - - /* - * check if the drive wants to transfer data in the same - * direction as we do... - */ - if ((reason & IREASON_CD) && cmd->data_direction != atapi_ddir_read) { - ob_ide_error(drive, stat, "atapi, bad transfer ddir"); - break; - } - - bc = (hcyl << 8) | lcyl; - if (!bc) - break; - - if (bc > bytes) - bc = bytes; - - if (cmd->data_direction == atapi_ddir_read) - ob_ide_pio_insw(drive, IDEREG_DATA, buffer, bc); - else - ob_ide_pio_outsw(drive, IDEREG_DATA, buffer, bc); - - bytes -= bc; - buffer += bc; - - ob_ide_400ns_delay(drive); - } while (bytes); - - if (cmd->data_direction != atapi_ddir_none) - (void) ob_ide_wait_stat(drive, 0, BUSY_STAT, &stat); - - if (bytes) - IDE_DPRINTF("cdb failed, bytes=%d, stat=%x\n", bytes, stat); - - return (stat & ERR_STAT) || bytes; -} - -/* - * execute a packet command, with retries if appropriate - */ -static int -ob_ide_atapi_packet(struct ide_drive *drive, struct atapi_command *cmd) -{ - int retries = 5, ret; - - if (drive->type != ide_type_atapi) - return 1; - if (cmd->buflen > 0xffff) - return 1; - - /* - * retry loop - */ - do { - ret = ob_ide_pio_packet(drive, cmd); - if (!ret) - break; - - /* - * request sense failed, bummer - */ - if (cmd->cdb[0] == ATAPI_REQ_SENSE) - break; - - if (ob_ide_atapi_request_sense(drive)) - break; - - /* - * we know sense is valid. retry if the drive isn't ready, - * otherwise don't bother. - */ - if (cmd->sense.sense_key != ATAPI_SENSE_NOT_READY) - break; - /* - * ... except 'medium not present' - */ - if (cmd->sense.asc == 0x3a) - break; - - udelay(1000000); - } while (retries--); - - if (ret) - ob_ide_error(drive, 0, "atapi command"); - - return ret; -} - -static int -ob_ide_atapi_request_sense(struct ide_drive *drive) -{ - struct atapi_command *cmd = &drive->channel->atapi_cmd; - unsigned char old_cdb; - - /* - * save old cdb for debug error - */ - old_cdb = cmd->cdb[0]; - - memset(cmd, 0, sizeof(*cmd)); - cmd->cdb[0] = ATAPI_REQ_SENSE; - cmd->cdb[4] = 18; - cmd->buffer = (unsigned char *) &cmd->sense; - cmd->buflen = 18; - cmd->data_direction = atapi_ddir_read; - cmd->old_cdb = old_cdb; - - if (ob_ide_atapi_packet(drive, cmd)) - return 1; - - cmd->sense_valid = 1; - return 0; -} - -/* - * make sure drive is ready and media loaded - */ -static int -ob_ide_atapi_drive_ready(struct ide_drive *drive) -{ - struct atapi_command *cmd = &drive->channel->atapi_cmd; - struct atapi_capacity cap; - - IDE_DPRINTF("ob_ide_atapi_drive_ready\n"); - - /* - * Test Unit Ready is like a ping - */ - memset(cmd, 0, sizeof(*cmd)); - cmd->cdb[0] = ATAPI_TUR; - - if (ob_ide_atapi_packet(drive, cmd)) { - IDE_DPRINTF("%d: TUR failed\n", drive->nr); - return 1; - } - - /* - * don't force load of tray (bit 2 in byte 4 of cdb), it's - * annoying and we don't want to deal with errors from drives - * that cannot do it - */ - memset(cmd, 0, sizeof(*cmd)); - cmd->cdb[0] = ATAPI_START_STOP_UNIT; - cmd->cdb[4] = 0x01; - - if (ob_ide_atapi_packet(drive, cmd)) { - IDE_DPRINTF("%d: START_STOP unit failed\n", drive->nr); - return 1; - } - - /* - * finally, get capacity and block size - */ - memset(cmd, 0, sizeof(*cmd)); - memset(&cap, 0, sizeof(cap)); - - cmd->cdb[0] = ATAPI_READ_CAPACITY; - cmd->buffer = (unsigned char *) ∩ - cmd->buflen = sizeof(cap); - cmd->data_direction = atapi_ddir_read; - - if (ob_ide_atapi_packet(drive, cmd)) { - drive->sectors = 0x1fffff; - drive->bs = 2048; - return 1; - } - - drive->sectors = __be32_to_cpu(cap.lba) + 1; - drive->bs = __be32_to_cpu(cap.block_size); - return 0; -} - -/* - * read from an atapi device, using READ_10 - */ -static int -ob_ide_read_atapi(struct ide_drive *drive, unsigned long long block, - unsigned char *buf, unsigned int sectors) -{ - struct atapi_command *cmd = &drive->channel->atapi_cmd; - - if (ob_ide_atapi_drive_ready(drive)) - return 1; - - memset(cmd, 0, sizeof(*cmd)); - - /* - * READ_10 should work on generally any atapi device - */ - cmd->cdb[0] = ATAPI_READ_10; - cmd->cdb[2] = (block >> 24) & 0xff; - cmd->cdb[3] = (block >> 16) & 0xff; - cmd->cdb[4] = (block >> 8) & 0xff; - cmd->cdb[5] = block & 0xff; - cmd->cdb[7] = (sectors >> 8) & 0xff; - cmd->cdb[8] = sectors & 0xff; - - cmd->buffer = buf; - cmd->buflen = sectors * 2048; - cmd->data_direction = atapi_ddir_read; - - return ob_ide_atapi_packet(drive, cmd); -} - -static int -ob_ide_read_ata_chs(struct ide_drive *drive, unsigned long long block, - unsigned char *buf, unsigned int sectors) -{ - struct ata_command *cmd = &drive->channel->ata_cmd; - unsigned int track = (block / drive->sect); - unsigned int sect = (block % drive->sect) + 1; - unsigned int head = (track % drive->head); - unsigned int cyl = (track / drive->head); - - /* - * fill in chs command to read from disk at given location - */ - cmd->buffer = buf; - cmd->buflen = sectors * 512; - - cmd->nsector = sectors & 0xff; - cmd->sector = sect; - cmd->lcyl = cyl; - cmd->hcyl = cyl >> 8; - cmd->device_head = head; - - cmd->command = WIN_READ; - - return ob_ide_pio_data_in(drive, cmd); -} - -static int -ob_ide_read_ata_lba28(struct ide_drive *drive, unsigned long long block, - unsigned char *buf, unsigned int sectors) -{ - struct ata_command *cmd = &drive->channel->ata_cmd; - - memset(cmd, 0, sizeof(*cmd)); - - /* - * fill in 28-bit lba command to read from disk at given location - */ - cmd->buffer = buf; - cmd->buflen = sectors * 512; - - cmd->nsector = sectors; - cmd->sector = block; - cmd->lcyl = block >>= 8; - cmd->hcyl = block >>= 8; - cmd->device_head = ((block >> 8) & 0x0f); - cmd->device_head |= (1 << 6); - - cmd->command = WIN_READ; - - return ob_ide_pio_data_in(drive, cmd); -} - -static int -ob_ide_read_ata_lba48(struct ide_drive *drive, unsigned long long block, - unsigned char *buf, unsigned int sectors) -{ - struct ata_command *cmd = &drive->channel->ata_cmd; - - memset(cmd, 0, sizeof(*cmd)); - - cmd->buffer = buf; - cmd->buflen = sectors * 512; - - /* - * we are using tasklet addressing here - */ - cmd->task[2] = sectors; - cmd->task[3] = sectors >> 8; - cmd->task[4] = block; - cmd->task[5] = block >> 8; - cmd->task[6] = block >> 16; - cmd->task[7] = block >> 24; - cmd->task[8] = (u64) block >> 32; - cmd->task[9] = (u64) block >> 40; - - cmd->command = WIN_READ_EXT; - - ob_ide_write_tasklet(drive, cmd); - - return ob_ide_pio_data_in(drive, cmd); -} -/* - * read 'sectors' sectors from ata device - */ -static int -ob_ide_read_ata(struct ide_drive *drive, unsigned long long block, - unsigned char *buf, unsigned int sectors) -{ - unsigned long long end_block = block + sectors; - const int need_lba48 = (end_block > (1ULL << 28)) || (sectors > 255); - - if (end_block > drive->sectors) - return 1; - if (need_lba48 && drive->addressing != ide_lba48) - return 1; - - /* - * use lba48 if we have to, otherwise use the faster lba28 - */ - if (need_lba48) - return ob_ide_read_ata_lba48(drive, block, buf, sectors); - else if (drive->addressing != ide_chs) - return ob_ide_read_ata_lba28(drive, block, buf, sectors); - - return ob_ide_read_ata_chs(drive, block, buf, sectors); -} - -static int -ob_ide_read_sectors(struct ide_drive *drive, unsigned long long block, - unsigned char *buf, unsigned int sectors) -{ - if (!sectors) - return 1; - if (block + sectors > drive->sectors) - return 1; - - IDE_DPRINTF("ob_ide_read_sectors: block=%lu sectors=%u\n", - (unsigned long) block, sectors); - - if (drive->type == ide_type_ata) - return ob_ide_read_ata(drive, block, buf, sectors); - else - return ob_ide_read_atapi(drive, block, buf, sectors); -} - -/* - * byte swap the string if necessay, and strip leading/trailing blanks - */ -static void -ob_ide_fixup_string(unsigned char *s, unsigned int len) -{ - unsigned char *p = s, *end = &s[len & ~1]; - - /* - * if big endian arch, byte swap the string - */ -#ifdef CONFIG_BIG_ENDIAN - for (p = end ; p != s;) { - unsigned short *pp = (unsigned short *) (p -= 2); - *pp = __le16_to_cpu(*pp); - } -#endif - - while (s != end && *s == ' ') - ++s; - while (s != end && *s) - if (*s++ != ' ' || (s != end && *s && *s != ' ')) - *p++ = *(s-1); - while (p != end) - *p++ = '\0'; -} - -/* - * it's big endian, we need to swap (if on little endian) the items we use - */ -static int -ob_ide_fixup_id(struct hd_driveid *id) -{ - ob_ide_fixup_string(id->model, 40); - id->config = __le16_to_cpu(id->config); - id->lba_capacity = __le32_to_cpu(id->lba_capacity); - id->cyls = __le16_to_cpu(id->cyls); - id->heads = __le16_to_cpu(id->heads); - id->sectors = __le16_to_cpu(id->sectors); - id->command_set_2 = __le16_to_cpu(id->command_set_2); - id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2); - - return 0; -} - -static int -ob_ide_identify_drive(struct ide_drive *drive) -{ - struct ata_command *cmd = &drive->channel->ata_cmd; - struct hd_driveid id; - - memset(cmd, 0, sizeof(*cmd)); - cmd->buffer = (unsigned char *) &id; - cmd->buflen = 512; - - if (drive->type == ide_type_ata) - cmd->command = WIN_IDENTIFY; - else if (drive->type == ide_type_atapi) - cmd->command = WIN_IDENTIFY_PACKET; - else { - IDE_DPRINTF("%s: called with bad device type %d\n", - __FUNCTION__, drive->type); - return 1; - } - - if (ob_ide_pio_data_in(drive, cmd)) - return 1; - - ob_ide_fixup_id(&id); - - if (drive->type == ide_type_atapi) { - drive->media = (id.config >> 8) & 0x1f; - drive->sectors = 0x7fffffff; - drive->bs = 2048; - drive->max_sectors = 31; - } else { - drive->media = ide_media_disk; - drive->sectors = id.lba_capacity; - drive->bs = 512; - drive->max_sectors = 255; - -#ifdef CONFIG_IDE_LBA48 - if ((id.command_set_2 & 0x0400) && (id.cfs_enable_2 & 0x0400)) { - drive->addressing = ide_lba48; - drive->max_sectors = 65535; - } else -#endif - if (id.capability & 2) - drive->addressing = ide_lba28; - else { - drive->addressing = ide_chs; - } - - /* only set these in chs mode? */ - drive->cyl = id.cyls; - drive->head = id.heads; - drive->sect = id.sectors; - } - - strncpy(drive->model, (char*)id.model, sizeof(id.model)); - drive->model[40] = '\0'; - return 0; -} - -/* - * identify type of devices on channel. must have already been probed. - */ -static void -ob_ide_identify_drives(struct ide_channel *chan) -{ - struct ide_drive *drive; - int i; - - for (i = 0; i < 2; i++) { - drive = &chan->drives[i]; - - if (!drive->present) - continue; - - ob_ide_identify_drive(drive); - } -} - -/* - * software reset (ATA-4, section 8.3) - */ -static void -ob_ide_software_reset(struct ide_drive *drive) -{ - struct ide_channel *chan = drive->channel; - - ob_ide_pio_writeb(drive, IDEREG_CONTROL, IDECON_NIEN | IDECON_SRST); - ob_ide_400ns_delay(drive); - ob_ide_pio_writeb(drive, IDEREG_CONTROL, IDECON_NIEN); - ob_ide_400ns_delay(drive); - - /* - * if master is present, wait for BUSY clear - */ - if (chan->drives[0].present) - ob_ide_wait_stat(drive, 0, BUSY_STAT, NULL); - - /* - * if slave is present, wait until it allows register access - */ - if (chan->drives[1].present) { - unsigned char sectorn, sectorc; - int timeout = 1000; - - do { - /* - * select it - */ - ob_ide_pio_writeb(drive, IDEREG_CURRENT, IDEHEAD_DEV1); - ob_ide_400ns_delay(drive); - - sectorn = ob_ide_pio_readb(drive, IDEREG_SECTOR); - sectorc = ob_ide_pio_readb(drive, IDEREG_NSECTOR); - - if (sectorc == 0x01 && sectorn == 0x01) - break; - - } while (--timeout); - } - - /* - * reset done, reselect original device - */ - drive->channel->selected = -1; - ob_ide_select_drive(drive); -} - -/* - * this serves as both a device check, and also to verify that the drives - * we initially "found" are really there - */ -static void -ob_ide_device_type_check(struct ide_drive *drive) -{ - unsigned char sc, sn, cl, ch, st; - - if (ob_ide_select_drive(drive)) - return; - - sc = ob_ide_pio_readb(drive, IDEREG_NSECTOR); - sn = ob_ide_pio_readb(drive, IDEREG_SECTOR); - - if (sc == 0x01 && sn == 0x01) { - /* - * read device signature - */ - cl = ob_ide_pio_readb(drive, IDEREG_LCYL); - ch = ob_ide_pio_readb(drive, IDEREG_HCYL); - st = ob_ide_pio_readb(drive, IDEREG_STATUS); - if (cl == 0x14 && ch == 0xeb) - drive->type = ide_type_atapi; - else if (cl == 0x00 && ch == 0x00 && st != 0x00) - drive->type = ide_type_ata; - else - drive->present = 0; - } else - drive->present = 0; -} - -/* - * pure magic - */ -static void -ob_ide_device_check(struct ide_drive *drive) -{ - unsigned char sc, sn; - - /* - * non-existing io port should return 0xff, don't probe this - * channel at all then - */ - if (ob_ide_pio_readb(drive, IDEREG_STATUS) == 0xff) { - drive->channel->present = 0; - return; - } - - if (ob_ide_select_drive(drive)) - return; - - ob_ide_pio_writeb(drive, IDEREG_NSECTOR, 0x55); - ob_ide_pio_writeb(drive, IDEREG_SECTOR, 0xaa); - ob_ide_pio_writeb(drive, IDEREG_NSECTOR, 0xaa); - ob_ide_pio_writeb(drive, IDEREG_SECTOR, 0x55); - ob_ide_pio_writeb(drive, IDEREG_NSECTOR, 0x55); - ob_ide_pio_writeb(drive, IDEREG_SECTOR, 0xaa); - - sc = ob_ide_pio_readb(drive, IDEREG_NSECTOR); - sn = ob_ide_pio_readb(drive, IDEREG_SECTOR); - - /* - * we _think_ the device is there, we will make sure later - */ - if (sc == 0x55 && sn == 0xaa) { - drive->present = 1; - drive->type = ide_type_unknown; - } -} - -/* - * probe the legacy ide ports and find attached devices. - */ -static void -ob_ide_probe(struct ide_channel *chan) -{ - struct ide_drive *drive; - int i; - - for (i = 0; i < 2; i++) { - drive = &chan->drives[i]; - - ob_ide_device_check(drive); - - /* - * no point in continuing - */ - if (!chan->present) - break; - - if (!drive->present) - continue; - - /* - * select and reset device - */ - if (ob_ide_select_drive(drive)) - continue; - - ob_ide_software_reset(drive); - - ob_ide_device_type_check(drive); - } -} - -/* - * The following functions are interfacing with OpenBIOS. They - * are device node methods. Thus they have to do proper stack handling. - * - */ - -/* - * 255 sectors for ata lba28, 65535 for lba48, and 31 sectors for atapi - */ -static void -ob_ide_max_transfer(int *idx) -{ - struct ide_drive *drive = *(struct ide_drive **)idx; - - IDE_DPRINTF("max_transfer %x\n", drive->max_sectors * drive->bs); - - PUSH(drive->max_sectors * drive->bs); -} - -static void -ob_ide_read_blocks(int *idx) -{ - cell n = POP(), cnt=n; - ucell blk = POP(); - unsigned char *dest = (unsigned char *)cell2pointer(POP()); - struct ide_drive *drive = *(struct ide_drive **)idx; - - IDE_DPRINTF("ob_ide_read_blocks %lx block=%ld n=%ld\n", - (unsigned long)dest, (unsigned long)blk, (long)n); - - while (n) { - int len = n; - if (len > drive->max_sectors) - len = drive->max_sectors; - - if (ob_ide_read_sectors(drive, blk, dest, len)) { - IDE_DPRINTF("ob_ide_read_blocks: error\n"); - RET(0); - } - - dest += len * drive->bs; - n -= len; - blk += len; - } - - PUSH(cnt); -} - -static void -ob_ide_block_size(int *idx) -{ - struct ide_drive *drive = *(struct ide_drive **)idx; - - IDE_DPRINTF("ob_ide_block_size: block size %x\n", drive->bs); - - PUSH(drive->bs); -} - -static void -ob_ide_initialize(int *idx) -{ - int props[3]; - phandle_t ph=get_cur_dev(); - - push_str("block"); - fword("device-type"); - - // Set dummy reg properties - - set_int_property(ph, "#address-cells", 1); - set_int_property(ph, "#size-cells", 0); - - props[0] = __cpu_to_be32(0); props[1] = __cpu_to_be32(0); props[2] = __cpu_to_be32(0); - set_property(ph, "reg", (char *)&props, 3*sizeof(int)); - - fword("is-deblocker"); -} - -static void -ob_ide_open(int *idx) -{ - int ret=1; - phandle_t ph; - struct ide_drive *drive; - struct ide_channel *chan; - int unit; - - fword("my-unit"); - unit = POP(); - - fword("my-parent"); - fword("ihandle>phandle"); - ph=(phandle_t)POP(); - - chan = ide_seek_channel(ph); - drive = &chan->drives[unit]; - *(struct ide_drive **)idx = drive; - - IDE_DPRINTF("opening channel %d unit %d\n", idx[1], idx[0]); - dump_drive(drive); - - if (drive->type != ide_type_ata) - ret= !ob_ide_atapi_drive_ready(drive); - - selfword("open-deblocker"); - - /* interpose disk-label */ - ph = find_dev("/packages/disk-label"); - fword("my-args"); - PUSH_ph( ph ); - fword("interpose"); - - RET ( -ret ); -} - -static void -ob_ide_close(struct ide_drive *drive) -{ - selfword("close-deblocker"); -} - -NODE_METHODS(ob_ide) = { - { NULL, ob_ide_initialize }, - { "open", ob_ide_open }, - { "close", ob_ide_close }, - { "read-blocks", ob_ide_read_blocks }, - { "block-size", ob_ide_block_size }, - { "max-transfer", ob_ide_max_transfer }, -}; - -static void -ob_ide_ctrl_initialize(int *idx) -{ - phandle_t ph=get_cur_dev(); - - /* set device type */ - push_str(DEV_TYPE); - fword("device-type"); - - set_int_property(ph, "#address-cells", 1); - set_int_property(ph, "#size-cells", 0); -} - -static void -ob_ide_ctrl_decodeunit(int *idx) -{ - fword("parse-hex"); -} - -NODE_METHODS(ob_ide_ctrl) = { - { NULL, ob_ide_ctrl_initialize }, - { "decode-unit", ob_ide_ctrl_decodeunit }, -}; - -static void set_cd_alias(const char *path) -{ - phandle_t aliases; - - aliases = find_dev("/aliases"); - - if (get_property(aliases, "cd", NULL)) - return; - - set_property(aliases, "cd", path, strlen(path) + 1); - set_property(aliases, "cdrom", path, strlen(path) + 1); -} - -static void set_hd_alias(const char *path) -{ - phandle_t aliases; - - aliases = find_dev("/aliases"); - - if (get_property(aliases, "hd", NULL)) - return; - - set_property(aliases, "hd", path, strlen(path) + 1); - set_property(aliases, "disk", path, strlen(path) + 1); -} - -static void set_ide_alias(const char *path) -{ - phandle_t aliases; - static int ide_counter = 0; - char idestr[8]; - - aliases = find_dev("/aliases"); - - snprintf(idestr, sizeof(idestr), "ide%d", ide_counter++); - set_property(aliases, idestr, path, strlen(path) + 1); -} - -int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0, - uint32_t io_port1, uint32_t ctl_port1) -{ - int i, j; - char nodebuff[128]; - phandle_t dnode; - struct ide_channel *chan; - int io_ports[IDE_MAX_CHANNELS]; - int ctl_ports[IDE_MAX_CHANNELS]; - u32 props[6]; - - io_ports[0] = io_port0; - ctl_ports[0] = ctl_port0; - io_ports[1] = io_port1; - ctl_ports[1] = ctl_port1; - - for (i = 0; i < IDE_NUM_CHANNELS; i++, current_channel++) { - - chan = malloc(sizeof(struct ide_channel)); - - chan->mmio = 0; - - for (j = 0; j < 8; j++) - chan->io_regs[j] = io_ports[i] + j; - - chan->io_regs[8] = ctl_ports[i]; - chan->io_regs[9] = ctl_ports[i] + 1; - - chan->obide_inb = ob_ide_inb; - chan->obide_insw = ob_ide_insw; - chan->obide_outb = ob_ide_outb; - chan->obide_outsw = ob_ide_outsw; - - chan->selected = -1; - - /* - * assume it's there, if not io port dead check will clear - */ - chan->present = 1; - - for (j = 0; j < 2; j++) { - chan->drives[j].present = 0; - chan->drives[j].unit = j; - chan->drives[j].channel = chan; - /* init with a decent value */ - chan->drives[j].bs = 512; - - chan->drives[j].nr = i * 2 + j; - } - - ide_add_channel(chan); - - ob_ide_probe(chan); - - if (!chan->present) - continue; - - ob_ide_identify_drives(chan); - - snprintf(nodebuff, sizeof(nodebuff), "%s/" DEV_NAME, path, - current_channel); - REGISTER_NAMED_NODE_PHANDLE(ob_ide_ctrl, nodebuff, dnode); - - chan->ph = dnode; - -#if !defined(CONFIG_PPC) && !defined(CONFIG_SPARC64) - props[0]=14; props[1]=0; - set_property(dnode, "interrupts", - (char *)&props, 2*sizeof(props[0])); -#endif - - props[0] = __cpu_to_be32(chan->io_regs[0]); - props[1] = __cpu_to_be32(1); props[2] = __cpu_to_be32(8); - props[3] = __cpu_to_be32(chan->io_regs[8]); - props[4] = __cpu_to_be32(1); props[5] = __cpu_to_be32(2); - set_property(dnode, "reg", (char *)&props, 6*sizeof(props[0])); - - IDE_DPRINTF(DEV_NAME": [io ports 0x%x-0x%x,0x%x]\n", - current_channel, chan->io_regs[0], - chan->io_regs[0] + 7, chan->io_regs[8]); - - for (j = 0; j < 2; j++) { - struct ide_drive *drive = &chan->drives[j]; - const char *media = "UNKNOWN"; - - if (!drive->present) - continue; - - IDE_DPRINTF(" drive%d [ATA%s ", j, - drive->type == ide_type_atapi ? "PI" : ""); - switch (drive->media) { - case ide_media_floppy: - media = "floppy"; - break; - case ide_media_cdrom: - media = "cdrom"; - break; - case ide_media_optical: - media = "mo"; - break; - case ide_media_disk: - media = "disk"; - break; - } - IDE_DPRINTF("%s]: %s\n", media, drive->model); - snprintf(nodebuff, sizeof(nodebuff), "%s/%s", - get_path_from_ph(dnode), media); - REGISTER_NAMED_NODE_PHANDLE(ob_ide, nodebuff, dnode); - set_int_property(dnode, "reg", j); - - /* create aliases */ - - set_ide_alias(nodebuff); - if (drive->media == ide_media_cdrom) - set_cd_alias(nodebuff); - if (drive->media == ide_media_disk) - set_hd_alias(nodebuff); - } - } - - return 0; -} - -void ob_ide_quiesce(void) -{ - struct ide_channel *channel; - int i; - - channel = channels; - while (channel) { - for (i = 0; i < 2; i++) { - struct ide_drive *drive = &channel->drives[i]; - - if (!drive->present) - continue; - - ob_ide_select_drive(drive); - ob_ide_software_reset(drive); - ob_ide_device_type_check(drive); - } - - channel = channel->next; - } -} - -#if defined(CONFIG_DRIVER_MACIO) -static unsigned char -macio_ide_inb(struct ide_channel *chan, unsigned int port) -{ - return in_8((unsigned char*)(chan->mmio + (port << 4))); -} - -static void -macio_ide_outb(struct ide_channel *chan, unsigned char data, unsigned int port) -{ - out_8((unsigned char*)(chan->mmio + (port << 4)), data); -} - -static void -macio_ide_insw(struct ide_channel *chan, - unsigned int port, unsigned char *addr, unsigned int count) -{ - _insw((uint16_t*)(chan->mmio + (port << 4)), addr, count); -} - -static void -macio_ide_outsw(struct ide_channel *chan, - unsigned int port, unsigned char *addr, unsigned int count) -{ - _outsw((uint16_t*)(chan->mmio + (port << 4)), addr, count); -} - -#define MACIO_IDE_OFFSET 0x00020000 -#define MACIO_IDE_SIZE 0x00001000 - -int macio_ide_init(const char *path, uint32_t addr, int nb_channels) -{ - int i, j; - char nodebuff[128]; - phandle_t dnode; - u32 props[8]; - struct ide_channel *chan; - - /* IDE ports on Macs are numbered from 3. - * Also see comments in pci.c:ob_pci_host_set_interrupt_map() */ - current_channel = 3; - - for (i = 0; i < nb_channels; i++) { - - chan = malloc(sizeof(struct ide_channel)); - - chan->mmio = addr + MACIO_IDE_OFFSET + i * MACIO_IDE_SIZE; - - chan->obide_inb = macio_ide_inb; - chan->obide_insw = macio_ide_insw; - chan->obide_outb = macio_ide_outb; - chan->obide_outsw = macio_ide_outsw; - - chan->selected = -1; - - /* - * assume it's there, if not io port dead check will clear - */ - chan->present = 1; - - for (j = 0; j < 2; j++) { - chan->drives[j].present = 0; - chan->drives[j].unit = j; - chan->drives[j].channel = chan; - /* init with a decent value */ - chan->drives[j].bs = 512; - - chan->drives[j].nr = i * 2 + j; - } - - ob_ide_probe(chan); - - if (!chan->present) { - free(chan); - continue; - } - - ide_add_channel(chan); - - ob_ide_identify_drives(chan); - - snprintf(nodebuff, sizeof(nodebuff), "%s/" DEV_NAME, path, - current_channel); - REGISTER_NAMED_NODE_PHANDLE(ob_ide_ctrl, nodebuff, dnode); - - chan->ph = dnode; - - set_property(dnode, "compatible", (is_oldworld() ? - "heathrow-ata" : "keylargo-ata"), 13); - - set_property(dnode, "model", ((current_channel == 3) ? - "ata-3" : "ata-4"), strlen("ata-*") + 1); - - set_property(dnode, "AAPL,connector", "ata", - strlen("ata") + 1); - - props[0] = 0x00000526; - props[1] = 0x00000085; - props[2] = 0x00000025; - props[3] = 0x00000025; - props[4] = 0x00000025; - props[5] = 0x00000000; - props[6] = 0x00000000; - props[7] = 0x00000000; - set_property(dnode, "AAPL,pio-timing", - (char *)&props, 8*sizeof(props[0])); - - /* The first interrupt entry is the ide interrupt, the second - the dbdma interrupt */ - switch (i) { - case 0: - props[0] = 0x0000000d; - props[2] = 0x00000002; - break; - case 1: - props[0] = 0x0000000e; - props[2] = 0x00000003; - break; - case 2: - props[0] = 0x0000000f; - props[2] = 0x00000004; - break; - default: - props[0] = 0x00000000; - props[2] = 0x00000000; - break; - } - props[1] = 0x00000000; /* XXX level triggered on real hw */ - props[3] = 0x00000000; - NEWWORLD(set_property(dnode, "interrupts", - (char *)&props, 4*sizeof(props[0]))); - NEWWORLD(set_int_property(dnode, "#interrupt-cells", 2)); - - props[1] = props[2]; - OLDWORLD(set_property(dnode, "AAPL,interrupts", - (char *)&props, 2*sizeof(props[0]))); - - props[0] = MACIO_IDE_OFFSET + i * MACIO_IDE_SIZE; - props[1] = MACIO_IDE_SIZE; - props[2] = 0x00008b00 + i * 0x0200; - props[3] = 0x0200; - set_property(dnode, "reg", (char *)&props, 4*sizeof(props[0])); - - props[0] = addr + MACIO_IDE_OFFSET + i * MACIO_IDE_SIZE; - props[1] = addr + 0x00008b00 + i * 0x0200; - OLDWORLD(set_property(dnode, "AAPL,address", - (char *)&props, 2*sizeof(props[0]))); - - props[0] = i; - set_property(dnode, "AAPL,bus-id", (char*)props, - 1 * sizeof(props[0])); - IDE_DPRINTF(DEV_NAME": [io ports 0x%lx]\n", - current_channel, chan->mmio); - - for (j = 0; j < 2; j++) { - struct ide_drive *drive = &chan->drives[j]; - const char *media = "UNKNOWN"; - - if (!drive->present) - continue; - - IDE_DPRINTF(" drive%d [ATA%s ", j, - drive->type == ide_type_atapi ? "PI" : ""); - switch (drive->media) { - case ide_media_floppy: - media = "floppy"; - break; - case ide_media_cdrom: - media = "cdrom"; - break; - case ide_media_optical: - media = "mo"; - break; - case ide_media_disk: - media = "disk"; - break; - } - IDE_DPRINTF("%s]: %s\n", media, drive->model); - snprintf(nodebuff, sizeof(nodebuff), "%s/%s", - get_path_from_ph(dnode), media); - REGISTER_NAMED_NODE_PHANDLE(ob_ide, nodebuff, dnode); - set_int_property(dnode, "reg", j); - - /* create aliases */ - - set_ide_alias(nodebuff); - if (drive->media == ide_media_cdrom) - set_cd_alias(nodebuff); - if (drive->media == ide_media_disk) - set_hd_alias(nodebuff); - } - } - - return 0; -} -#endif /* CONFIG_DRIVER_MACIO */ diff --git a/qemu/roms/openbios/drivers/ide.h b/qemu/roms/openbios/drivers/ide.h deleted file mode 100644 index 8983c8ecf..000000000 --- a/qemu/roms/openbios/drivers/ide.h +++ /dev/null @@ -1,213 +0,0 @@ -#ifndef IDE_H -#define IDE_H - -#include "hdreg.h" - -/* - * legacy ide ports - */ -#define IDEREG_DATA 0x00 -#define IDEREG_ERROR 0x01 -#define IDEREG_FEATURE IDEREG_ERROR -#define IDEREG_NSECTOR 0x02 -#define IDEREG_SECTOR 0x03 -#define IDEREG_LCYL 0x04 -#define IDEREG_HCYL 0x05 -#define IDEREG_CURRENT 0x06 -#define IDEREG_STATUS 0x07 -#define IDEREG_COMMAND IDEREG_STATUS -#define IDEREG_CONTROL 0x08 -#define IDEREG_ASTATUS IDEREG_CONTROL - -/* - * device control bits - */ -#define IDECON_NIEN 0x02 -#define IDECON_SRST 0x04 - -/* - * device head bits - */ -#define IDEHEAD_LBA 0x40 -#define IDEHEAD_DEV0 0x00 -#define IDEHEAD_DEV1 0x10 - -/* - * status bytes - */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 -#define SEEK_STAT 0x10 -#define WRERR_STAT 0x20 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -#define IREASON_CD 0x01 -#define IREASON_IO 0x02 - -/* - * ATA opcodes - */ -#define WIN_READ 0x20 -#define WIN_READ_EXT 0x24 -#define WIN_IDENTIFY 0xEC -#define WIN_PACKET 0xA0 -#define WIN_IDENTIFY_PACKET 0xA1 - -/* - * ATAPI opcodes - */ -#define ATAPI_TUR 0x00 -#define ATAPI_READ_10 0x28 -#define ATAPI_REQ_SENSE 0x03 -#define ATAPI_START_STOP_UNIT 0x1b -#define ATAPI_READ_CAPACITY 0x25 - -/* - * atapi sense keys - */ -#define ATAPI_SENSE_NOT_READY 0x02 - -/* - * supported device types - */ -enum { - ide_type_unknown, - ide_type_ata, - ide_type_atapi, -}; - -enum { - ide_media_floppy = 0x00, - ide_media_cdrom = 0x05, - ide_media_optical = 0x07, - ide_media_disk = 0x20, -}; - -/* - * drive addressing - */ -enum { - ide_chs = 1, - ide_lba28, - ide_lba48, -}; - -/* - * simple ata command that works for everything (except 48-bit lba commands) - */ -struct ata_command { - unsigned char *buffer; - unsigned int buflen; - - /* - * data register - */ - unsigned char data; - unsigned char feature; - unsigned char nsector; - unsigned char sector; - unsigned char lcyl; - unsigned char hcyl; - unsigned char device_head; - unsigned char command; - unsigned char control; - - /* - * or tasklet, just for lba48 for now (above could be scrapped) - */ - unsigned char task[10]; - - /* - * output - */ - unsigned char stat; - unsigned int bytes; -}; - -struct atapi_command { - unsigned char cdb[12]; - unsigned char *buffer; - unsigned int buflen; - unsigned char data_direction; - - unsigned char stat; - unsigned char sense_valid; - struct request_sense sense; - unsigned char old_cdb; -}; - -struct ide_channel; - -struct ide_drive { - char unit; /* 0: master, 1: slave */ - char present; /* there or not */ - char type; /* ata or atapi */ - char media; /* disk, cdrom, etc */ - char addressing; /* chs/lba28/lba48 */ - - char model[41]; /* name */ - int nr; - - unsigned long sectors; - - unsigned int max_sectors; - - /* - * for legacy chs crap - */ - unsigned int cyl; - unsigned int head; - unsigned int sect; - - unsigned int bs; /* block size */ - - struct ide_channel *channel; -}; - -struct ide_channel { - - phandle_t ph; - struct ide_channel *next; - - /* - * either mmio or io_regs is set to indicate mmio or not - */ - unsigned long mmio; - int io_regs[10]; - - /* - * can be set to a mmio hook, default it legacy outb/inb - */ - void (*obide_outb)(struct ide_channel *chan, - unsigned char addr, unsigned int port); - unsigned char (*obide_inb)(struct ide_channel *chan, - unsigned int port); - void (*obide_insw)(struct ide_channel *chan, - unsigned int port, unsigned char *addr, - unsigned int count); - void (*obide_outsw)(struct ide_channel *chan, - unsigned int port, unsigned char *addr, - unsigned int count); - - struct ide_drive drives[2]; - char selected; - char present; - - /* - * only one can be busy per channel - */ - struct ata_command ata_cmd; - struct atapi_command atapi_cmd; - -}; - -enum { - atapi_ddir_none, - atapi_ddir_read, - atapi_ddir_write, -}; - -static int ob_ide_atapi_request_sense(struct ide_drive *drive); - -#endif diff --git a/qemu/roms/openbios/drivers/iommu.c b/qemu/roms/openbios/drivers/iommu.c deleted file mode 100644 index cd9a64bb6..000000000 --- a/qemu/roms/openbios/drivers/iommu.c +++ /dev/null @@ -1,207 +0,0 @@ -/** - ** Proll (PROM replacement) - ** iommu.c: Functions for DVMA management. - ** Copyright 1999 Pete Zaitcev - ** This code is licensed under GNU General Public License. - **/ -#include "config.h" -#include "libopenbios/bindings.h" -#include "libopenbios/ofmem.h" -#include "drivers/drivers.h" -#include "iommu.h" -#include "arch/sparc32/ofmem_sparc32.h" - -#ifdef CONFIG_DEBUG_IOMMU -#define DPRINTF(fmt, args...) \ - do { printk(fmt , ##args); } while (0) -#else -#define DPRINTF(fmt, args...) -#endif - -/* - * IOMMU parameters - */ -struct iommu { - struct iommu_regs *regs; - unsigned int *page_table; - unsigned long plow; /* Base bus address */ -}; - -static struct iommu ciommu; - -static void -iommu_invalidate(struct iommu_regs *iregs) -{ - iregs->tlbflush = 0; -} - -/* - * XXX This is a problematic interface. We alloc _memory_ which is uncached. - * So if we ever reuse allocations somebody is going to get uncached pages. - * Returned address is always aligned by page. - * BTW, we were not going to give away anonymous storage, were we not? - */ -void * -dvma_alloc(int size, unsigned int *pphys) -{ - void *va; - unsigned int pa, ba; - unsigned int npages; - unsigned int mva, mpa; - unsigned int i; - unsigned int *iopte; - struct iommu *t = &ciommu; - int ret; - - npages = (size + (PAGE_SIZE-1)) / PAGE_SIZE; - ret = ofmem_posix_memalign(&va, npages * PAGE_SIZE, PAGE_SIZE); - if (ret != 0) - return NULL; - - ba = (unsigned int)mem_alloc(&cdvmem, npages * PAGE_SIZE, PAGE_SIZE); - if (ba == 0) - return NULL; - - pa = (unsigned int)va2pa((unsigned long)va); - - /* - * Change page attributes in MMU to uncached. - */ - mva = (unsigned int) va; - mpa = (unsigned int) pa; - ofmem_arch_map_pages(mpa, mva, npages * PAGE_SIZE, ofmem_arch_io_translation_mode(mpa)); - - /* - * Map into IOMMU page table. - */ - mpa = (unsigned int) pa; - iopte = &t->page_table[(ba - t->plow) / PAGE_SIZE]; - for (i = 0; i < npages; i++) { - *iopte++ = MKIOPTE(mpa); - mpa += PAGE_SIZE; - } - - *pphys = ba; - - return va; -} - -/* - * Initialize IOMMU - * This looks like initialization of CPU MMU but - * the routine is higher in food chain. - */ -static struct iommu_regs * -iommu_init(struct iommu *t, uint64_t base) -{ - unsigned int *ptab; - int ptsize; -#ifdef CONFIG_DEBUG_IOMMU - unsigned int impl, vers; -#endif - unsigned int tmp; - struct iommu_regs *regs; - int ret; - unsigned long vasize; - - regs = (struct iommu_regs *)ofmem_map_io(base, IOMMU_REGS); - if (regs == NULL) { - DPRINTF("Cannot map IOMMU\n"); - for (;;) { } - } - t->regs = regs; -#ifdef CONFIG_DEBUG_IOMMU - impl = (regs->control & IOMMU_CTRL_IMPL) >> 28; - vers = (regs->control & IOMMU_CTRL_VERS) >> 24; -#endif - - tmp = regs->control; - tmp &= ~(IOMMU_CTRL_RNGE); - - tmp |= (IOMMU_RNGE_32MB | IOMMU_CTRL_ENAB); - t->plow = 0xfe000000; /* End - 32 MB */ - /* Size of VA region that we manage */ - vasize = 0x2000000; /* 32 MB */ - - regs->control = tmp; - iommu_invalidate(regs); - - /* Allocate IOMMU page table */ - /* Tremendous alignment causes great waste... */ - ptsize = (vasize / PAGE_SIZE) * sizeof(int); - ret = ofmem_posix_memalign((void *)&ptab, ptsize, ptsize); - if (ret != 0) { - DPRINTF("Cannot allocate IOMMU table [0x%x]\n", ptsize); - for (;;) { } - } - t->page_table = ptab; - - /* flush_cache_all(); */ - /** flush_tlb_all(); **/ - tmp = (unsigned int)va2pa((unsigned long)ptab); - regs->base = tmp >> 4; - iommu_invalidate(regs); - - DPRINTF("IOMMU: impl %d vers %d page table at 0x%p (pa 0x%x) of size %d bytes\n", - impl, vers, t->page_table, tmp, ptsize); - - mem_init(&cdvmem, (char*)t->plow, (char *)0xfffff000); - return regs; -} - -/* ( addr.lo addr.hi size -- virt ) */ - -static void -ob_iommu_map_in(void) -{ - phys_addr_t phys; - ucell size, virt; - - size = POP(); - phys = POP(); - phys = (phys << 32) + POP(); - - virt = ofmem_map_io(phys, size); - - PUSH(virt); -} - -/* ( virt size ) */ - -static void -ob_iommu_map_out(void) -{ - ucell size = POP(); - ucell virt = POP(); - - ofmem_release_io(virt, size); -} - -void -ob_init_iommu(uint64_t base) -{ - struct iommu_regs *regs; - - regs = iommu_init(&ciommu, base); - - push_str("/iommu"); - fword("find-device"); - PUSH((unsigned long)regs); - fword("encode-int"); - push_str("address"); - fword("property"); - - PUSH(base >> 32); - fword("encode-int"); - PUSH(base & 0xffffffff); - fword("encode-int"); - fword("encode+"); - PUSH(IOMMU_REGS); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - bind_func("map-in", ob_iommu_map_in); - bind_func("map-out", ob_iommu_map_out); -} diff --git a/qemu/roms/openbios/drivers/iommu.h b/qemu/roms/openbios/drivers/iommu.h deleted file mode 100644 index 59e3387ca..000000000 --- a/qemu/roms/openbios/drivers/iommu.h +++ /dev/null @@ -1,102 +0,0 @@ -/* iommu.h: Definitions for the sun4m IOMMU. - * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) - * Adapted for Proll by Pete Zaitcev in 1999 (== made worse than original). - */ - -/* #include */ - -/* The iommu handles all virtual to physical address translations - * that occur between the SBUS and physical memory. Access by - * the cpu to IO registers and similar go over the mbus so are - * translated by the on chip SRMMU. The iommu and the srmmu do - * not need to have the same translations at all, in fact most - * of the time the translations they handle are a disjunct set. - * Basically the iommu handles all dvma sbus activity. - */ - -/* The IOMMU registers occupy three pages in IO space. */ -struct iommu_regs { - /* First page */ - volatile unsigned long control; /* IOMMU control */ - volatile unsigned long base; /* Physical base of iopte page table */ - volatile unsigned long _unused1[3]; - volatile unsigned long tlbflush; /* write only */ - volatile unsigned long pageflush; /* write only */ - volatile unsigned long _unused2[1017]; - /* Second page */ - volatile unsigned long afsr; /* Async-fault status register */ - volatile unsigned long afar; /* Async-fault physical address */ - volatile unsigned long _unused3[2]; - volatile unsigned long sbuscfg0; /* SBUS configuration registers, per-slot */ - volatile unsigned long sbuscfg1; - volatile unsigned long sbuscfg2; - volatile unsigned long sbuscfg3; - volatile unsigned long mfsr; /* Memory-fault status register */ - volatile unsigned long mfar; /* Memory-fault physical address */ - volatile unsigned long _unused4[1014]; - /* Third page */ - volatile unsigned long mid; /* IOMMU module-id */ -}; - -#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */ -#define IOMMU_CTRL_VERS 0x0f000000 /* Version */ -#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */ -#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */ -#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */ -#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */ -#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */ -#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */ -#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */ -#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */ -#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */ -#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */ - -#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */ -#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */ -#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */ -#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */ -#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */ -#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */ -#define IOMMU_AFSR_RESV 0x00f00000 /* Reserver, forced to 0x8 by hardware */ -#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */ -#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */ -#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */ - -#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */ -#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */ -#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */ -#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses - produced by this device as pure - physical. */ - -#define IOMMU_MFSR_ERR 0x80000000 /* One or more of PERR1 or PERR0 */ -#define IOMMU_MFSR_S 0x01000000 /* Sparc was in supervisor mode */ -#define IOMMU_MFSR_CPU 0x00800000 /* CPU transaction caused parity error */ -#define IOMMU_MFSR_ME 0x00080000 /* Multiple parity errors occurred */ -#define IOMMU_MFSR_PERR 0x00006000 /* high bit indicates parity error occurred - on the even word of the access, low bit - indicated odd word caused the parity error */ -#define IOMMU_MFSR_BM 0x00001000 /* Error occurred while in boot mode */ -#define IOMMU_MFSR_C 0x00000800 /* Address causing error was marked cacheable */ -#define IOMMU_MFSR_RTYP 0x000000f0 /* Memory request transaction type */ - -#define IOMMU_MID_SBAE 0x001f0000 /* SBus arbitration enable */ -#define IOMMU_MID_SE 0x00100000 /* Enables SCSI/ETHERNET arbitration */ -#define IOMMU_MID_SB3 0x00080000 /* Enable SBUS device 3 arbitration */ -#define IOMMU_MID_SB2 0x00040000 /* Enable SBUS device 2 arbitration */ -#define IOMMU_MID_SB1 0x00020000 /* Enable SBUS device 1 arbitration */ -#define IOMMU_MID_SB0 0x00010000 /* Enable SBUS device 0 arbitration */ -#define IOMMU_MID_MID 0x0000000f /* Module-id, hardcoded to 0x8 */ - -/* The format of an iopte in the page tables */ -#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */ -#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */ -#define IOPTE_WRITE 0x00000004 /* Writeable */ -#define IOPTE_VALID 0x00000002 /* IOPTE is valid */ -#define IOPTE_WAZ 0x00000001 /* Write as zeros */ - -#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID) -#define MKIOPTE(phys) (((((phys)>>4) & IOPTE_PAGE) | IOPERM) & ~IOPTE_WAZ) - -#define IOMMU_REGS 0x300 diff --git a/qemu/roms/openbios/drivers/kbd.c b/qemu/roms/openbios/drivers/kbd.c deleted file mode 100644 index 43070d877..000000000 --- a/qemu/roms/openbios/drivers/kbd.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * - * Open Hack'Ware BIOS generic keyboard input translation. - * - * Copyright (c) 2005 Jocelyn Mayer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include "config.h" -#include "libc/string.h" -#include "asm/types.h" -#include "kbd.h" - -//#define DEBUG_KBD -#ifdef DEBUG_KBD -#define KBD_DPRINTF(fmt, args...) \ -do { printk("KBD - %s: " fmt, __func__ , ##args); } while (0) -#else -#define KBD_DPRINTF(fmt, args...) do { } while (0) -#endif - -int kbd_set_keymap (kbd_t *kbd, int nb_keys, const keymap_t *keymap, const char **sequences) -{ - kbd->nb_keys = nb_keys; - kbd->keymap = keymap; - kbd->sequences = sequences; - - return 0; -} - -int kbd_translate_key (kbd_t *kbd, int keycode, int up_down, char *sequence) -{ - const keymap_t *keyt; - int mod_state, key, type; - int ret; - - ret = -1; - /* Get key table */ - if (keycode < kbd->nb_keys) { - keyt = &kbd->keymap[keycode]; - /* Get modifier state */ - mod_state = (kbd->mod_state | (kbd->mod_state >> 8)) & 0xFF; - /* Adjust with lock */ - if (keyt->lck_shift >= 0) { - if ((kbd->mod_state >> (16 + keyt->lck_shift)) & 0x01) { - KBD_DPRINTF("adjust with lock %02x => %02x (%d %08x)\n", - mod_state, - mod_state ^ ((kbd->mod_state >> - (16 + keyt->lck_shift)) & - 0x01), - keyt->lck_shift, kbd->mod_state); - } - mod_state ^= (kbd->mod_state >> (16 + keyt->lck_shift)) & 0x01; - } - key = keyt->trans[mod_state]; - type = key & 0xFF000000; - key &= ~0xFF000000; - switch (type) { - case KBD_TYPE_REGULAR: - if (!up_down) { - /* We don't care about up events on "normal" keys */ - *sequence = key; - ret = 1; - } - break; - case KBD_TYPE_SEQUENCE: - if (!up_down) { - /* We don't care about up events on "normal" keys */ - ret = strlen(kbd->sequences[key]); - memcpy(sequence, kbd->sequences[key], ret); - } - break; - case KBD_TYPE_LOCK: - if (!up_down) { - kbd->mod_state ^= key; - ret = -2; - KBD_DPRINTF("Change modifier type %d key %04x %s => %08x\n", - type, key, up_down ? "up" : "down", - kbd->mod_state); - } - break; - case KBD_TYPE_LMOD: - case KBD_TYPE_RMOD: - if (up_down) - kbd->mod_state &= ~key; - else - kbd->mod_state |= key; - KBD_DPRINTF("Change modifier type %d key %04x %s => %08x\n", - type, key, up_down ? "up" : "down", kbd->mod_state); - ret = -2; /* The caller may know the key was a modifier */ - break; - default: - KBD_DPRINTF("Unknown key: keycode=%02x mod_state=%02x (%08x)\n", - keycode, mod_state, kbd->mod_state); - break; - } - } else { - KBD_DPRINTF("Unmanaged key: keycode=%02x mod_state %08x\n", - keycode, kbd->mod_state); - } - - return ret; -} diff --git a/qemu/roms/openbios/drivers/kbd.h b/qemu/roms/openbios/drivers/kbd.h deleted file mode 100644 index 8a7d0d476..000000000 --- a/qemu/roms/openbios/drivers/kbd.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * - * Open Hack'Ware BIOS generic keyboard management definitions. - * - * Copyright (c) 2005 Jocelyn Mayer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#if !defined (__OHW_KBD_H__) -#define __OHW_KBD_H__ -typedef struct kbd_t kbd_t; -typedef struct keymap_t keymap_t; -struct kbd_t { - uint32_t mod_state; - /* Modifier state - * 0x00 kk ll rr - * | | | | - * Not used for now -+ | | | - * Locks ---------------+ | | - * Left modifiers ---------+ | - * Right modifiers -----------+ - */ - int nb_keys; - const keymap_t *keymap; - const char **sequences; -}; - -/* Modifiers */ -typedef enum { - KBD_MOD_SHIFT = 0x01, - KBD_MOD_CTRL = 0x02, - KBD_MOD_ALT = 0x04, - KBD_MOD_CMD = 0x08, - KBD_MOD_OPT = 0x10, -} kbd_modifiers; - -/* Locks */ -typedef enum { - KBD_LCK_CAPS = 0x01, - KBD_LCK_NUM = 0x02, - KBD_LCK_SCROLL = 0x04, -} kbd_locks; - -/* Lock shifts */ -typedef enum { - KBD_SH_NONE = -1, - KBD_SH_CAPS = 0, - KBD_SH_NUML = 1, - KBD_SH_SCRL = 2, -} kbd_lck_shifts; - -enum { - KBD_TYPE_REGULAR = 0 << 24, - KBD_TYPE_LMOD = 1 << 24, - KBD_TYPE_RMOD = 2 << 24, - KBD_TYPE_LOCK = 3 << 24, - KBD_TYPE_SEQUENCE = 4 << 24, -}; - -#define KBD_SEQUENCE(sequence) (KBD_TYPE_SEQUENCE | (sequence)) - -#define KBD_MOD_MAP(mod) \ -KBD_SH_NONE, { (mod), (mod), (mod), (mod), (mod), (mod), (mod), (mod), \ - (mod), (mod), (mod), (mod), (mod), (mod), (mod), (mod), \ - (mod), (mod), (mod), (mod), (mod), (mod), (mod), (mod), \ - (mod), (mod), (mod), (mod), (mod), (mod), (mod), (mod), } -#define KBD_MOD_MAP_LSHIFT KBD_MOD_MAP(KBD_TYPE_LMOD | KBD_MOD_SHIFT) -#define KBD_MOD_MAP_RSHIFT KBD_MOD_MAP(KBD_TYPE_RMOD | (KBD_MOD_SHIFT << 8)) -#define KBD_MOD_MAP_LCTRL KBD_MOD_MAP(KBD_TYPE_LMOD | KBD_MOD_CTRL) -#define KBD_MOD_MAP_RCTRL KBD_MOD_MAP(KBD_TYPE_RMOD | (KBD_MOD_CTRL << 8)) -#define KBD_MOD_MAP_LALT KBD_MOD_MAP(KBD_TYPE_LMOD | KBD_MOD_ALT) -#define KBD_MOD_MAP_RALT KBD_MOD_MAP(KBD_TYPE_RMOD | (KBD_MOD_ALT << 8)) -#define KBD_MOD_MAP_LCMD KBD_MOD_MAP(KBD_TYPE_LMOD | KBD_MOD_CMD) -#define KBD_MOD_MAP_RCMD KBD_MOD_MAP(KBD_TYPE_RMOD | (KBD_MOD_CMD << 8)) -#define KBD_MOD_MAP_LOPT KBD_MOD_MAP(KBD_TYPE_LMOD | KBD_MOD_OPT) -#define KBD_MOD_MAP_ROPT KBD_MOD_MAP(KBD_TYPE_RMOD | (KBD_MOD_OPT << 8)) -#define KBD_MOD_MAP_CAPS KBD_MOD_MAP(KBD_TYPE_LOCK | (KBD_LCK_CAPS << 16)) -#define KBD_MOD_MAP_NUML KBD_MOD_MAP(KBD_TYPE_LOCK | (KBD_LCK_NUML << 16)) -#define KBD_MOD_MAP_SCROLL KBD_MOD_MAP(KBD_TYPE_LOCK | (KBD_LCK_SCRL << 16)) -#define KBD_MAP_NONE KBD_MOD_MAP(-1) - -/* Keymap definition */ -struct keymap_t { - /* Set the lock which applies to this key (if any) */ - int lck_shift; - /* Key translations */ - uint32_t trans[32]; -}; - -void *kbd_new (int len); -int kbd_set_keymap (kbd_t *kbd, int nb_keys, const keymap_t *keymap, - const char **sequences); -int kbd_translate_key (kbd_t *kbd, int keycode, int up_down, char *sequence); - -#endif /* !defined (__OHW_KBD_H__) */ diff --git a/qemu/roms/openbios/drivers/macio.c b/qemu/roms/openbios/drivers/macio.c deleted file mode 100644 index f54bc86dc..000000000 --- a/qemu/roms/openbios/drivers/macio.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * derived from mol/mol.c, - * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "arch/common/nvram.h" -#include "packages/nvram.h" -#include "libopenbios/bindings.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "drivers/drivers.h" -#include "macio.h" -#include "cuda.h" -#include "escc.h" -#include "drivers/pci.h" - -#define OW_IO_NVRAM_SIZE 0x00020000 -#define OW_IO_NVRAM_OFFSET 0x00060000 -#define OW_IO_NVRAM_SHIFT 4 - -#define NW_IO_NVRAM_SIZE 0x00004000 -#define NW_IO_NVRAM_OFFSET 0xfff04000 - -#define IO_OPENPIC_SIZE 0x00040000 -#define IO_OPENPIC_OFFSET 0x00040000 - -static char *nvram; - -static int macio_nvram_shift(void) -{ - int nvram_flat; - - if (is_oldworld()) - return OW_IO_NVRAM_SHIFT; - - nvram_flat = fw_cfg_read_i32(FW_CFG_PPC_NVRAM_FLAT); - return nvram_flat ? 0 : 1; -} - -int -macio_get_nvram_size(void) -{ - int shift = macio_nvram_shift(); - if (is_oldworld()) - return OW_IO_NVRAM_SIZE >> shift; - else - return NW_IO_NVRAM_SIZE >> shift; -} - -static unsigned long macio_nvram_offset(void) -{ - unsigned long r; - - /* Hypervisor tells us where NVRAM lies */ - r = fw_cfg_read_i32(FW_CFG_PPC_NVRAM_ADDR); - if (r) - return r; - - /* Fall back to hardcoded addresses */ - if (is_oldworld()) - return OW_IO_NVRAM_OFFSET; - - return NW_IO_NVRAM_OFFSET; -} - -static unsigned long macio_nvram_size(void) -{ - if (is_oldworld()) - return OW_IO_NVRAM_SIZE; - else - return NW_IO_NVRAM_SIZE; -} - -void macio_nvram_init(const char *path, phys_addr_t addr) -{ - phandle_t chosen, aliases; - phandle_t dnode; - int props[2]; - char buf[64]; - unsigned long nvram_size, nvram_offset; - - nvram_offset = macio_nvram_offset(); - nvram_size = macio_nvram_size(); - - nvram = (char*)addr + nvram_offset; - snprintf(buf, sizeof(buf), "%s/nvram", path); - nvram_init(buf); - dnode = find_dev(buf); - set_int_property(dnode, "#bytes", arch_nvram_size() ); - props[0] = __cpu_to_be32(nvram_offset); - props[1] = __cpu_to_be32(nvram_size); - set_property(dnode, "reg", (char *)&props, sizeof(props)); - set_property(dnode, "device_type", "nvram", 6); - NEWWORLD(set_property(dnode, "compatible", "nvram,flash", 12)); - - chosen = find_dev("/chosen"); - push_str(buf); - fword("open-dev"); - set_int_property(chosen, "nvram", POP()); - - aliases = find_dev("/aliases"); - set_property(aliases, "nvram", buf, strlen(buf) + 1); -} - -#ifdef DUMP_NVRAM -static void -dump_nvram(void) -{ - int i, j; - for (i = 0; i < 10; i++) - { - for (j = 0; j < 16; j++) - printk ("%02x ", nvram[(i*16+j)<<4]); - printk (" "); - for (j = 0; j < 16; j++) - if (isprint(nvram[(i*16+j)<<4])) - printk("%c", nvram[(i*16+j)<<4]); - else - printk("."); - printk ("\n"); - } -} -#endif - - -void -macio_nvram_put(char *buf) -{ - int i; - unsigned int it_shift = macio_nvram_shift(); - - for (i=0; i < arch_nvram_size(); i++) - nvram[i << it_shift] = buf[i]; -#ifdef DUMP_NVRAM - printk("new nvram:\n"); - dump_nvram(); -#endif -} - -void -macio_nvram_get(char *buf) -{ - int i; - unsigned int it_shift = macio_nvram_shift(); - - for (i=0; i< arch_nvram_size(); i++) - buf[i] = nvram[i << it_shift]; - -#ifdef DUMP_NVRAM - printk("current nvram:\n"); - dump_nvram(); -#endif -} - -static void -openpic_init(const char *path, phys_addr_t addr) -{ - phandle_t dnode; - int props[2]; - char buf[128]; - - push_str(path); - fword("find-device"); - fword("new-device"); - push_str("interrupt-controller"); - fword("device-name"); - - snprintf(buf, sizeof(buf), "%s/interrupt-controller", path); - dnode = find_dev(buf); - set_property(dnode, "device_type", "open-pic", 9); - set_property(dnode, "compatible", "chrp,open-pic", 14); - set_property(dnode, "built-in", "", 0); - props[0] = __cpu_to_be32(IO_OPENPIC_OFFSET); - props[1] = __cpu_to_be32(IO_OPENPIC_SIZE); - set_property(dnode, "reg", (char *)&props, sizeof(props)); - set_int_property(dnode, "#interrupt-cells", 2); - set_int_property(dnode, "#address-cells", 0); - set_property(dnode, "interrupt-controller", "", 0); - set_int_property(dnode, "clock-frequency", 4166666); - - fword("finish-device"); -} - -DECLARE_NODE(ob_macio, INSTALL_OPEN, sizeof(int), "Tmac-io"); - -/* ( str len -- addr ) */ - -static void -ob_macio_decode_unit(void *private) -{ - ucell addr; - - const char *arg = pop_fstr_copy(); - - addr = strtol(arg, NULL, 16); - - free((char*)arg); - - PUSH(addr); -} - -/* ( addr -- str len ) */ - -static void -ob_macio_encode_unit(void *private) -{ - char buf[8]; - - ucell addr = POP(); - - snprintf(buf, sizeof(buf), "%x", addr); - - push_str(buf); -} - -NODE_METHODS(ob_macio) = { - { "decode-unit", ob_macio_decode_unit }, - { "encode-unit", ob_macio_encode_unit }, -}; - -static void -ob_unin_init(void) -{ - phandle_t dnode; - int props[2]; - - push_str("/"); - fword("find-device"); - fword("new-device"); - push_str("uni-n"); - fword("device-name"); - - dnode = find_dev("/uni-n"); - set_property(dnode, "device_type", "memory-controller", 18); - set_property(dnode, "compatible", "uni-north", 10); - set_int_property(dnode, "device-rev", 0); - props[0] = __cpu_to_be32(0xf8000000); - props[1] = __cpu_to_be32(0x1000000); - set_property(dnode, "reg", (char *)&props, sizeof(props)); - - fword("finish-device"); -} - -void -ob_macio_heathrow_init(const char *path, phys_addr_t addr) -{ - phandle_t aliases; - - REGISTER_NODE(ob_macio); - aliases = find_dev("/aliases"); - set_property(aliases, "mac-io", path, strlen(path) + 1); - - cuda_init(path, addr); - macio_nvram_init(path, addr); - escc_init(path, addr); - macio_ide_init(path, addr, 2); -} - -void -ob_macio_keylargo_init(const char *path, phys_addr_t addr) -{ - phandle_t aliases; - - aliases = find_dev("/aliases"); - set_property(aliases, "mac-io", path, strlen(path) + 1); - - cuda_init(path, addr); - /* The NewWorld NVRAM is not located in the MacIO device */ - macio_nvram_init("", 0); - escc_init(path, addr); - macio_ide_init(path, addr, 2); - openpic_init(path, addr); - ob_unin_init(); -} diff --git a/qemu/roms/openbios/drivers/macio.h b/qemu/roms/openbios/drivers/macio.h deleted file mode 100644 index 925b8812b..000000000 --- a/qemu/roms/openbios/drivers/macio.h +++ /dev/null @@ -1,5 +0,0 @@ -extern phandle_t pic_handle; - -void ob_macio_heathrow_init(const char *path, phys_addr_t addr); -void ob_macio_keylargo_init(const char *path, phys_addr_t addr); -void macio_nvram_init(const char *path, phys_addr_t addr); diff --git a/qemu/roms/openbios/drivers/obio.c b/qemu/roms/openbios/drivers/obio.c deleted file mode 100644 index 4ac063188..000000000 --- a/qemu/roms/openbios/drivers/obio.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * OpenBIOS Sparc OBIO driver - * - * (C) 2004 Stefan Reinauer - * (C) 2005 Ed Schouten - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "kernel/kernel.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "drivers/drivers.h" -#include "arch/common/nvram.h" -#include "libopenbios/ofmem.h" -#include "obio.h" -#include "escc.h" - -#define PROMDEV_KBD 0 /* input from keyboard */ -#define PROMDEV_SCREEN 0 /* output to screen */ -#define PROMDEV_TTYA 1 /* in/out to ttya */ - - -void -ob_new_obio_device(const char *name, const char *type) -{ - push_str("/obio"); - fword("find-device"); - fword("new-device"); - - push_str(name); - fword("device-name"); - - if (type) { - push_str(type); - fword("device-type"); - } -} - -static unsigned long -map_reg(uint64_t base, uint64_t offset, unsigned long size, int map, - int phys_hi) -{ - PUSH(phys_hi); - fword("encode-int"); - PUSH(offset); - fword("encode-int"); - fword("encode+"); - PUSH(size); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - if (map) { - unsigned long addr; - - addr = (unsigned long)ofmem_map_io(base + offset, size); - - PUSH(addr); - fword("encode-int"); - push_str("address"); - fword("property"); - return addr; - } - return 0; -} - -unsigned long -ob_reg(uint64_t base, uint64_t offset, unsigned long size, int map) -{ - return map_reg(base, offset, size, map, 0); -} - -void -ob_intr(int intr) -{ - PUSH(intr); - fword("encode-int"); - PUSH(0); - fword("encode-int"); - fword("encode+"); - push_str("intr"); - fword("property"); -} - -void -ob_eccmemctl_init(uint64_t base) -{ - uint32_t version, *regs; - const char *mc_type; - - push_str("/"); - fword("find-device"); - fword("new-device"); - - push_str("eccmemctl"); - fword("device-name"); - - PUSH(0x20); - fword("encode-int"); - push_str("width"); - fword("property"); - - regs = (uint32_t *)map_reg(ECC_BASE, 0, ECC_SIZE, 1, ECC_BASE >> 32); - - version = regs[0]; - switch (version) { - case 0x00000000: - mc_type = "MCC"; - break; - case 0x10000000: - mc_type = "EMC"; - break; - default: - case 0x20000000: - mc_type = "SMC"; - break; - } - push_str(mc_type); - fword("encode-string"); - push_str("mc-type"); - fword("property"); - - fword("finish-device"); -} - -static unsigned char *nvram; - -#define NVRAM_OB_START (0) -#define NVRAM_OB_SIZE ((NVRAM_IDPROM - NVRAM_OB_START) & ~15) - -void -arch_nvram_get(char *data) -{ - memcpy(data, &nvram[NVRAM_OB_START], NVRAM_OB_SIZE); -} - -void -arch_nvram_put(char *data) -{ - memcpy(&nvram[NVRAM_OB_START], data, NVRAM_OB_SIZE); -} - -int -arch_nvram_size(void) -{ - return NVRAM_OB_SIZE; -} - -void -ss5_init(uint64_t base) -{ - ob_new_obio_device("slavioconfig", NULL); - - ob_reg(base, SLAVIO_SCONFIG, SCONFIG_REGS, 0); - - fword("finish-device"); -} - -static void -ob_nvram_init(uint64_t base, uint64_t offset) -{ - ob_new_obio_device("eeprom", NULL); - - nvram = (unsigned char *)ob_reg(base, offset, NVRAM_SIZE, 1); - - PUSH((unsigned long)nvram); - fword("encode-int"); - push_str("address"); - fword("property"); - - push_str("mk48t08"); - fword("model"); - - fword("finish-device"); - - // Add /idprom - push_str("/"); - fword("find-device"); - - PUSH((long)&nvram[NVRAM_IDPROM]); - PUSH(32); - fword("encode-bytes"); - push_str("idprom"); - fword("property"); -} - -static void -ob_fd_init(uint64_t base, uint64_t offset, int intr) -{ - unsigned long addr; - - ob_new_obio_device("SUNW,fdtwo", "block"); - - addr = ob_reg(base, offset, FD_REGS, 1); - - ob_intr(intr); - - fword("is-deblocker"); - - ob_floppy_init("/obio", "SUNW,fdtwo", 0, addr); - - fword("finish-device"); -} - -static void -ob_auxio_init(uint64_t base, uint64_t offset) -{ - ob_new_obio_device("auxio", NULL); - - ob_reg(base, offset, AUXIO_REGS, 1); - - fword("finish-device"); -} - -volatile unsigned char *power_reg; -volatile unsigned int *reset_reg; - -static void -sparc32_reset_all(void) -{ - *reset_reg = 1; -} - -// AUX 2 (Software Powerdown Control) and reset -static void -ob_aux2_reset_init(uint64_t base, uint64_t offset, int intr) -{ - ob_new_obio_device("power", NULL); - - power_reg = (void *)ob_reg(base, offset, AUXIO2_REGS, 1); - - // Not in device tree - reset_reg = (unsigned int *)ofmem_map_io(base + (uint64_t)SLAVIO_RESET, RESET_REGS); - - bind_func("sparc32-reset-all", sparc32_reset_all); - push_str("' sparc32-reset-all to reset-all"); - fword("eval"); - - ob_intr(intr); - - fword("finish-device"); -} - -volatile struct sun4m_timer_regs *counter_regs; - -static void -ob_counter_init(uint64_t base, unsigned long offset, int ncpu) -{ - int i; - - ob_new_obio_device("counter", NULL); - - for (i = 0; i < ncpu; i++) { - PUSH(0); - fword("encode-int"); - if (i != 0) fword("encode+"); - PUSH(offset + (i * PAGE_SIZE)); - fword("encode-int"); - fword("encode+"); - PUSH(COUNTER_REGS); - fword("encode-int"); - fword("encode+"); - } - - PUSH(0); - fword("encode-int"); - fword("encode+"); - PUSH(offset + 0x10000); - fword("encode-int"); - fword("encode+"); - PUSH(COUNTER_REGS); - fword("encode-int"); - fword("encode+"); - - push_str("reg"); - fword("property"); - - - counter_regs = (struct sun4m_timer_regs *)ofmem_map_io(base + (uint64_t)offset, sizeof(*counter_regs)); - counter_regs->cfg = 0xfffffffe; - counter_regs->l10_timer_limit = 0; - counter_regs->cpu_timers[0].l14_timer_limit = 0x9c4000; /* see comment in obio.h */ - counter_regs->cpu_timers[0].cntrl = 1; - - for (i = 0; i < ncpu; i++) { - PUSH((unsigned long)&counter_regs->cpu_timers[i]); - fword("encode-int"); - if (i != 0) - fword("encode+"); - } - PUSH((unsigned long)&counter_regs->l10_timer_limit); - fword("encode-int"); - fword("encode+"); - push_str("address"); - fword("property"); - - fword("finish-device"); -} - -static volatile struct sun4m_intregs *intregs; - -static void -ob_interrupt_init(uint64_t base, unsigned long offset, int ncpu) -{ - int i; - - ob_new_obio_device("interrupt", NULL); - - for (i = 0; i < ncpu; i++) { - PUSH(0); - fword("encode-int"); - if (i != 0) fword("encode+"); - PUSH(offset + (i * PAGE_SIZE)); - fword("encode-int"); - fword("encode+"); - PUSH(INTERRUPT_REGS); - fword("encode-int"); - fword("encode+"); - } - - PUSH(0); - fword("encode-int"); - fword("encode+"); - PUSH(offset + 0x10000); - fword("encode-int"); - fword("encode+"); - PUSH(INTERRUPT_REGS); - fword("encode-int"); - fword("encode+"); - - push_str("reg"); - fword("property"); - - intregs = (struct sun4m_intregs *)ofmem_map_io(base | (uint64_t)offset, sizeof(*intregs)); - intregs->clear = ~SUN4M_INT_MASKALL; - intregs->cpu_intregs[0].clear = ~0x17fff; - - for (i = 0; i < ncpu; i++) { - PUSH((unsigned long)&intregs->cpu_intregs[i]); - fword("encode-int"); - if (i != 0) - fword("encode+"); - } - PUSH((unsigned long)&intregs->tbt); - fword("encode-int"); - fword("encode+"); - push_str("address"); - fword("property"); - - fword("finish-device"); -} - -/* SMP CPU boot structure */ -struct smp_cfg { - uint32_t smp_ctx; - uint32_t smp_ctxtbl; - uint32_t smp_entry; - uint32_t valid; -}; - -static struct smp_cfg *smp_header; - -int -start_cpu(unsigned int pc, unsigned int context_ptr, unsigned int context, int cpu) -{ - if (!cpu) - return -1; - - cpu &= 7; - - smp_header->smp_entry = pc; - smp_header->smp_ctxtbl = context_ptr; - smp_header->smp_ctx = context; - smp_header->valid = cpu; - - intregs->cpu_intregs[cpu].set = SUN4M_SOFT_INT(14); - - return 0; -} - -static void -ob_smp_init(unsigned long mem_size) -{ - // See arch/sparc32/entry.S for memory layout - smp_header = (struct smp_cfg *)ofmem_map_io((uint64_t)(mem_size - 0x100), - sizeof(struct smp_cfg)); -} - -static void -ob_set_obio_ranges(uint64_t base) -{ - push_str("/obio"); - fword("find-device"); - PUSH(0); - fword("encode-int"); - PUSH(0); - fword("encode-int"); - fword("encode+"); - PUSH(base >> 32); - fword("encode-int"); - fword("encode+"); - PUSH(base & 0xffffffff); - fword("encode-int"); - fword("encode+"); - PUSH(SLAVIO_SIZE); - fword("encode-int"); - fword("encode+"); - push_str("ranges"); - fword("property"); -} - - -int -ob_obio_init(uint64_t slavio_base, unsigned long fd_offset, - unsigned long counter_offset, unsigned long intr_offset, - int intr_ncpu, unsigned long aux1_offset, unsigned long aux2_offset, - unsigned long mem_size) -{ - - // All devices were integrated to NCR89C105, see - // http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt - - //printk("Initializing OBIO devices...\n"); - ob_set_obio_ranges(slavio_base); - - // Zilog Z8530 serial ports, see http://www.zilog.com - // Must be before zs@0,0 or Linux won't boot - ob_zs_init(slavio_base, SLAVIO_ZS1, ZS_INTR, 0, 0); - - ob_zs_init(slavio_base, SLAVIO_ZS, ZS_INTR, 1, 1); - - // M48T08 NVRAM, see http://www.st.com - ob_nvram_init(slavio_base, SLAVIO_NVRAM); - - // 82078 FDC - if (fd_offset != (unsigned long) -1) - ob_fd_init(slavio_base, fd_offset, FD_INTR); - - ob_auxio_init(slavio_base, aux1_offset); - - if (aux2_offset != (unsigned long) -1) - ob_aux2_reset_init(slavio_base, aux2_offset, AUXIO2_INTR); - - ob_counter_init(slavio_base, counter_offset, intr_ncpu); - - ob_interrupt_init(slavio_base, intr_offset, intr_ncpu); - - ob_smp_init(mem_size); - - return 0; -} diff --git a/qemu/roms/openbios/drivers/obio.h b/qemu/roms/openbios/drivers/obio.h deleted file mode 100644 index 49c3040c4..000000000 --- a/qemu/roms/openbios/drivers/obio.h +++ /dev/null @@ -1,165 +0,0 @@ -/* Addresses, interrupt numbers, register sizes */ - -#define SLAVIO_ZS 0x00000000ULL -#define SLAVIO_ZS1 0x00100000ULL -#define ZS_INTR 0x2c - -#define SLAVIO_NVRAM 0x00200000ULL -#define NVRAM_SIZE 0x2000 -#define NVRAM_IDPROM 0x1fd8 - -#define SLAVIO_FD 0x00400000ULL -#define FD_REGS 15 -#define FD_INTR 0x2b - -#define SLAVIO_SCONFIG 0x00800000ULL -#define SCONFIG_REGS 1 - -#define AUXIO_REGS 1 - -#define AUXIO2_REGS 1 -#define AUXIO2_INTR 0x22 - -#define SLAVIO_COUNTER 0x00d00000ULL -#define COUNTER_REGS 0x10 - -#define SLAVIO_INTERRUPT 0x00e00000ULL -#define INTERRUPT_REGS 0x10 - -#define SLAVIO_RESET 0x00f00000ULL -#define RESET_REGS 1 - -#define ECC_BASE 0xf00000000ULL -#define ECC_SIZE 0x20 - -#define SLAVIO_SIZE 0x01000000 - -#define SUN4M_NCPUS 16 - -#define CFG_ADDR 0xd00000510ULL -#define CFG_SIZE 3 - -/* linux/include/asm-sparc/timer.h */ - -/* A sun4m has two blocks of registers which are probably of the same - * structure. LSI Logic's L64851 is told to _decrement_ from the limit - * value. Aurora behaves similarly but its limit value is compacted in - * other fashion (it's wider). Documented fields are defined here. - */ - -/* As with the interrupt register, we have two classes of timer registers - * which are per-cpu and master. Per-cpu timers only hit that cpu and are - * only level 14 ticks, master timer hits all cpus and is level 10. - */ - -#define SUN4M_PRM_CNT_L 0x80000000 -#define SUN4M_PRM_CNT_LVALUE 0x7FFFFC00 - -struct sun4m_timer_percpu_info { - __volatile__ unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */ - __volatile__ unsigned int l14_cur_count; - - /* This register appears to be write only and/or inaccessible - * on Uni-Processor sun4m machines. - */ - __volatile__ unsigned int l14_limit_noclear; /* Data access error is here */ - - __volatile__ unsigned int cntrl; /* =1 after POST on Aurora */ - __volatile__ unsigned char space[PAGE_SIZE - 16]; -}; - -struct sun4m_timer_regs { - struct sun4m_timer_percpu_info cpu_timers[SUN4M_NCPUS]; - volatile unsigned int l10_timer_limit; - volatile unsigned int l10_cur_count; - - /* Again, this appears to be write only and/or inaccessible - * on uni-processor sun4m machines. - */ - volatile unsigned int l10_limit_noclear; - - /* This register too, it must be magic. */ - volatile unsigned int foobar; - - volatile unsigned int cfg; /* equals zero at boot time... */ -}; - -/* - * Registers of hardware timer in sun4m. - */ -struct sun4m_timer_percpu { - volatile unsigned int l14_timer_limit; /* Initial value is 0x009c4000 = 10ms period*/ - volatile unsigned int l14_cur_count; -}; - -struct sun4m_timer_global { - volatile unsigned int l10_timer_limit; - volatile unsigned int l10_cur_count; -}; - -/* linux/include/asm-sparc/irq.h */ - -/* These registers are used for sending/receiving irqs from/to - * different cpu's. - */ -struct sun4m_intreg_percpu { - unsigned int tbt; /* Interrupts still pending for this cpu. */ - - /* These next two registers are WRITE-ONLY and are only - * "on bit" sensitive, "off bits" written have NO affect. - */ - unsigned int clear; /* Clear this cpus irqs here. */ - unsigned int set; /* Set this cpus irqs here. */ - unsigned char space[PAGE_SIZE - 12]; -}; - -/* - * djhr - * Actually the clear and set fields in this struct are misleading.. - * according to the SLAVIO manual (and the same applies for the SEC) - * the clear field clears bits in the mask which will ENABLE that IRQ - * the set field sets bits in the mask to DISABLE the IRQ. - * - * Also the undirected_xx address in the SLAVIO is defined as - * RESERVED and write only.. - * - * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor - * sun4m machines, for MP the layout makes more sense. - */ -struct sun4m_intregs { - struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS]; - unsigned int tbt; /* IRQ's that are still pending. */ - unsigned int irqs; /* Master IRQ bits. */ - - /* Again, like the above, two these registers are WRITE-ONLY. */ - unsigned int clear; /* Clear master IRQ's by setting bits here. */ - unsigned int set; /* Set master IRQ's by setting bits here. */ - - /* This register is both READ and WRITE. */ - unsigned int undirected_target; /* Which cpu gets undirected irqs. */ -}; - -/* Dave Redman (djhr@tadpole.co.uk) - * The sun4m interrupt registers. - */ -#define SUN4M_INT_ENABLE 0x80000000 -#define SUN4M_INT_E14 0x00000080 -#define SUN4M_INT_E10 0x00080000 - -#define SUN4M_HARD_INT(x) (0x000000001 << (x)) -#define SUN4M_SOFT_INT(x) (0x000010000 << (x)) - -#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ -#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ -#define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */ -#define SUN4M_INT_ECC 0x10000000 /* ecc memory error */ -#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */ -#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */ -#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */ -#define SUN4M_INT_REALTIME 0x00080000 /* system timer */ -#define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */ -#define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */ -#define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */ -#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */ -#define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */ -#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */ diff --git a/qemu/roms/openbios/drivers/pc_kbd.c b/qemu/roms/openbios/drivers/pc_kbd.c deleted file mode 100644 index 49218f82e..000000000 --- a/qemu/roms/openbios/drivers/pc_kbd.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2003, 2004 Stefan Reinauer - * - * See the file "COPYING" for further information about - * the copyright and warranty status of this work. - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "kernel/kernel.h" -#include "drivers/drivers.h" -#include "libc/vsprintf.h" - -/* ****************************************************************** - * simple polling video/keyboard console functions - * ****************************************************************** */ - -#define SER_SIZE 8 - -/* - * keyboard driver - */ - -static const char normal[] = { - 0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', - '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', - 'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j', - 'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b', - 'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f -}; - -static const char shifted[] = { - 0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', - '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', - 'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', - 'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B', - 'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8', - '9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f -}; - -static int key_ext; -static int key_lshift = 0, key_rshift = 0, key_caps = 0; - -static char last_key; - -static void pc_kbd_cmd(unsigned char cmd, unsigned char val) -{ - outb(cmd, 0x60); - /* wait until keyboard controller accepts cmds: */ - while (inb(0x64) & 2); - outb(val, 0x60); - while (inb(0x64) & 2); -} - -static void pc_kbd_controller_cmd(unsigned char cmd, unsigned char val) -{ - outb(cmd, 0x64); - /* wait until keyboard controller accepts cmds: */ - while (inb(0x64) & 2); - outb(val, 0x60); - while (inb(0x64) & 2); -} - -static char pc_kbd_poll(void) -{ - unsigned int c; - if (inb(0x64) & 1) { - c = inb(0x60); - switch (c) { - case 0xe0: - key_ext = 1; - return 0; - case 0x2a: - key_lshift = 1; - return 0; - case 0x36: - key_rshift = 1; - return 0; - case 0xaa: - key_lshift = 0; - return 0; - case 0xb6: - key_rshift = 0; - return 0; - case 0x3a: - if (key_caps) { - key_caps = 0; - pc_kbd_cmd(0xed, 0); - } else { - key_caps = 1; - pc_kbd_cmd(0xed, 4); /* set caps led */ - } - return 0; - } - - if (key_ext) { - // void printk(const char *format, ...); - printk("extended keycode: %x\n", c); - - key_ext = 0; - return 0; - } - - if (c & 0x80) /* unhandled key release */ - return 0; - - if (key_lshift || key_rshift) - return key_caps ? normal[c] : shifted[c]; - else - return key_caps ? shifted[c] : normal[c]; - } - return 0; -} - -int pc_kbd_dataready(void) -{ - if (last_key) - return 1; - - last_key = pc_kbd_poll(); - - return (last_key != 0); -} - -unsigned char pc_kbd_readdata(void) -{ - char tmp; - while (!pc_kbd_dataready()); - tmp = last_key; - last_key = 0; - return tmp; -} - -/* ( addr len -- actual ) */ -static void -pc_kbd_read(void) -{ - unsigned char *addr; - int len; - - len = POP(); - addr = (unsigned char *)POP(); - - if (len != 1) - printk("pc_kbd_read: bad len, addr %lx len %x\n", (unsigned long)addr, len); - - if (pc_kbd_dataready()) { - *addr = pc_kbd_readdata(); - PUSH(1); - } else { - PUSH(0); - } -} - -static void -pc_kbd_close(void) -{ -} - -static void -pc_kbd_open(unsigned long *address) -{ - int len; - phandle_t ph; - unsigned long *prop; - - fword("my-self"); - fword("ihandle>phandle"); - ph = (phandle_t)POP(); - prop = (unsigned long *)get_property(ph, "address", &len); - *address = *prop; - - RET ( -1 ); -} - -DECLARE_UNNAMED_NODE(pc_kbd, INSTALL_OPEN, sizeof(unsigned long)); - -NODE_METHODS(pc_kbd) = { - { "open", pc_kbd_open }, - { "close", pc_kbd_close }, - { "read", pc_kbd_read }, -}; - -void -ob_pc_kbd_init(const char *path, const char *dev_name, uint64_t base, - uint64_t offset, int intr) -{ - phandle_t chosen, aliases; - char nodebuff[128]; - - snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name); - REGISTER_NAMED_NODE(pc_kbd, nodebuff); - - push_str(nodebuff); - fword("find-device"); - - push_str(dev_name); - fword("device-name"); - - push_str("serial"); - fword("device-type"); - - PUSH(-1); - fword("encode-int"); - push_str("keyboard"); - fword("property"); - - PUSH((base + offset) >> 32); - fword("encode-int"); - PUSH((base + offset) & 0xffffffff); - fword("encode-int"); - fword("encode+"); - PUSH(SER_SIZE); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - PUSH(offset); - fword("encode-int"); - push_str("address"); - fword("property"); - - chosen = find_dev("/chosen"); - push_str(nodebuff); - fword("open-dev"); - set_int_property(chosen, "keyboard", POP()); - - aliases = find_dev("/aliases"); - set_property(aliases, "keyboard", nodebuff, strlen(nodebuff) + 1); - - pc_kbd_controller_cmd(0x60, 0x40); // Write mode command, translated mode -} diff --git a/qemu/roms/openbios/drivers/pc_serial.c b/qemu/roms/openbios/drivers/pc_serial.c deleted file mode 100644 index a638e1f99..000000000 --- a/qemu/roms/openbios/drivers/pc_serial.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2003, 2004 Stefan Reinauer - * - * See the file "COPYING" for further information about - * the copyright and warranty status of this work. - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "kernel/kernel.h" -#include "drivers/drivers.h" -#include "libc/vsprintf.h" - -/* ****************************************************************** - * serial console functions - * ****************************************************************** */ - -#define SER_SIZE 8 - -#define RBR(x) x==2?0x2f8:0x3f8 -#define THR(x) x==2?0x2f8:0x3f8 -#define IER(x) x==2?0x2f9:0x3f9 -#define IIR(x) x==2?0x2fa:0x3fa -#define LCR(x) x==2?0x2fb:0x3fb -#define MCR(x) x==2?0x2fc:0x3fc -#define LSR(x) x==2?0x2fd:0x3fd -#define MSR(x) x==2?0x2fe:0x3fe -#define SCR(x) x==2?0x2ff:0x3ff -#define DLL(x) x==2?0x2f8:0x3f8 -#define DLM(x) x==2?0x2f9:0x3f9 - -int uart_charav(int port) -{ - return ((inb(LSR(port)) & 1) != 0); -} - -char uart_getchar(int port) -{ - while (!uart_charav(port)); - return ((char) inb(RBR(port)) & 0177); -} - -static void uart_port_putchar(int port, unsigned char c) -{ - if (c == '\n') - uart_port_putchar(port, '\r'); - while (!(inb(LSR(port)) & 0x20)); - outb(c, THR(port)); -} - -static void uart_init_line(int port, unsigned long baud) -{ - int i, baudconst; - - switch (baud) { - case 115200: - baudconst = 1; - break; - case 57600: - baudconst = 2; - break; - case 38400: - baudconst = 3; - break; - case 19200: - baudconst = 6; - break; - case 9600: - default: - baudconst = 12; - break; - } - - outb(0x87, LCR(port)); - outb(0x00, DLM(port)); - outb(baudconst, DLL(port)); - outb(0x07, LCR(port)); - outb(0x0f, MCR(port)); - - for (i = 10; i > 0; i--) { - if (inb(LSR(port)) == (unsigned int) 0) - break; - inb(RBR(port)); - } -} - -#ifdef CONFIG_DEBUG_CONSOLE_SERIAL -int uart_init(int port, unsigned long speed) -{ - uart_init_line(port, speed); - return -1; -} - -void uart_putchar(int c) -{ - uart_port_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff)); -} -#endif - -/* ( addr len -- actual ) */ -static void -pc_serial_read(unsigned long *address) -{ - char *addr; - int len; - - len = POP(); - addr = (char *)POP(); - - if (len != 1) - printk("pc_serial_read: bad len, addr %lx len %x\n", (unsigned long)addr, len); - - if (uart_charav(*address)) { - *addr = (char)uart_getchar(*address); - PUSH(1); - } else { - PUSH(0); - } -} - -/* ( addr len -- actual ) */ -static void -pc_serial_write(unsigned long *address) -{ - unsigned char *addr; - int i, len; - - len = POP(); - addr = (unsigned char *)POP(); - - for (i = 0; i < len; i++) { - uart_port_putchar(*address, addr[i]); - } - PUSH(len); -} - -static void -pc_serial_close(void) -{ -} - -static void -pc_serial_open(unsigned long *address) -{ - RET ( -1 ); -} - -static void -pc_serial_init(unsigned long *address) -{ - *address = POP(); -} - -DECLARE_UNNAMED_NODE(pc_serial, INSTALL_OPEN, sizeof(unsigned long)); - -NODE_METHODS(pc_serial) = { - { "init", pc_serial_init }, - { "open", pc_serial_open }, - { "close", pc_serial_close }, - { "read", pc_serial_read }, - { "write", pc_serial_write }, -}; - -void -ob_pc_serial_init(const char *path, const char *dev_name, uint64_t base, - uint64_t offset, int intr) -{ - phandle_t aliases; - char nodebuff[128]; - - snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name); - REGISTER_NAMED_NODE(pc_serial, nodebuff); - - push_str(nodebuff); - fword("find-device"); - - PUSH(offset); - PUSH(find_package_method("init", get_cur_dev())); - fword("execute"); - - push_str("serial"); - fword("device-type"); - - PUSH((base + offset) >> 32); - fword("encode-int"); - PUSH((base + offset) & 0xffffffff); - fword("encode-int"); - fword("encode+"); - PUSH(SER_SIZE); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - -#if !defined(CONFIG_SPARC64) - PUSH(offset); - fword("encode-int"); - push_str("address"); - fword("property"); -#endif - -#if defined(CONFIG_SPARC64) - set_int_property(get_cur_dev(), "interrupts", 1); -#endif - - aliases = find_dev("/aliases"); - set_property(aliases, "ttya", nodebuff, strlen(nodebuff) + 1); -} diff --git a/qemu/roms/openbios/drivers/pci.c b/qemu/roms/openbios/drivers/pci.c deleted file mode 100644 index 5062f302f..000000000 --- a/qemu/roms/openbios/drivers/pci.c +++ /dev/null @@ -1,1600 +0,0 @@ -/* - * OpenBIOS pci driver - * - * This driver is compliant to the - * PCI bus binding to IEEE 1275-1994 Rev 2.1 - * - * (C) 2004 Stefan Reinauer - * (C) 2005 Ed Schouten - * - * Some parts from OpenHackWare-0.4, Copyright (c) 2004-2005 Jocelyn Mayer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "libopenbios/ofmem.h" -#include "kernel/kernel.h" -#include "drivers/pci.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" - -#include "drivers/drivers.h" -#include "drivers/vga.h" -#include "packages/video.h" -#include "libopenbios/video.h" -#include "timer.h" -#include "pci.h" -#include "pci_database.h" -#ifdef CONFIG_DRIVER_MACIO -#include "cuda.h" -#include "macio.h" -#endif -#ifdef CONFIG_DRIVER_USB -#include "drivers/usb.h" -#endif - -#if defined (CONFIG_DEBUG_PCI) -# define PCI_DPRINTF(format, ...) printk(format, ## __VA_ARGS__) -#else -# define PCI_DPRINTF(format, ...) do { } while (0) -#endif - -#define set_bool_property(ph, name) set_property(ph, name, NULL, 0); - -/* DECLARE data structures for the nodes. */ - -DECLARE_UNNAMED_NODE( ob_pci_bus_node, INSTALL_OPEN, 2*sizeof(int) ); -DECLARE_UNNAMED_NODE( ob_pci_simple_node, INSTALL_OPEN, 2*sizeof(int) ); -DECLARE_UNNAMED_NODE( ob_pci_empty_node, 0, 2*sizeof(int) ); - -const pci_arch_t *arch; - -#define IS_NOT_RELOCATABLE 0x80000000 -#define IS_PREFETCHABLE 0x40000000 -#define IS_ALIASED 0x20000000 - -enum { - CONFIGURATION_SPACE = 0, - IO_SPACE = 1, - MEMORY_SPACE_32 = 2, - MEMORY_SPACE_64 = 3, -}; - -static int encode_int32_cells(int num_cells, u32 *prop, ucell val) -{ - int i = 0; - - /* hi ... lo */ - for (i=0; i < num_cells; ++i) { - prop[num_cells - i - 1] = val; - val >>= 16; - val >>= 16; - } - - return num_cells; -} - -static inline int pci_encode_phys_addr(u32 *phys, int flags, int space_code, - pci_addr dev, uint8_t reg, uint64_t addr) -{ - - /* phys.hi */ - - phys[0] = flags | (space_code << 24) | dev | reg; - - /* phys.mid */ - - phys[1] = addr >> 32; - - /* phys.lo */ - - phys[2] = addr; - - return 3; -} - -static inline int pci_encode_size(u32 *prop, uint64_t size) -{ - return encode_int32_cells(2, prop, size); -} - -static int host_address_cells(void) -{ - return get_int_property(find_dev("/"), "#address-cells", NULL); -} - -static int host_encode_phys_addr(u32 *prop, ucell addr) -{ - return encode_int32_cells(host_address_cells(), prop, addr); -} - -static int host_size_cells(void) -{ - return get_int_property(find_dev("/"), "#size-cells", NULL); -} - -/* -static int parent_address_cells(void) -{ - phandle_t parent_ph = ih_to_phandle(my_parent()); - return get_int_property(parent_ph, "#address-cells", NULL); -} - -static int parent_size_cells(void) -{ - phandle_t parent_ph = ih_to_phandle(my_parent()); - return get_int_property(parent_ph, "#size-cells", NULL); -} -*/ - -#if defined(CONFIG_DEBUG_PCI) -static void dump_reg_property(const char* description, int nreg, u32 *reg) -{ - int i; - printk("%s reg", description); - for (i=0; i < nreg; ++i) { - printk(" %08X", reg[i]); - } - printk("\n"); -} -#endif - -static unsigned long pci_bus_addr_to_host_addr(int space, uint32_t ba) -{ - if (space == IO_SPACE) { - return arch->io_base + (unsigned long)ba; - } else if (space == MEMORY_SPACE_32) { - return arch->host_pci_base + (unsigned long)ba; - } else { - /* Return unaltered to aid debugging property values */ - return (unsigned long)ba; - } -} - -static void -ob_pci_open(int *idx) -{ - int ret=1; - RET ( -ret ); -} - -static void -ob_pci_close(int *idx) -{ -} - -static void -ob_pci_initialize(int *idx) -{ -} - -/* ( str len -- phys.lo phys.mid phys.hi ) */ - -static void -ob_pci_decode_unit(int *idx) -{ - ucell hi, mid, lo; - const char *arg = pop_fstr_copy(); - int dev, fn, reg, ss, n, p, t; - int bus = 0; /* no information */ - char *ptr; - - PCI_DPRINTF("ob_pci_decode_unit idx=%p\n", idx); - - fn = 0; - reg = 0; - n = 0; - p = 0; - t = 0; - - ptr = (char*)arg; - if (*ptr == 'n') { - n = IS_NOT_RELOCATABLE; - ptr++; - } - if (*ptr == 'i') { - ss = IO_SPACE; - ptr++; - if (*ptr == 't') { - t = IS_ALIASED; - ptr++; - } - - /* DD,F,RR,NNNNNNNN */ - - dev = strtol(ptr, &ptr, 16); - ptr++; - fn = strtol(ptr, &ptr, 16); - ptr++; - reg = strtol(ptr, &ptr, 16); - ptr++; - lo = strtol(ptr, &ptr, 16); - mid = 0; - - } else if (*ptr == 'm') { - ss = MEMORY_SPACE_32; - ptr++; - if (*ptr == 't') { - t = IS_ALIASED; - ptr++; - } - if (*ptr == 'p') { - p = IS_PREFETCHABLE; - ptr++; - } - - /* DD,F,RR,NNNNNNNN */ - - dev = strtol(ptr, &ptr, 16); - ptr++; - fn = strtol(ptr, &ptr, 16); - ptr++; - reg = strtol(ptr, &ptr, 16); - ptr++; - lo = strtol(ptr, &ptr, 16); - mid = 0; - - } else if (*ptr == 'x') { - unsigned long long addr64; - ss = MEMORY_SPACE_64; - ptr++; - if (*ptr == 'p') { - p = IS_PREFETCHABLE; - ptr++; - } - - /* DD,F,RR,NNNNNNNNNNNNNNNN */ - - dev = strtol(ptr, &ptr, 16); - ptr++; - fn = strtol(ptr, &ptr, 16); - ptr++; - reg = strtol(ptr, &ptr, 16); - ptr++; - addr64 = strtoll(ptr, &ptr, 16); - lo = (ucell)addr64; - mid = addr64 >> 32; - - } else { - ss = CONFIGURATION_SPACE; - /* "DD" or "DD,FF" */ - dev = strtol(ptr, &ptr, 16); - if (*ptr == ',') { - ptr++; - fn = strtol(ptr, NULL, 16); - } - lo = 0; - mid = 0; - } - free((char*)arg); - - hi = n | p | t | (ss << 24) | (bus << 16) | (dev << 11) | (fn << 8) | reg; - - PUSH(lo); - PUSH(mid); - PUSH(hi); - - PCI_DPRINTF("ob_pci_decode_unit idx=%p addr=" - FMT_ucellx " " FMT_ucellx " " FMT_ucellx "\n", - idx, lo, mid, hi); -} - -/* ( phys.lo phy.mid phys.hi -- str len ) */ - -static void -ob_pci_encode_unit(int *idx) -{ - char buf[28]; - cell hi = POP(); - cell mid = POP(); - cell lo = POP(); - int n, p, t, ss, dev, fn, reg; - - n = hi & IS_NOT_RELOCATABLE; - p = hi & IS_PREFETCHABLE; - t = hi & IS_ALIASED; - ss = (hi >> 24) & 0x03; - - dev = (hi >> 11) & 0x1F; - fn = (hi >> 8) & 0x07; - reg = hi & 0xFF; - - switch(ss) { - case CONFIGURATION_SPACE: - - if (fn == 0) /* DD */ - snprintf(buf, sizeof(buf), "%x", dev); - else /* DD,F */ - snprintf(buf, sizeof(buf), "%x,%x", dev, fn); - break; - - case IO_SPACE: - - /* [n]i[t]DD,F,RR,NNNNNNNN */ - snprintf(buf, sizeof(buf), "%si%s%x,%x,%x," FMT_ucellx, - n ? "n" : "", /* relocatable */ - t ? "t" : "", /* aliased */ - dev, fn, reg, t ? lo & 0x03FF : lo); - break; - - case MEMORY_SPACE_32: - - /* [n]m[t][p]DD,F,RR,NNNNNNNN */ - snprintf(buf, sizeof(buf), "%sm%s%s%x,%x,%x," FMT_ucellx, - n ? "n" : "", /* relocatable */ - t ? "t" : "", /* aliased */ - p ? "p" : "", /* prefetchable */ - dev, fn, reg, lo ); - break; - - case MEMORY_SPACE_64: - - /* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN */ - snprintf(buf, sizeof(buf), "%sx%s%x,%x,%x,%llx", - n ? "n" : "", /* relocatable */ - p ? "p" : "", /* prefetchable */ - dev, fn, reg, ((long long)mid << 32) | (long long)lo); - break; - } - push_str(buf); - - PCI_DPRINTF("ob_pci_encode_unit space=%d dev=%d fn=%d buf=%s\n", - ss, dev, fn, buf); -} - -/* ( pci-addr.lo pci-addr.mid pci-addr.hi size -- virt ) */ - -static void -ob_pci_map_in(int *idx) -{ - phys_addr_t phys; - uint32_t ba; - ucell size, virt, tmp; - int space; - - PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx); - - size = POP(); - tmp = POP(); - POP(); - ba = POP(); - - /* Get the space from the pci-addr.hi */ - space = ((tmp & PCI_RANGE_TYPE_MASK) >> 24); - - phys = pci_bus_addr_to_host_addr(space, ba); - -#if defined(CONFIG_OFMEM) - ofmem_claim_phys(phys, size, 0); - -#if defined(CONFIG_PPC) - /* For some reason PPC gets upset when virt != phys for map-in... */ - virt = ofmem_claim_virt(phys, size, 0); -#else - virt = ofmem_claim_virt(-1, size, size); -#endif - - ofmem_map(phys, virt, size, ofmem_arch_io_translation_mode(phys)); - -#else - virt = size; /* Keep compiler quiet */ - virt = phys; -#endif - - PUSH(virt); -} - -NODE_METHODS(ob_pci_bus_node) = { - { NULL, ob_pci_initialize }, - { "open", ob_pci_open }, - { "close", ob_pci_close }, - { "decode-unit", ob_pci_decode_unit }, - { "encode-unit", ob_pci_encode_unit }, - { "pci-map-in", ob_pci_map_in }, -}; - -NODE_METHODS(ob_pci_simple_node) = { - { NULL, ob_pci_initialize }, - { "open", ob_pci_open }, - { "close", ob_pci_close }, -}; - -NODE_METHODS(ob_pci_empty_node) = { - { NULL, ob_pci_initialize } -}; - -static void pci_set_bus_range(const pci_config_t *config) -{ - phandle_t dev = find_dev(config->path); - u32 props[2]; - - props[0] = config->secondary_bus; - props[1] = config->subordinate_bus; - - PCI_DPRINTF("setting bus range for %s PCI device, " - "package handle " FMT_ucellx " " - "bus primary=%d secondary=%d subordinate=%d\n", - config->path, - dev, - config->primary_bus, - config->secondary_bus, - config->subordinate_bus); - - - set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0])); -} - -static void pci_host_set_reg(phandle_t phandle) -{ - phandle_t dev = phandle; - - /* at most 2 integers for address and size */ - u32 props[4]; - int ncells = 0; - - ncells += encode_int32_cells(host_address_cells(), props + ncells, - arch->cfg_base); - - ncells += encode_int32_cells(host_size_cells(), props + ncells, - arch->cfg_len); - - set_property(dev, "reg", (char *)props, ncells * sizeof(props[0])); - -#if defined(CONFIG_DEBUG_PCI) - dump_reg_property("pci_host_set_reg", 4, props); -#endif -} - -/* child-phys : parent-phys : size */ -/* 3 cells for PCI : 2 cells for 64bit parent : 2 cells for PCI */ - -static void pci_host_set_ranges(const pci_config_t *config) -{ - phandle_t dev = get_cur_dev(); - u32 props[32]; - int ncells; - - ncells = 0; - -#ifdef CONFIG_SPARC64 - /* While configuration space isn't mentioned in the IEEE-1275 PCI - bindings, it appears in the PCI host bridge ranges property in - real device trees. Hence we disable this range for all host - bridges except for SPARC, particularly as it causes Darwin/OS X - to incorrectly calculated PCI memory space ranges on PPC. */ - ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE, - config->dev, 0, 0); - ncells += host_encode_phys_addr(props + ncells, arch->cfg_addr); - ncells += pci_encode_size(props + ncells, arch->cfg_len); -#endif - - if (arch->io_base) { - ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE, - config->dev, 0, 0); - ncells += host_encode_phys_addr(props + ncells, arch->io_base); - ncells += pci_encode_size(props + ncells, arch->io_len); - } - if (arch->rbase) { - ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32, - config->dev, 0, 0); - ncells += host_encode_phys_addr(props + ncells, arch->rbase); - ncells += pci_encode_size(props + ncells, arch->rlen); - } - if (arch->pci_mem_base) { - ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32, - config->dev, 0, arch->pci_mem_base); - ncells += host_encode_phys_addr(props + ncells, arch->host_pci_base + - arch->pci_mem_base); - ncells += pci_encode_size(props + ncells, arch->mem_len); - } - set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0])); -} - -int host_config_cb(const pci_config_t *config) -{ - //XXX this overrides "reg" property - pci_host_set_reg(get_cur_dev()); - pci_host_set_ranges(config); - - return 0; -} - -static int sabre_configure(phandle_t dev) -{ - uint32_t props[28]; - - props[0] = 0xc0000000; - props[1] = 0x20000000; - set_property(dev, "virtual-dma", (char *)props, 2 * sizeof(props[0])); - props[0] = 1; - set_property(dev, "#virtual-dma-size-cells", (char *)props, - sizeof(props[0])); - set_property(dev, "#virtual-dma-addr-cells", (char *)props, - sizeof(props[0])); - - set_property(dev, "no-streaming-cache", (char *)props, 0); - - props[0] = 0x000007f0; - props[1] = 0x000007ee; - props[2] = 0x000007ef; - props[3] = 0x000007e5; - set_property(dev, "interrupts", (char *)props, 4 * sizeof(props[0])); - props[0] = 0x0000001f; - set_property(dev, "upa-portid", (char *)props, 1 * sizeof(props[0])); - return 0; -} - -int sabre_config_cb(const pci_config_t *config) -{ - host_config_cb(config); - - return sabre_configure(get_cur_dev()); -} - -int bridge_config_cb(const pci_config_t *config) -{ - phandle_t aliases; - - aliases = find_dev("/aliases"); - set_property(aliases, "bridge", config->path, strlen(config->path) + 1); - - return 0; -} - -int ide_config_cb2 (const pci_config_t *config) -{ - ob_ide_init(config->path, - config->assigned[0] & ~0x0000000F, - (config->assigned[1] & ~0x0000000F) + 2, - config->assigned[2] & ~0x0000000F, - (config->assigned[3] & ~0x0000000F) + 2); - return 0; -} - -int eth_config_cb (const pci_config_t *config) -{ - phandle_t ph = get_cur_dev(); - - set_property(ph, "network-type", "ethernet", 9); - set_property(ph, "removable", "network", 8); - set_property(ph, "category", "net", 4); - - return 0; -} - -static inline void pci_decode_pci_addr(pci_addr addr, int *flags, - int *space_code, uint32_t *mask) -{ - *flags = 0; - - if (addr & 0x01) { - *space_code = IO_SPACE; - *mask = 0x00000001; - } else { - if (addr & 0x04) { - *space_code = MEMORY_SPACE_64; - *flags |= IS_NOT_RELOCATABLE; /* XXX: why not relocatable? */ - } else { - *space_code = MEMORY_SPACE_32; - } - - if (addr & 0x08) { - *flags |= IS_PREFETCHABLE; - } - - *mask = 0x0000000F; - } -} - -/* - * "Designing PCI Cards and Drivers for Power Macintosh Computers", p. 454 - * - * "AAPL,address" provides an array of 32-bit logical addresses - * Nth entry corresponding to Nth "assigned-address" base address entry. - */ - -static void pci_set_AAPL_address(const pci_config_t *config) -{ - phandle_t dev = get_cur_dev(); - cell props[7]; - uint32_t mask; - int ncells, i, flags, space_code; - - ncells = 0; - for (i = 0; i < 6; i++) { - if (!config->assigned[i] || !config->sizes[i]) - continue; - pci_decode_pci_addr(config->assigned[i], - &flags, &space_code, &mask); - - props[ncells++] = pci_bus_addr_to_host_addr(space_code, - config->assigned[i] & ~mask); - } - if (ncells) - set_property(dev, "AAPL,address", (char *)props, - ncells * sizeof(cell)); -} - -static void pci_set_assigned_addresses(phandle_t phandle, - const pci_config_t *config, int num_bars) -{ - phandle_t dev = phandle; - u32 props[32]; - int ncells; - int i; - uint32_t mask; - int flags, space_code; - - ncells = 0; - for (i = 0; i < num_bars; i++) { - /* consider only bars with non-zero region size */ - if (!config->sizes[i]) - continue; - pci_decode_pci_addr(config->assigned[i], - &flags, &space_code, &mask); - - ncells += pci_encode_phys_addr(props + ncells, - flags, space_code, config->dev, - PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)), - config->assigned[i] & ~mask); - - props[ncells++] = 0x00000000; - props[ncells++] = config->sizes[i]; - } - if (ncells) - set_property(dev, "assigned-addresses", (char *)props, - ncells * sizeof(props[0])); -} - -/* call after writing "reg" property to update config->path */ -static void ob_pci_reload_device_path(phandle_t phandle, pci_config_t *config) -{ - /* since "name" and "reg" are now assigned - we need to reload current node name */ - - PUSH(phandle); - fword("get-package-path"); - char *new_path = pop_fstr_copy(); - if (new_path) { - if (0 != strcmp(config->path, new_path)) { - PCI_DPRINTF("\n=== CHANGED === package path old=%s new=%s\n", - config->path, new_path); - strncpy(config->path, new_path, sizeof(config->path)); - config->path[sizeof(config->path)-1] = '\0'; - } - free(new_path); - } else { - PCI_DPRINTF("\n=== package path old=%s new=NULL\n", config->path); - } -} - -static void pci_set_reg(phandle_t phandle, - pci_config_t *config, int num_bars) -{ - phandle_t dev = phandle; - u32 props[38]; - int ncells; - int i; - uint32_t mask; - int space_code, flags; - - ncells = 0; - - /* first (addr, size) pair is the beginning of configuration address space */ - ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE, - config->dev, 0, 0); - - ncells += pci_encode_size(props + ncells, 0); - - for (i = 0; i < num_bars; i++) { - /* consider only bars with non-zero region size */ - if (!config->sizes[i]) - continue; - - pci_decode_pci_addr(config->regions[i], - &flags, &space_code, &mask); - - ncells += pci_encode_phys_addr(props + ncells, - flags, space_code, config->dev, - PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)), - config->regions[i] & ~mask); - - /* set size */ - ncells += pci_encode_size(props + ncells, config->sizes[i]); - } - - set_property(dev, "reg", (char *)props, ncells * sizeof(props[0])); - ob_pci_reload_device_path(dev, config); - -#if defined(CONFIG_DEBUG_PCI) - dump_reg_property("pci_set_reg", ncells, props); -#endif -} - - -static void pci_set_ranges(const pci_config_t *config) -{ - phandle_t dev = get_cur_dev(); - u32 props[32]; - int ncells; - int i; - uint32_t mask; - int flags; - int space_code; - - ncells = 0; - for (i = 0; i < 6; i++) { - if (!config->assigned[i] || !config->sizes[i]) - continue; - - /* child address */ - - props[ncells++] = 0x00000000; - - /* parent address */ - - pci_decode_pci_addr(config->assigned[i], - &flags, &space_code, &mask); - ncells += pci_encode_phys_addr(props + ncells, flags, space_code, - config->dev, 0x10 + i * 4, - config->assigned[i] & ~mask); - - /* size */ - - props[ncells++] = config->sizes[i]; - } - set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0])); -} - -int macio_heathrow_config_cb (const pci_config_t *config) -{ - pci_set_ranges(config); - -#ifdef CONFIG_DRIVER_MACIO - ob_macio_heathrow_init(config->path, config->assigned[0] & ~0x0000000F); -#endif - return 0; -} - -int macio_keylargo_config_cb (const pci_config_t *config) -{ - pci_set_ranges(config); - -#ifdef CONFIG_DRIVER_MACIO - ob_macio_keylargo_init(config->path, config->assigned[0] & ~0x0000000F); -#endif - return 0; -} - -int vga_config_cb (const pci_config_t *config) -{ - unsigned long rom; - uint32_t rom_size, size, mask; - int flags, space_code; - phandle_t ph; - - if (config->assigned[0] != 0x00000000) { - setup_video(); - - pci_decode_pci_addr(config->assigned[1], - &flags, &space_code, &mask); - - rom = pci_bus_addr_to_host_addr(space_code, - config->assigned[1] & ~0x0000000F); - - rom_size = config->sizes[1]; - - ph = get_cur_dev(); - - if (rom_size >= 8) { - const char *p; - - p = (const char *)rom; - if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') { - size = *(uint32_t*)(p + 4); - set_property(ph, "driver,AAPL,MacOS,PowerPC", p + 8, size); - } - } - - /* Currently we don't read FCode from the hardware but execute it directly */ - feval("['] vga-driver-fcode 2 cells + 1 byte-load"); - -#ifdef CONFIG_MOL - /* Install special words for Mac On Linux */ - molvideo_init(); -#endif - - } - - return 0; -} - -int ebus_config_cb(const pci_config_t *config) -{ -#ifdef CONFIG_DRIVER_EBUS - phandle_t dev = get_cur_dev(); - uint32_t props[12]; - int ncells; - int i; - uint32_t mask; - int flags, space_code; - - props[0] = 0x14; - props[1] = 0x3f8; - props[2] = 1; - props[3] = find_dev("/"); - props[4] = 0x2b; - set_property(dev, "interrupt-map", (char *)props, 5 * sizeof(props[0])); - - props[0] = 0x000001ff; - props[1] = 0xffffffff; - props[2] = 3; - set_property(dev, "interrupt-map-mask", (char *)props, 3 * sizeof(props[0])); - - /* Build ranges property from the BARs */ - ncells = 0; - for (i = 0; i < 6; i++) { - /* consider only bars with non-zero region size */ - if (!config->sizes[i]) - continue; - - pci_decode_pci_addr(config->assigned[i], - &flags, &space_code, &mask); - - props[ncells++] = PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)); - props[ncells++] = 0x0; - - ncells += pci_encode_phys_addr(props + ncells, - flags, space_code, config->dev, - PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)), - config->assigned[i] & ~mask); - - props[ncells++] = config->sizes[i]; - } - - set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0])); - - /* Build eeprom node */ - fword("new-device"); - PUSH(0x14); - fword("encode-int"); - PUSH(0x2000); - fword("encode-int"); - fword("encode+"); - PUSH(0x2000); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - push_str("mk48t59"); - fword("model"); - - push_str("eeprom"); - fword("device-name"); - fword("finish-device"); - -#ifdef CONFIG_DRIVER_FLOPPY - ob_floppy_init(config->path, "fdthree", 0x3f0ULL, 0); -#endif -#ifdef CONFIG_DRIVER_PC_SERIAL - ob_pc_serial_init(config->path, "su", (PCI_BASE_ADDR_1 | 0ULL) << 32, 0x3f8ULL, 0); -#endif -#ifdef CONFIG_DRIVER_PC_KBD - ob_pc_kbd_init(config->path, "kb_ps2", (PCI_BASE_ADDR_1 | 0ULL) << 32, 0x60ULL, 0); -#endif -#endif - return 0; -} - -int i82378_config_cb(const pci_config_t *config) -{ -#ifdef CONFIG_DRIVER_PC_SERIAL - ob_pc_serial_init(config->path, "serial", arch->io_base, 0x3f8ULL, 0); -#endif -#ifdef CONFIG_DRIVER_PC_KBD - ob_pc_kbd_init(config->path, "8042", arch->io_base, 0x60ULL, 0); -#endif -#ifdef CONFIG_DRIVER_IDE - ob_ide_init(config->path, 0x1f0, 0x3f6, 0x170, 0x376); -#endif - - return 0; -} - -int usb_ohci_config_cb(const pci_config_t *config) -{ -#ifdef CONFIG_DRIVER_USB - ob_usb_ohci_init(config->path, 0x80000000 | config->dev); -#endif - return 0; -} - -static void ob_pci_add_properties(phandle_t phandle, - pci_addr addr, const pci_dev_t *pci_dev, - const pci_config_t *config, int num_bars) -{ - /* cannot use get_cur_dev() path resolution since "name" and "reg" - properties are being changed */ - phandle_t dev=phandle; - int status,id; - uint16_t vendor_id, device_id; - uint8_t rev; - uint8_t class_prog; - uint32_t class_code; - - vendor_id = pci_config_read16(addr, PCI_VENDOR_ID); - device_id = pci_config_read16(addr, PCI_DEVICE_ID); - rev = pci_config_read8(addr, PCI_REVISION_ID); - class_prog = pci_config_read8(addr, PCI_CLASS_PROG); - class_code = pci_config_read16(addr, PCI_CLASS_DEVICE); - - if (pci_dev) { - /**/ - if (pci_dev->name) { - push_str(pci_dev->name); - fword("encode-string"); - push_str("name"); - fword("property"); - } else { - char path[256]; - snprintf(path, sizeof(path), - "pci%x,%x", vendor_id, device_id); - push_str(path); - fword("encode-string"); - push_str("name"); - fword("property"); - } - } else { - PCI_DPRINTF("*** missing pci_dev\n"); - } - - /* create properties as described in 2.5 */ - - set_int_property(dev, "vendor-id", vendor_id); - set_int_property(dev, "device-id", device_id); - set_int_property(dev, "revision-id", rev); - set_int_property(dev, "class-code", class_code << 8 | class_prog); - - if (config->irq_pin) { - OLDWORLD(set_int_property(dev, "AAPL,interrupts", - config->irq_line)); -#if defined(CONFIG_SPARC64) - set_int_property(dev, "interrupts", config->irq_pin); -#else - NEWWORLD(set_int_property(dev, "interrupts", config->irq_pin)); -#endif - } - - set_int_property(dev, "min-grant", pci_config_read8(addr, PCI_MIN_GNT)); - set_int_property(dev, "max-latency", pci_config_read8(addr, PCI_MAX_LAT)); - - status=pci_config_read16(addr, PCI_STATUS); - - set_int_property(dev, "devsel-speed", - (status&PCI_STATUS_DEVSEL_MASK)>>10); - - if(status&PCI_STATUS_FAST_BACK) - set_bool_property(dev, "fast-back-to-back"); - if(status&PCI_STATUS_66MHZ) - set_bool_property(dev, "66mhz-capable"); - if(status&PCI_STATUS_UDF) - set_bool_property(dev, "udf-supported"); - - id=pci_config_read16(addr, PCI_SUBSYSTEM_VENDOR_ID); - if(id) - set_int_property(dev, "subsystem-vendor-id", id); - id=pci_config_read16(addr, PCI_SUBSYSTEM_ID); - if(id) - set_int_property(dev, "subsystem-id", id); - - set_int_property(dev, "cache-line-size", - pci_config_read16(addr, PCI_CACHE_LINE_SIZE)); - - if (pci_dev) { - if (pci_dev->type) { - push_str(pci_dev->type); - fword("encode-string"); - push_str("device_type"); - fword("property"); - } - if (pci_dev->model) { - push_str(pci_dev->model); - fword("encode-string"); - push_str("model"); - fword("property"); - } - if (pci_dev->compat) - set_property(dev, "compatible", - pci_dev->compat, pci_compat_len(pci_dev)); - - if (pci_dev->acells) - set_int_property(dev, "#address-cells", - pci_dev->acells); - if (pci_dev->scells) - set_int_property(dev, "#size-cells", - pci_dev->scells); - if (pci_dev->icells) - set_int_property(dev, "#interrupt-cells", - pci_dev->icells); - } - - pci_set_assigned_addresses(phandle, config, num_bars); - - if (is_apple()) { - pci_set_AAPL_address(config); - } - - PCI_DPRINTF("\n"); -} - -#ifdef CONFIG_XBOX -static char pci_xbox_blacklisted (int bus, int devnum, int fn) -{ - /* - * The Xbox MCPX chipset is a derivative of the nForce 1 - * chipset. It almost has the same bus layout; some devices - * cannot be used, because they have been removed. - */ - - /* - * Devices 00:00.1 and 00:00.2 used to be memory controllers on - * the nForce chipset, but on the Xbox, using them will lockup - * the chipset. - */ - if ((bus == 0) && (devnum == 0) && ((fn == 1) || (fn == 2))) - return 1; - - /* - * Bus 1 only contains a VGA controller at 01:00.0. When you try - * to probe beyond that device, you only get garbage, which - * could cause lockups. - */ - if ((bus == 1) && ((devnum != 0) || (fn != 0))) - return 1; - - /* - * Bus 2 used to contain the AGP controller, but the Xbox MCPX - * doesn't have one. Probing it can cause lockups. - */ - if (bus >= 2) - return 1; - - /* - * The device is not blacklisted. - */ - return 0; -} -#endif - -static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config, - int reg, int config_addr, - uint32_t *p_omask, - unsigned long *mem_base, - unsigned long *io_base) -{ - uint32_t smask, amask, size, reloc, min_align; - unsigned long base; - - config->assigned[reg] = 0x00000000; - config->sizes[reg] = 0x00000000; - - if ((*p_omask & 0x0000000f) == 0x4) { - /* 64 bits memory mapping */ - PCI_DPRINTF("Skipping 64 bit BARs for %s\n", config->path); - return; - } - - config->regions[reg] = pci_config_read32(addr, config_addr); - - /* get region size */ - - pci_config_write32(addr, config_addr, 0xffffffff); - smask = pci_config_read32(addr, config_addr); - if (smask == 0x00000000 || smask == 0xffffffff) - return; - - if (smask & 0x00000001 && reg != 6) { - /* I/O space */ - base = *io_base; - min_align = 1 << 7; - amask = 0x00000001; - } else { - /* Memory Space */ - base = *mem_base; - min_align = 1 << 16; - amask = 0x0000000F; - if (reg == 6) { - smask |= 1; /* ROM */ - } - } - *p_omask = smask & amask; - smask &= ~amask; - size = (~smask) + 1; - config->sizes[reg] = size; - reloc = base; - if (size < min_align) - size = min_align; - reloc = (reloc + size -1) & ~(size - 1); - if (*io_base == base) { - PCI_DPRINTF("changing io_base from 0x%lx to 0x%x\n", - *io_base, reloc + size); - *io_base = reloc + size; - } else { - PCI_DPRINTF("changing mem_base from 0x%lx to 0x%x\n", - *mem_base, reloc + size); - *mem_base = reloc + size; - } - PCI_DPRINTF("Configuring BARs for %s: reloc 0x%x omask 0x%x " - "io_base 0x%lx mem_base 0x%lx size 0x%x\n", - config->path, reloc, *p_omask, *io_base, *mem_base, size); - pci_config_write32(addr, config_addr, reloc | *p_omask); - config->assigned[reg] = reloc | *p_omask; -} - -static void ob_pci_configure_irq(pci_addr addr, pci_config_t *config) -{ - uint8_t irq_pin, irq_line; - - irq_pin = pci_config_read8(addr, PCI_INTERRUPT_PIN); - if (irq_pin) { - config->irq_pin = irq_pin; - irq_pin = (((config->dev >> 11) & 0x1F) + irq_pin - 1) & 3; - irq_line = arch->irqs[irq_pin]; - pci_config_write8(addr, PCI_INTERRUPT_LINE, irq_line); - config->irq_line = irq_line; - } else - config->irq_line = -1; -} - -static void -ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar, - unsigned long *mem_base, unsigned long *io_base) - -{ - uint32_t omask; - uint16_t cmd; - int reg; - pci_addr config_addr; - - ob_pci_configure_irq(addr, config); - - omask = 0x00000000; - for (reg = 0; reg < num_regs; ++reg) { - config_addr = PCI_BASE_ADDR_0 + reg * 4; - - ob_pci_configure_bar(addr, config, reg, config_addr, - &omask, mem_base, - io_base); - } - - if (rom_bar) { - config_addr = rom_bar; - ob_pci_configure_bar(addr, config, reg, config_addr, - &omask, mem_base, io_base); - } - cmd = pci_config_read16(addr, PCI_COMMAND); - cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; - pci_config_write16(addr, PCI_COMMAND, cmd); -} - -static void ob_configure_pci_device(const char* parent_path, - int *bus_num, unsigned long *mem_base, unsigned long *io_base, - int bus, int devnum, int fn, int *p_is_multi); - -static void ob_scan_pci_bus(int *bus_num, unsigned long *mem_base, - unsigned long *io_base, const char *path, - int bus) -{ - int devnum, fn, is_multi; - - PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path); - - for (devnum = 0; devnum < 32; devnum++) { - is_multi = 0; - for (fn = 0; fn==0 || (is_multi && fn<8); fn++) { - ob_configure_pci_device(path, bus_num, mem_base, io_base, - bus, devnum, fn, &is_multi); - - } - } -} - -static void ob_configure_pci_bridge(pci_addr addr, - int *bus_num, unsigned long *mem_base, - unsigned long *io_base, - int primary_bus, pci_config_t *config) -{ - config->primary_bus = primary_bus; - pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus); - - config->secondary_bus = *bus_num; - pci_config_write8(addr, PCI_SECONDARY_BUS, config->secondary_bus); - - config->subordinate_bus = 0xff; - pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus); - - PCI_DPRINTF("scanning new pci bus %u under bridge %s\n", - config->secondary_bus, config->path); - - /* make pci bridge parent device, prepare for recursion */ - - ob_scan_pci_bus(bus_num, mem_base, io_base, - config->path, config->secondary_bus); - - /* bus scan updates *bus_num to last revealed pci bus number */ - config->subordinate_bus = *bus_num; - pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus); - - PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n", - config->path, config->primary_bus, config->secondary_bus, - config->subordinate_bus); - - pci_set_bus_range(config); -} - -static int ob_pci_read_identification(int bus, int devnum, int fn, - int *p_vid, int *p_did, - uint8_t *p_class, uint8_t *p_subclass) -{ - int vid, did; - uint32_t ccode; - pci_addr addr; - -#ifdef CONFIG_XBOX - if (pci_xbox_blacklisted (bus, devnum, fn)) - return; -#endif - addr = PCI_ADDR(bus, devnum, fn); - vid = pci_config_read16(addr, PCI_VENDOR_ID); - did = pci_config_read16(addr, PCI_DEVICE_ID); - - if (vid==0xffff || vid==0) { - return 0; - } - - if (p_vid) { - *p_vid = vid; - } - - if (p_did) { - *p_did = did; - } - - ccode = pci_config_read16(addr, PCI_CLASS_DEVICE); - - if (p_class) { - *p_class = ccode >> 8; - } - - if (p_subclass) { - *p_subclass = ccode; - } - - return 1; -} - -static void ob_configure_pci_device(const char* parent_path, - int *bus_num, unsigned long *mem_base, unsigned long *io_base, - int bus, int devnum, int fn, int *p_is_multi) -{ - int vid, did; - unsigned int htype; - pci_addr addr; - pci_config_t config = {}; - const pci_dev_t *pci_dev; - uint8_t class, subclass, iface; - int num_bars, rom_bar; - - phandle_t phandle = 0; - int is_host_bridge = 0; - - if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) { - return; - } - - addr = PCI_ADDR(bus, devnum, fn); - iface = pci_config_read8(addr, PCI_CLASS_PROG); - - pci_dev = pci_find_device(class, subclass, iface, - vid, did); - - PCI_DPRINTF("%x:%x.%x - %x:%x - ", bus, devnum, fn, - vid, did); - - htype = pci_config_read8(addr, PCI_HEADER_TYPE); - - if (fn == 0) { - if (p_is_multi) { - *p_is_multi = htype & 0x80; - } - } - - /* stop adding host bridge accessible from it's primary bus - PCI host bridge is to be added by host code - */ - if (class == PCI_BASE_CLASS_BRIDGE && - subclass == PCI_SUBCLASS_BRIDGE_HOST) { - is_host_bridge = 1; - } - - if (is_host_bridge) { - /* reuse device tree node */ - PCI_DPRINTF("host bridge found - "); - snprintf(config.path, sizeof(config.path), - "%s", parent_path); - } else if (pci_dev == NULL || pci_dev->name == NULL) { - snprintf(config.path, sizeof(config.path), - "%s/pci%x,%x", parent_path, vid, did); - } - else { - snprintf(config.path, sizeof(config.path), - "%s/%s", parent_path, pci_dev->name); - } - - PCI_DPRINTF("%s - ", config.path); - - config.dev = addr & 0x00FFFFFF; - - switch (class) { - case PCI_BASE_CLASS_BRIDGE: - if (subclass != PCI_SUBCLASS_BRIDGE_HOST) { - REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle); - } - break; - case PCI_CLASS_DISPLAY: - REGISTER_NAMED_NODE_PHANDLE(ob_pci_empty_node, config.path, phandle); - break; - default: - REGISTER_NAMED_NODE_PHANDLE(ob_pci_simple_node, config.path, phandle); - break; - } - - if (is_host_bridge) { - phandle = find_dev(config.path); - - if (get_property(phandle, "vendor-id", NULL)) { - PCI_DPRINTF("host bridge already configured\n"); - return; - } - } - - activate_dev(phandle); - - if (htype & PCI_HEADER_TYPE_BRIDGE) { - num_bars = 2; - rom_bar = PCI_ROM_ADDRESS1; - } else { - num_bars = 6; - rom_bar = PCI_ROM_ADDRESS; - } - - ob_pci_configure(addr, &config, num_bars, rom_bar, - mem_base, io_base); - - ob_pci_add_properties(phandle, addr, pci_dev, &config, num_bars); - - if (!is_host_bridge) { - pci_set_reg(phandle, &config, num_bars); - } - - /* call device-specific configuration callback */ - if (pci_dev && pci_dev->config_cb) { - //activate_device(config.path); - pci_dev->config_cb(&config); - } - - /* device is configured so we may move it out of scope */ - device_end(); - - /* scan bus behind bridge device */ - //if (htype & PCI_HEADER_TYPE_BRIDGE && class == PCI_BASE_CLASS_BRIDGE) { - if ( class == PCI_BASE_CLASS_BRIDGE && - ( subclass == PCI_SUBCLASS_BRIDGE_PCI || - subclass == PCI_SUBCLASS_BRIDGE_HOST ) ) { - - if (subclass == PCI_SUBCLASS_BRIDGE_PCI) { - /* reserve next pci bus number for this PCI bridge */ - ++(*bus_num); - } - - ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config); - } -} - -static void ob_pci_set_available(phandle_t host, unsigned long mem_base, unsigned long io_base) -{ - /* Create an available property for both memory and IO space */ - uint32_t props[10]; - int ncells; - - ncells = 0; - ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32, 0, 0, mem_base); - ncells += pci_encode_size(props + ncells, arch->mem_len - mem_base); - ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE, 0, 0, io_base); - ncells += pci_encode_size(props + ncells, arch->io_len - io_base); - - set_property(host, "available", (char *)props, ncells * sizeof(props[0])); -} - -/* Convert device/irq pin to interrupt property */ -#define SUN4U_INTERRUPT(dev, irq_pin) \ - ((((dev >> 11) << 2) + irq_pin - 1) & 0x1f) - -static void ob_pci_host_set_interrupt_map(phandle_t host) -{ - phandle_t dnode = 0, pci_childnode = 0; - u32 props[128], intno; - int i, ncells, len; - u32 *val, addr; - char *reg; - -#if defined(CONFIG_PPC) - phandle_t target_node; - - /* Oldworld macs do interrupt maps differently */ - if (!is_newworld()) - return; - - dnode = dt_iterate_type(0, "open-pic"); - if (dnode) { - /* patch in openpic interrupt-parent properties */ - target_node = find_dev("/pci/mac-io"); - set_int_property(target_node, "interrupt-parent", dnode); - - target_node = find_dev("/pci/mac-io/escc/ch-a"); - set_int_property(target_node, "interrupt-parent", dnode); - - target_node = find_dev("/pci/mac-io/escc/ch-b"); - set_int_property(target_node, "interrupt-parent", dnode); - - target_node = find_dev("/pci/mac-io/escc-legacy/ch-a"); - set_int_property(target_node, "interrupt-parent", dnode); - - target_node = find_dev("/pci/mac-io/escc-legacy/ch-b"); - set_int_property(target_node, "interrupt-parent", dnode); - - /* QEMU only emulates 2 of the 3 ata buses currently */ - /* On a new world Mac these are not numbered but named by the - * ATA version they support. Thus we have: ata-3, ata-3, ata-4 - * On g3beige they all called just ide. - * We take 2 x ata-3 buses which seems to work for - * at least the clients we care about */ - target_node = find_dev("/pci/mac-io/ata-3@20000"); - set_int_property(target_node, "interrupt-parent", dnode); - - target_node = find_dev("/pci/mac-io/ata-3@21000"); - set_int_property(target_node, "interrupt-parent", dnode); - - target_node = find_dev("/pci/mac-io/via-cuda"); - set_int_property(target_node, "interrupt-parent", dnode); - - target_node = find_dev("/pci"); - set_int_property(target_node, "interrupt-parent", dnode); - } -#else - /* PCI host bridge is the default interrupt controller */ - dnode = host; -#endif - - /* Set interrupt-map for PCI devices with an interrupt pin present */ - ncells = 0; - - PUSH(host); - fword("child"); - pci_childnode = POP(); - while (pci_childnode) { - intno = get_int_property(pci_childnode, "interrupts", &len); - if (len && intno) { - reg = get_property(pci_childnode, "reg", &len); - if (len && reg) { - val = (u32 *)reg; - - for (i = 0; i < (len / sizeof(u32)); i += 5) { - addr = val[i]; - - /* Device address is in 1st 32-bit word of encoded PCI address for config space */ - if ((addr & PCI_RANGE_TYPE_MASK) == PCI_RANGE_CONFIG) { -#if defined(CONFIG_SPARC64) - ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0); - props[ncells++] = intno; - props[ncells++] = dnode; - props[ncells++] = SUN4U_INTERRUPT(addr, intno); -#elif defined(CONFIG_PPC) - ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0); - props[ncells++] = intno; - props[ncells++] = dnode; - props[ncells++] = arch->irqs[intno - 1]; - props[ncells++] = 3; -#else - /* Keep compiler quiet */ - dnode = dnode; -#endif - } - } - } - } - - PUSH(pci_childnode); - fword("peer"); - pci_childnode = POP(); - } - set_property(host, "interrupt-map", (char *)props, ncells * sizeof(props[0])); - - props[0] = 0x0000f800; - props[1] = 0x0; - props[2] = 0x0; - props[3] = 0x7; - set_property(host, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0])); -} - -int ob_pci_init(void) -{ - int bus, devnum, fn; - uint8_t class, subclass; - unsigned long mem_base, io_base; - - pci_config_t config = {}; /* host bridge */ - phandle_t phandle_host = 0; - - PCI_DPRINTF("Initializing PCI host bridge...\n"); - - activate_device("/"); - - /* Find all PCI bridges */ - - mem_base = arch->pci_mem_base; - /* I/O ports under 0x400 are used by devices mapped at fixed - location. */ - io_base = 0x400; - - bus = 0; - - for (devnum = 0; devnum < 32; devnum++) { - /* scan only fn 0 */ - fn = 0; - - if (!ob_pci_read_identification(bus, devnum, fn, - 0, 0, &class, &subclass)) { - continue; - } - - if (class != PCI_BASE_CLASS_BRIDGE || subclass != PCI_SUBCLASS_BRIDGE_HOST) { - continue; - } - - /* create root node for host PCI bridge */ - - /* configure */ - snprintf(config.path, sizeof(config.path), "/pci"); - - REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle_host); - - pci_host_set_reg(phandle_host); - - /* update device path after changing "reg" property */ - ob_pci_reload_device_path(phandle_host, &config); - - ob_configure_pci_device(config.path, &bus, &mem_base, &io_base, - bus, devnum, fn, 0); - - /* we expect single host PCI bridge - but this may be machine-specific */ - break; - } - - /* create available attributes for the PCI bridge */ - ob_pci_set_available(phandle_host, mem_base, io_base); - - /* configure the host bridge interrupt map */ - ob_pci_host_set_interrupt_map(phandle_host); - - device_end(); - - return 0; -} diff --git a/qemu/roms/openbios/drivers/pci.fs b/qemu/roms/openbios/drivers/pci.fs deleted file mode 100644 index a7b56e1f8..000000000 --- a/qemu/roms/openbios/drivers/pci.fs +++ /dev/null @@ -1,40 +0,0 @@ -[IFDEF] CONFIG_DRIVER_PCI - -: pci-addr-encode ( addr.lo addr.mi addr.hi ) - rot >r swap >r - encode-int - r> encode-int encode+ - r> encode-int encode+ - ; - -: pci-len-encode ( len.lo len.hi ) - encode-int - rot encode-int encode+ - ; - -\ Get PCI physical address and size for configured BAR reg -: pci-bar>pci-addr ( bar-reg -- addr.lo addr.mid addr.hi size -1 | 0 ) - " assigned-addresses" active-package get-package-property 0= if - begin - decode-phys \ ( reg prop prop-len phys.lo phys.mid phys.hi ) - dup ff and 6 pick = if - >r >r >r rot drop - decode-int drop decode-int - -rot 2drop - r> swap r> r> rot - -1 exit - else - 3drop - then - \ Drop the size as we don't need it - decode-int drop decode-int drop - dup 0= - until - 3drop - 0 exit - else - 0 - then - ; - -[THEN] diff --git a/qemu/roms/openbios/drivers/pci.h b/qemu/roms/openbios/drivers/pci.h deleted file mode 100644 index d5aa5f84a..000000000 --- a/qemu/roms/openbios/drivers/pci.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef PCI_H -#define PCI_H - -#define PCI_VENDOR_ID 0x00 -#define PCI_DEVICE_ID 0x02 - -#define PCI_COMMAND 0x04 -#define PCI_COMMAND_IO 0x01 -#define PCI_COMMAND_MEMORY 0x02 -#define PCI_COMMAND_BUS_MASTER 0x04 - -#define PCI_STATUS 0x06 /* 16 bits */ -#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */ -#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ -#define PCI_STATUS_UDF 0x40 /* Support User Definable Features - [obsolete] */ -#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ -#define PCI_STATUS_PARITY 0x100 /* Detected parity error */ -#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */ -#define PCI_STATUS_DEVSEL_FAST 0x000 -#define PCI_STATUS_DEVSEL_MEDIUM 0x200 -#define PCI_STATUS_DEVSEL_SLOW 0x400 -#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */ -#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */ -#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */ -#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */ -#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */ - - -#define PCI_REVISION_ID 0x08 /* Revision ID */ -#define PCI_CLASS_DISPLAY 0x03 -#define PCI_CLASS_PROG 0x09 -#define PCI_CLASS_DEVICE 0x0a -#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ -#define PCI_HEADER_TYPE 0x0e -#define PCI_HEADER_TYPE_NORMAL 0x00 -#define PCI_HEADER_TYPE_BRIDGE 0x01 -#define PCI_HEADER_TYPE_CARDBUS 0x02 -#define PCI_PRIMARY_BUS 0x18 -#define PCI_SECONDARY_BUS 0x19 -#define PCI_SUBORDINATE_BUS 0x1A -#define PCI_BASE_ADDR_0 0x10 -#define PCI_BASE_ADDR_1 0x14 -#define PCI_BASE_ADDR_2 0x18 -#define PCI_BASE_ADDR_3 0x1c -#define PCI_BASE_ADDR_4 0x20 -#define PCI_BASE_ADDR_5 0x24 - -#define PCI_SUBSYSTEM_VENDOR_ID 0x2c -#define PCI_SUBSYSTEM_ID 0x2e - -#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */ -#define PCI_ROM_ADDRESS_ENABLE 0x01 -#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) -#define PCI_ROM_ADDRESS1 0x38 /* ROM_ADDRESS in bridge header */ - -#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ -#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ -#define PCI_MIN_GNT 0x3e /* 8 bits */ -#define PCI_MAX_LAT 0x3f /* 8 bits */ - -#define PCI_RANGE_RELOCATABLE 0x80000000 -#define PCI_RANGE_PREFETCHABLE 0x40000000 -#define PCI_RANGE_ALIASED 0x20000000 -#define PCI_RANGE_TYPE_MASK 0x03000000 -#define PCI_RANGE_MMIO_64BIT 0x03000000 -#define PCI_RANGE_MMIO 0x02000000 -#define PCI_RANGE_IOPORT 0x01000000 -#define PCI_RANGE_CONFIG 0x00000000 - -typedef struct { - u16 signature; - u8 reserved[0x16]; - u16 dptr; -} rom_header_t; - -typedef struct { - u32 signature; - u16 vendor; - u16 device; - u16 reserved_1; - u16 dlen; - u8 drevision; - u8 class_hi; - u16 class_lo; - u16 ilen; - u16 irevision; - u8 type; - u8 indicator; - u16 reserved_2; -} pci_data_t; - - -#include "asm/pci.h" - -#endif /* PCI_H */ diff --git a/qemu/roms/openbios/drivers/pci_database.c b/qemu/roms/openbios/drivers/pci_database.c deleted file mode 100644 index 0070a78ba..000000000 --- a/qemu/roms/openbios/drivers/pci_database.c +++ /dev/null @@ -1,1275 +0,0 @@ -#include "config.h" -#include "libopenbios/bindings.h" -#include "drivers/pci.h" -#include "libc/vsprintf.h" - -#include "pci_database.h" - -/* PCI devices database */ - -typedef struct pci_class_t pci_class_t; -typedef struct pci_subclass_t pci_subclass_t; -typedef struct pci_iface_t pci_iface_t; - -struct pci_iface_t { - uint8_t iface; - const char *name; - const char *type; - const pci_dev_t *devices; - int (*config_cb)(const pci_config_t *config); - const void *private; -}; - -struct pci_subclass_t { - uint8_t subclass; - const char *name; - const char *type; - const pci_dev_t *devices; - const pci_iface_t *iface; - int (*config_cb)(const pci_config_t *config); - const void *private; -}; - -struct pci_class_t { - const char *name; - const char *type; - const pci_subclass_t *subc; -}; - -/* Current machine description */ - -static const pci_subclass_t undef_subclass[] = { - { - 0xFF, NULL, NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_dev_t scsi_devices[] = { - { - /* Virtio-block controller */ - PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_BLOCK, - NULL, "virtio-blk", NULL, - "pci1af4,1001\0pci1af4,1001\0pciclass,01018f\0", - 0, 0, 0, - NULL, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_dev_t ide_devices[] = { - { - PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, /* CMD646 IDE controller */ - "pci-ide", "pci-ata", NULL, - "pci1095,646\0pci1095,646\0pciclass,01018f\0", - 0, 0, 0, - ide_config_cb2, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_subclass_t mass_subclass[] = { - { - PCI_SUBCLASS_STORAGE_SCSI, "SCSI bus controller", - "scsi", scsi_devices, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_STORAGE_IDE, "IDE controller", - "ide", ide_devices, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_STORAGE_FLOPPY, "Floppy disk controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_STORAGE_IPI, "IPI bus controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_STORAGE_RAID, "RAID controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_STORAGE_ATA, "ATA controller", - "ata", NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_STORAGE_OTHER, "misc mass-storage controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_dev_t eth_devices[] = { - { - PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_RTL8029, - NULL, "NE2000", "NE2000 PCI", NULL, - 0, 0, 0, - NULL, "ethernet", - }, - { - /* Virtio-network controller */ - PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_NET, - NULL, "virtio-net", NULL, - "pci1af4,1000\0pci1af4,1000\0pciclass,020000\0", - 0, 0, 0, - NULL, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_subclass_t net_subclass[] = { - { - PCI_SUBCLASS_NETWORK_ETHERNET, "ethernet controller", - NULL, eth_devices, NULL, - eth_config_cb, "ethernet", - }, - { - PCI_SUBCLASS_NETWORK_TOKEN_RING, "token ring controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_NETWORK_FDDI, "FDDI controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_NETWORK_ATM, "ATM controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_NETWORK_ISDN, "ISDN controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_NETWORK_WORDFIP, "WordFip controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_NETWORK_PICMG214, "PICMG 2.14 controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_NETWORK_OTHER, "misc network controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_dev_t vga_devices[] = { - { - PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF, - NULL, "ATY", "ATY Rage128", "VGA\0", - 0, 0, 0, - NULL, NULL, - }, - { - PCI_VENDOR_ID_QEMU, PCI_DEVICE_ID_QEMU_VGA, - NULL, "QEMU,VGA", "Qemu VGA", "VGA\0", - 0, 0, 0, - NULL, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const struct pci_iface_t vga_iface[] = { - { - 0x00, "VGA controller", NULL, - vga_devices, &vga_config_cb, NULL, - }, - { - 0x01, "8514 compatible controller", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_subclass_t displ_subclass[] = { - { - PCI_SUBCLASS_DISPLAY_VGA, "display controller", - NULL, NULL, vga_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_DISPLAY_XGA, "XGA display controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_DISPLAY_3D, "3D display controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_DISPLAY_OTHER, "misc display controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t media_subclass[] = { - { - PCI_SUBCLASS_MULTIMEDIA_VIDEO, "video device", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_MULTIMEDIA_AUDIO, "audio device", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_MULTIMEDIA_PHONE, "computer telephony device", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_MULTIMEDIA_OTHER, "misc multimedia device", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t mem_subclass[] = { - { - PCI_SUBCLASS_MEMORY_RAM, "RAM controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_MEMORY_FLASH, "flash controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - - -static const pci_dev_t hbrg_devices[] = { - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U3_AGP, NULL, - "pci", "AAPL,UniNorth", "u3-agp\0", - 3, 2, 1, - host_config_cb, NULL, - }, - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_AGP, NULL, - "pci", "AAPL,UniNorth", "uni-north\0", - 3, 2, 1, - host_config_cb, NULL, - }, - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI, NULL, - "pci", "AAPL,UniNorth", "uni-north\0", - 3, 2, 1, - host_config_cb, NULL, - }, - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI, NULL, - "pci", "AAPL,UniNorth", "uni-north\0", - 3, 2, 1, - NULL, NULL - }, - { - PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_MPC106, "pci", - "pci", "MOT,MPC106", "grackle\0", - 3, 2, 1, - host_config_cb, NULL - }, - { - PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_RAVEN, NULL, - "pci", "PREP Host PCI Bridge - Motorola Raven", NULL, - 3, 2, 1, - host_config_cb, NULL, - }, - { - PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SABRE, NULL, - "pci", "SUNW,sabre", "pci108e,a000\0pciclass,0\0", - 3, 2, 1, - sabre_config_cb, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_dev_t PCIbrg_devices[] = { - { - PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21154, NULL, - "pci-bridge", "DEV,21154", "DEV,21154\0pci-bridge\0", - 3, 2, 1, - bridge_config_cb, NULL, - }, - { - PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA, NULL, - "pci", "SUNW,simba", "pci108e,5000\0pciclass,060400\0", - 3, 2, 1, - bridge_config_cb, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_dev_t miscbrg_devices[] = { - { - PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL, - "ebus", "ebus", "pci108e,1000\0pciclass,068000\0", - 2, 1, 1, - ebus_config_cb, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_dev_t isabrg_devices[] = { - { - PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, NULL, - "isa", "isa", "pci8086,484\0", - 1, 1, 1, - i82378_config_cb, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_subclass_t bridg_subclass[] = { - { - PCI_SUBCLASS_BRIDGE_HOST, "PCI host bridge", - "pci", hbrg_devices, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_ISA, "ISA bridge", - "isa", isabrg_devices, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_EISA, "EISA bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_MC, "MCA bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_PCI, "PCI-to-PCI bridge", - "pci", PCIbrg_devices, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_PCMCIA, "PCMCIA bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_NUBUS, "NUBUS bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_CARDBUS, "cardbus bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_RACEWAY, "raceway bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_PCI_SEMITP, "semi-transparent PCI-to-PCI bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_IB_PCI, "infiniband-to-PCI bridge", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_BRIDGE_OTHER, "misc PCI bridge", - NULL, miscbrg_devices, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_iface_t serial_iface[] = { - { - 0x00, "XT serial controller", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "16450 serial controller", NULL, - NULL, NULL, NULL, - }, - { - 0x02, "16550 serial controller", NULL, - NULL, NULL, NULL, - }, - { - 0x03, "16650 serial controller", NULL, - NULL, NULL, NULL, - }, - { - 0x04, "16750 serial controller", NULL, - NULL, NULL, NULL, - }, - { - 0x05, "16850 serial controller", NULL, - NULL, NULL, NULL, - }, - { - 0x06, "16950 serial controller", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_iface_t par_iface[] = { - { - 0x00, "parallel port", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "bi-directional parallel port", NULL, - NULL, NULL, NULL, - }, - { - 0x02, "ECP 1.x parallel port", NULL, - NULL, NULL, NULL, - }, - { - 0x03, "IEEE 1284 controller", NULL, - NULL, NULL, NULL, - }, - { - 0xFE, "IEEE 1284 device", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_iface_t modem_iface[] = { - { - 0x00, "generic modem", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "Hayes 16450 modem", NULL, - NULL, NULL, NULL, - }, - { - 0x02, "Hayes 16550 modem", NULL, - NULL, NULL, NULL, - }, - { - 0x03, "Hayes 16650 modem", NULL, - NULL, NULL, NULL, - }, - { - 0x04, "Hayes 16750 modem", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_subclass_t comm_subclass[] = { - { - PCI_SUBCLASS_COMMUNICATION_SERIAL, "serial controller", - NULL, NULL, serial_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_COMMUNICATION_PARALLEL, "parallel port", - NULL, NULL, par_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_COMMUNICATION_MULTISERIAL, "multiport serial controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_COMMUNICATION_MODEM, "modem", - NULL, NULL, modem_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_COMMUNICATION_GPIB, "GPIB controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_COMMUNICATION_SC, "smart card", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_COMMUNICATION_OTHER, "misc communication device", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_iface_t pic_iface[] = { - { - 0x00, "8259 PIC", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "ISA PIC", NULL, - NULL, NULL, NULL, - }, - { - 0x02, "EISA PIC", NULL, - NULL, NULL, NULL, - }, - { - 0x10, "I/O APIC", NULL, - NULL, NULL, NULL, - }, - { - 0x20, "I/O APIC", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_iface_t dma_iface[] = { - { - 0x00, "8237 DMA controller", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "ISA DMA controller", NULL, - NULL, NULL, NULL, - }, - { - 0x02, "EISA DMA controller", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_iface_t tmr_iface[] = { - { - 0x00, "8254 system timer", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "ISA system timer", NULL, - NULL, NULL, NULL, - }, - { - 0x02, "EISA system timer", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_iface_t rtc_iface[] = { - { - 0x00, "generic RTC controller", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "ISA RTC controller", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_dev_t sys_devices[] = { - /* IBM MPIC controller */ - { - PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OPENPIC, - "open-pic", "MPIC", NULL, "chrp,open-pic\0", - 0, 0, 2, - NULL, NULL, - }, - /* IBM MPIC2 controller */ - { - PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OPENPIC2, - "open-pic", "MPIC2", NULL, "chrp,open-pic\0", - 0, 0, 2, - NULL, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_subclass_t sys_subclass[] = { - { - PCI_SUBCLASS_SYSTEM_PIC, "PIC", - NULL, NULL, pic_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_SYSTEM_DMA, "DMA controller", - NULL, NULL, dma_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_SYSTEM_TIMER, "system timer", - NULL, NULL, tmr_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_SYSTEM_RTC, "RTC controller", - NULL, NULL, rtc_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_SYSTEM_PCI_HOTPLUG, "PCI hotplug controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SYSTEM_OTHER, "misc system peripheral", - NULL, sys_devices, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t inp_subclass[] = { - { - PCI_SUBCLASS_INPUT_KEYBOARD, "keyboard controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_INPUT_PEN, "digitizer", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_INPUT_MOUSE, "mouse controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_INPUT_SCANNER, "scanner controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_INPUT_GAMEPORT, "gameport controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_INPUT_OTHER, "misc input device", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t dock_subclass[] = { - { - PCI_SUBCLASS_DOCKING_GENERIC, "generic docking station", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_DOCKING_OTHER, "misc docking station", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t cpu_subclass[] = { - { - PCI_SUBCLASS_PROCESSOR_386, "i386 processor", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_PROCESSOR_486, "i486 processor", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_PROCESSOR_PENTIUM, "pentium processor", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_PROCESSOR_ALPHA, "alpha processor", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_PROCESSOR_POWERPC, "PowerPC processor", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_PROCESSOR_MIPS, "MIPS processor", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_PROCESSOR_CO, "co-processor", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_dev_t usb_devices[] = { -#if defined(CONFIG_QEMU) - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_KEYL_USB, - "usb", "usb", NULL, - "pci106b,3f\0pciclass,0c0310\0", - 1, 0, 0, - NULL, NULL, - }, -#endif - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -static const pci_iface_t usb_iface[] = { - { - 0x00, "UHCI USB controller", NULL, - NULL, NULL, NULL, - }, - { - 0x10, "OHCI USB controller", NULL, - usb_devices, &usb_ohci_config_cb, NULL, - }, - { - 0x20, "EHCI USB controller", NULL, - NULL, NULL, NULL, - }, - { - 0x80, "misc USB controller", NULL, - NULL, NULL, NULL, - }, - { - 0xFE, "USB device", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_iface_t ipmi_iface[] = { - { - 0x00, "IPMI SMIC interface", NULL, - NULL, NULL, NULL, - }, - { - 0x01, "IPMI keyboard interface", NULL, - NULL, NULL, NULL, - }, - { - 0x02, "IPMI block transfer interface", NULL, - NULL, NULL, NULL, - }, - { - 0xFF, NULL, NULL, - NULL, NULL, NULL, - }, -}; - -static const pci_subclass_t ser_subclass[] = { - { - PCI_SUBCLASS_SERIAL_FIREWIRE, "Firewire bus controller", - "ieee1394", NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_ACCESS, "ACCESS bus controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_SSA, "SSA controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_USB, "USB controller", - "usb", NULL, usb_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_FIBER, "fibre channel controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_SMBUS, "SMBus controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_IB, "InfiniBand controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_IPMI, "IPMI interface", - NULL, NULL, ipmi_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_SERCOS, "SERCOS controller", - NULL, NULL, ipmi_iface, - NULL, NULL, - }, - { - PCI_SUBCLASS_SERIAL_CANBUS, "CANbus controller", - NULL, NULL, ipmi_iface, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t wrl_subclass[] = { - { - PCI_SUBCLASS_WIRELESS_IRDA, "IRDA controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_WIRELESS_CIR, "consumer IR controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_WIRELESS_RF_CONTROLLER, "RF controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_WIRELESS_BLUETOOTH, "bluetooth controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_WIRELESS_BROADBAND, "broadband controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_WIRELESS_OTHER, "misc wireless controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t sat_subclass[] = { - { - PCI_SUBCLASS_SATELLITE_TV, "satellite TV controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SATELLITE_AUDIO, "satellite audio controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SATELLITE_VOICE, "satellite voice controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SATELLITE_DATA, "satellite data controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t crypt_subclass[] = { - { - PCI_SUBCLASS_CRYPT_NETWORK, "cryptographic network controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_CRYPT_ENTERTAINMENT, - "cryptographic entertainment controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_CRYPT_OTHER, "misc cryptographic controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_subclass_t spc_subclass[] = { - { - PCI_SUBCLASS_SP_DPIO, "DPIO module", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SP_PERF, "performances counters", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SP_SYNCH, "communication synchronisation", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SP_MANAGEMENT, "management card", - NULL, NULL, NULL, - NULL, NULL, - }, - { - PCI_SUBCLASS_SP_OTHER, "misc signal processing controller", - NULL, NULL, NULL, - NULL, NULL, - }, - { - 0xFF, NULL, - NULL, NULL, NULL, - NULL, NULL, - }, -}; - -static const pci_class_t pci_classes[] = { - /* 0x00 */ - { "undefined", NULL, undef_subclass, }, - /* 0x01 */ - { "mass-storage controller", NULL, mass_subclass, }, - /* 0x02 */ - { "network controller", "network", net_subclass, }, - /* 0x03 */ - { "display controller", "display", displ_subclass, }, - /* 0x04 */ - { "multimedia device", NULL, media_subclass, }, - /* 0x05 */ - { "memory controller", "memory-controller", mem_subclass, }, - /* 0x06 */ - { "PCI bridge", NULL, bridg_subclass, }, - /* 0x07 */ - { "communication device", NULL, comm_subclass,}, - /* 0x08 */ - { "system peripheral", NULL, sys_subclass, }, - /* 0x09 */ - { "input device", NULL, inp_subclass, }, - /* 0x0A */ - { "docking station", NULL, dock_subclass, }, - /* 0x0B */ - { "processor", NULL, cpu_subclass, }, - /* 0x0C */ - { "serial bus controller", NULL, ser_subclass, }, - /* 0x0D */ - { "wireless controller", NULL, wrl_subclass, }, - /* 0x0E */ - { "intelligent I/O controller", NULL, NULL, }, - /* 0x0F */ - { "satellite communication controller", NULL, sat_subclass, }, - /* 0x10 */ - { "cryptographic controller", NULL, crypt_subclass, }, - /* 0x11 */ - { "signal processing controller", NULL, spc_subclass, }, -}; - -static const pci_dev_t misc_pci[] = { - /* Heathrow Mac I/O */ - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_343S1201, - "mac-io", "mac-io", "AAPL,343S1201", "heathrow\0", - 1, 1, 1, - &macio_heathrow_config_cb, NULL, - }, - /* Paddington Mac I/O */ - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_343S1211, - "mac-io", "mac-io", "AAPL,343S1211", "paddington\0heathrow\0", - 1, 1, 1, - &macio_heathrow_config_cb, NULL, - }, - /* KeyLargo Mac I/O */ - { - PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, - "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo\0", - 1, 1, 1, - &macio_keylargo_config_cb, NULL, - }, - { - 0xFFFF, 0xFFFF, - NULL, NULL, NULL, NULL, - -1, -1, -1, - NULL, NULL, - }, -}; - -const pci_dev_t *pci_find_device (uint8_t class, uint8_t subclass, - uint8_t iface, uint16_t vendor, - uint16_t product) -{ - int (*config_cb)(const pci_config_t *config); - const pci_class_t *pclass; - const pci_subclass_t *psubclass; - const pci_iface_t *piface; - const pci_dev_t *dev; - const void *private; - pci_dev_t *new; - const char *name, *type; - - name = "unknown"; - type = "unknown"; - config_cb = NULL; - private = NULL; - - if (class == 0x00 && subclass == 0x01) { - /* Special hack for old style VGA devices */ - class = 0x03; - subclass = 0x00; - } else if (class == 0xFF) { - /* Special case for misc devices */ - dev = misc_pci; - goto find_device; - } - if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) { - name = "invalid PCI device"; - type = "invalid"; - goto bad_device; - } - pclass = &pci_classes[class]; - name = pclass->name; - type = pclass->type; - for (psubclass = pclass->subc; ; psubclass++) { - if (psubclass->subclass == 0xFF) - goto bad_device; - if (psubclass->subclass == subclass) { - if (psubclass->name != NULL) - name = psubclass->name; - if (psubclass->type != NULL) - type = psubclass->type; - if (psubclass->config_cb != NULL) { - config_cb = psubclass->config_cb; - } - if (psubclass->private != NULL) - private = psubclass->private; - if (psubclass->iface != NULL) - break; - dev = psubclass->devices; - goto find_device; - } - } - for (piface = psubclass->iface; ; piface++) { - if (piface->iface == 0xFF) { - dev = psubclass->devices; - break; - } - if (piface->iface == iface) { - if (piface->name != NULL) - name = piface->name; - if (piface->type != NULL) - type = piface->type; - if (piface->config_cb != NULL) { - config_cb = piface->config_cb; - } - if (piface->private != NULL) - private = piface->private; - dev = piface->devices; - break; - } - } -find_device: - if (dev == NULL) - goto bad_device; - for (;; dev++) { - if (dev->vendor == 0xFFFF && dev->product == 0xFFFF) { - goto bad_device; - } - if (dev->vendor == vendor && dev->product == product) { - if (dev->name != NULL) - name = dev->name; - if (dev->type != NULL) - type = dev->type; - if (dev->config_cb != NULL) { - config_cb = dev->config_cb; - } - if (dev->private != NULL) - private = dev->private; - new = malloc(sizeof(pci_dev_t)); - if (new == NULL) - return NULL; - new->vendor = vendor; - new->product = product; - new->type = type; - new->name = name; - new->model = dev->model; - new->compat = dev->compat; - new->acells = dev->acells; - new->scells = dev->scells; - new->icells = dev->icells; - new->config_cb = config_cb; - new->private = private; - - return new; - } - } -bad_device: - printk("Cannot manage '%s' PCI device type '%s':\n %x %x (%x %x %x)\n", - name, type, vendor, product, class, subclass, iface); - - return NULL; -} diff --git a/qemu/roms/openbios/drivers/pci_database.h b/qemu/roms/openbios/drivers/pci_database.h deleted file mode 100644 index 7f053d808..000000000 --- a/qemu/roms/openbios/drivers/pci_database.h +++ /dev/null @@ -1,57 +0,0 @@ -typedef struct pci_config_t pci_config_t; - -struct pci_config_t { - char path[256]; - uint32_t dev; /* bus, dev, fn */ - uint32_t regions[7]; - uint32_t assigned[7]; - uint32_t sizes[7]; - int irq_pin; - int irq_line; - u32 primary_bus; - u32 secondary_bus; - u32 subordinate_bus; -}; - -typedef struct pci_dev_t pci_dev_t; -struct pci_dev_t { - uint16_t vendor; - uint16_t product; - const char *type; - const char *name; - const char *model; - const char *compat; - int acells; - int scells; - int icells; - int (*config_cb)(const pci_config_t *config); - const void *private; -}; - -extern int ide_config_cb2(const pci_config_t *config); -extern int eth_config_cb(const pci_config_t *config); -extern int macio_heathrow_config_cb(const pci_config_t *config); -extern int macio_keylargo_config_cb(const pci_config_t *config); -extern int vga_config_cb(const pci_config_t *config); -extern int host_config_cb(const pci_config_t *config); -extern int sabre_config_cb(const pci_config_t *config); -extern int bridge_config_cb(const pci_config_t *config); -extern int ebus_config_cb(const pci_config_t *config); -extern int i82378_config_cb(const pci_config_t *config); -extern int usb_ohci_config_cb(const pci_config_t *config); - -static inline int pci_compat_len(const pci_dev_t *dev) -{ - int len, ret; - const char *path = dev->compat; - ret = 0; - while ((len = strlen(path)) != 0) { - ret += len + 1; - path += len + 1; - } - return ret; -} - -extern const pci_dev_t *pci_find_device(uint8_t class, uint8_t subclass, - uint8_t iface, uint16_t vendor, - uint16_t product); diff --git a/qemu/roms/openbios/drivers/sbus.c b/qemu/roms/openbios/drivers/sbus.c deleted file mode 100644 index 4caa59aaf..000000000 --- a/qemu/roms/openbios/drivers/sbus.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * OpenBIOS SBus driver - * - * (C) 2004 Stefan Reinauer - * (C) 2005 Ed Schouten - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "kernel/kernel.h" -#include "libc/byteorder.h" -#include "libc/vsprintf.h" -#include "drivers/drivers.h" -#include "libopenbios/ofmem.h" -#include "libopenbios/video.h" - -#define SBUS_REGS 0x28 -#define SBUS_SLOTS 16 -#define APC_REGS 0x10 -#define APC_OFFSET 0x0a000000ULL -#define CS4231_REGS 0x40 -#define CS4231_OFFSET 0x0c000000ULL -#define MACIO_ESPDMA 0x00400000ULL /* ESP DMA controller */ -#define MACIO_ESP 0x00800000ULL /* ESP SCSI */ -#define SS600MP_ESPDMA 0x00081000ULL -#define SS600MP_ESP 0x00080000ULL -#define SS600MP_LEBUFFER (SS600MP_ESPDMA + 0x10) // XXX should be 0x40000 -#define LEDMA_REGS 0x4 -#define LE_REGS 0x20 - -#ifdef CONFIG_DEBUG_SBUS -#define DPRINTF(fmt, args...) \ - do { printk(fmt , ##args); } while (0) -#else -#define DPRINTF(fmt, args...) -#endif - -typedef struct le_private { - uint32_t *dmaregs; - uint32_t *regs; -} le_private_t; - -static void -ob_sbus_node_init(uint64_t base) -{ - void *regs; - - push_str("/iommu/sbus"); - fword("find-device"); - - PUSH(base >> 32); - fword("encode-int"); - PUSH(base & 0xffffffff); - fword("encode-int"); - fword("encode+"); - PUSH(SBUS_REGS); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - regs = (void *)ofmem_map_io(base, SBUS_REGS); - PUSH((unsigned long)regs); - fword("encode-int"); - push_str("address"); - fword("property"); -} - -static void -ob_le_init(unsigned int slot, uint64_t base, unsigned long leoffset, unsigned long dmaoffset) -{ - le_private_t *le; - - le = malloc(sizeof(le_private_t)); - if (!le) { - DPRINTF("Can't allocate LANCE private structure\n"); - return; - } - - /* Get the IO region for DMA registers */ - le->dmaregs = (void *)ofmem_map_io(base + (uint64_t)dmaoffset, LEDMA_REGS); - if (le->dmaregs == NULL) { - DPRINTF("Can't map LANCE DMA registers\n"); - return; - } - - /* Now it appears that the Solaris kernel forgets to set up the LANCE DMA mapping - and so it must inherit the one from OpenBIOS. The symptom of this is that the - LANCE DMA base addr register is still zero, and so we start sending network - packets containing random areas of memory. - - The correct fix for this should be to use dvma_alloc() to grab a section of - memory and point the LANCE DMA buffers to use that instead; this gets - slightly further but still crashes. Time-consuming investigation on various - hacked versions of QEMU seems to indicate that Solaris always assumes the LANCE - DMA base address is fixed 0xff000000 when setting up the IOMMU for the LANCE - card. Hence we imitate this behaviour here. */ - le->dmaregs[3] = 0xff000000; - - push_str("/iommu/sbus/ledma"); - fword("find-device"); - PUSH(slot); - fword("encode-int"); - PUSH(dmaoffset); - fword("encode-int"); - fword("encode+"); - PUSH(0x00000020); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - /* Get the IO region for Lance registers */ - le->regs = (void *)ofmem_map_io(base + (uint64_t)leoffset, LE_REGS); - if (le->regs == NULL) { - DPRINTF("Can't map LANCE registers\n"); - return; - } - - push_str("/iommu/sbus/ledma/le"); - fword("find-device"); - PUSH(slot); - fword("encode-int"); - PUSH(leoffset); - fword("encode-int"); - fword("encode+"); - PUSH(0x00000004); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); -} - -uint16_t graphic_depth; - -static void -ob_tcx_init(unsigned int slot, const char *path) -{ - char buf[6]; - - printk("No display device located during SBus probe - falling back to internal TCX driver\n"); - - /* Make the sbus node the current instance and active package for probing */ - feval("active-package my-self"); - push_str("/iommu/sbus"); - feval("2dup find-device open-dev to my-self"); - - fword("new-device"); - PUSH(0); - PUSH(0); - snprintf(buf, 6, "%x,0", slot); - push_str(buf); - fword("set-args"); - feval("['] tcx-driver-fcode 2 cells + 1 byte-load"); - fword("finish-device"); - - /* Restore */ - feval("to my-self active-package!"); -} - -static void -ob_apc_init(unsigned int slot, unsigned long base) -{ - push_str("/iommu/sbus"); - fword("find-device"); - fword("new-device"); - - push_str("power-management"); - fword("device-name"); - - PUSH(slot); - fword("encode-int"); - PUSH(base); - fword("encode-int"); - fword("encode+"); - PUSH(APC_REGS); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - fword("finish-device"); -} - -static void -ob_cs4231_init(unsigned int slot) -{ - push_str("/iommu/sbus"); - fword("find-device"); - fword("new-device"); - - push_str("SUNW,CS4231"); - fword("device-name"); - - push_str("serial"); - fword("device-type"); - - PUSH(slot); - fword("encode-int"); - PUSH(CS4231_OFFSET); - fword("encode-int"); - fword("encode+"); - PUSH(CS4231_REGS); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - PUSH(5); - fword("encode-int"); - PUSH(0); - fword("encode-int"); - fword("encode+"); - push_str("intr"); - fword("property"); - - PUSH(5); - fword("encode-int"); - push_str("interrupts"); - fword("property"); - - push_str("audio"); - fword("encode-string"); - push_str("alias"); - fword("property"); - - fword("finish-device"); -} - -static void -ob_macio_init(unsigned int slot, uint64_t base, unsigned long offset) -{ - // All devices were integrated to NCR89C100, see - // http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt - - // NCR 53c9x, aka ESP. See - // http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt -#ifdef CONFIG_DRIVER_ESP - ob_esp_init(slot, base, offset + MACIO_ESP, offset + MACIO_ESPDMA); -#endif - - // NCR 92C990, Am7990, Lance. See http://www.amd.com - ob_le_init(slot, base, offset + 0x00c00000, offset + 0x00400010); - - // Parallel port - //ob_bpp_init(base); -} - -static void -sbus_probe_self(unsigned int slot, unsigned long offset) -{ - /* Wrapper for calling probe-self in Forth. This is mainly because some - drivers don't handle properties correctly when the sbus node is set - as the current instance during probe. */ - char buf[6]; - - printk("Probing SBus slot %d offset %ld\n", slot, offset); - - /* Make the sbus node the current instance and active package for probing */ - feval("active-package my-self"); - push_str("/iommu/sbus"); - feval("open-dev to my-self"); - - PUSH(0); - PUSH(0); - snprintf(buf, 6, "%x,%lx", slot, offset); - push_str(buf); - fword("2dup"); - fword("probe-self-sbus"); - - /* Restore */ - feval("to my-self active-package!"); -} - -static int -sbus_probe_sucess(void) -{ - /* Return true if the last sbus_probe_self() resulted in - the successful detection and execution of FCode */ - fword("probe-fcode?"); - return POP(); -} - -static void -sbus_probe_slot_ss5(unsigned int slot, uint64_t base) -{ - /* Probe the slot */ - sbus_probe_self(slot, 0); - - /* If the device was successfully created by FCode then do nothing */ - if (sbus_probe_sucess()) { - return; - } - - switch(slot) { - case 3: // SUNW,tcx - ob_tcx_init(slot, "/iommu/sbus/SUNW,tcx"); - break; - case 4: - // SUNW,CS4231 - ob_cs4231_init(slot); - // Power management (APC) - ob_apc_init(slot, APC_OFFSET); - break; - case 5: // MACIO: le, esp, bpp - ob_macio_init(slot, base, 0x08000000); - break; - default: - break; - } -} - -static void -sbus_probe_slot_ss10(unsigned int slot, uint64_t base) -{ - /* Probe the slot */ - sbus_probe_self(slot, 0); - - /* If the device was successfully created by FCode then do nothing */ - if (sbus_probe_sucess()) { - return; - } - - switch(slot) { - case 2: // SUNW,tcx - ob_tcx_init(slot, "/iommu/sbus/SUNW,tcx"); - break; - case 0xf: // le, esp, bpp, power-management - ob_macio_init(slot, base, 0); - // Power management (APC) XXX should not exist - ob_apc_init(slot, APC_OFFSET); - break; - default: - break; - } -} - -static void -sbus_probe_slot_ss600mp(unsigned int slot, uint64_t base) -{ - /* Probe the slot */ - sbus_probe_self(slot, 0); - - /* If the device was successfully created by FCode then do nothing */ - if (sbus_probe_sucess()) { - return; - } - - switch(slot) { - case 2: // SUNW,tcx - ob_tcx_init(slot, "/iommu/sbus/SUNW,tcx"); - break; - case 0xf: // le, esp, bpp, power-management -#ifdef CONFIG_DRIVER_ESP - ob_esp_init(slot, base, SS600MP_ESP, SS600MP_ESPDMA); -#endif - // NCR 92C990, Am7990, Lance. See http://www.amd.com - ob_le_init(slot, base, 0x00060000, SS600MP_LEBUFFER); - // Power management (APC) XXX should not exist - ob_apc_init(slot, APC_OFFSET); - break; - default: - break; - } -} - -struct sbus_offset { - int slot, type; - uint64_t base; - unsigned long size; -}; - -static const struct sbus_offset sbus_offsets_ss5[SBUS_SLOTS] = { - { 0, 0, 0x20000000, 0x10000000,}, - { 1, 0, 0x30000000, 0x10000000,}, - { 2, 0, 0x40000000, 0x10000000,}, - { 3, 0, 0x50000000, 0x10000000,}, - { 4, 0, 0x60000000, 0x10000000,}, - { 5, 0, 0x70000000, 0x10000000,}, -}; - -/* Shared with ss600mp */ -static const struct sbus_offset sbus_offsets_ss10[SBUS_SLOTS] = { - { 0, 0, 0xe00000000ULL, 0x10000000,}, - { 1, 0, 0xe10000000ULL, 0x10000000,}, - { 2, 0, 0xe20000000ULL, 0x10000000,}, - { 3, 0, 0xe30000000ULL, 0x10000000,}, - [0xf] = { 0xf, 0, 0xef0000000ULL, 0x10000000,}, -}; - -static void -ob_add_sbus_range(const struct sbus_offset *range, int notfirst) -{ - if (!notfirst) { - push_str("/iommu/sbus"); - fword("find-device"); - } - PUSH(range->slot); - fword("encode-int"); - if (notfirst) - fword("encode+"); - PUSH(range->type); - fword("encode-int"); - fword("encode+"); - PUSH(range->base >> 32); - fword("encode-int"); - fword("encode+"); - PUSH(range->base & 0xffffffff); - fword("encode-int"); - fword("encode+"); - PUSH(range->size); - fword("encode-int"); - fword("encode+"); -} - -static int -ob_sbus_init_ss5(void) -{ - unsigned int slot; - int notfirst = 0; - - for (slot = 0; slot < SBUS_SLOTS; slot++) { - if (sbus_offsets_ss5[slot].size > 0) - ob_add_sbus_range(&sbus_offsets_ss5[slot], notfirst++); - } - push_str("ranges"); - fword("property"); - - for (slot = 0; slot < SBUS_SLOTS; slot++) { - if (sbus_offsets_ss5[slot].size > 0) - sbus_probe_slot_ss5(slot, sbus_offsets_ss5[slot].base); - } - - return 0; -} - -static int -ob_sbus_init_ss10(void) -{ - unsigned int slot; - int notfirst = 0; - - for (slot = 0; slot < SBUS_SLOTS; slot++) { - if (sbus_offsets_ss10[slot].size > 0) - ob_add_sbus_range(&sbus_offsets_ss10[slot], notfirst++); - } - push_str("ranges"); - fword("property"); - - for (slot = 0; slot < SBUS_SLOTS; slot++) { - if (sbus_offsets_ss10[slot].size > 0) - sbus_probe_slot_ss10(slot, sbus_offsets_ss10[slot].base); - } - - return 0; -} - -static int -ob_sbus_init_ss600mp(void) -{ - unsigned int slot; - int notfirst = 0; - - for (slot = 0; slot < SBUS_SLOTS; slot++) { - if (sbus_offsets_ss10[slot].size > 0) - ob_add_sbus_range(&sbus_offsets_ss10[slot], notfirst++); - } - push_str("ranges"); - fword("property"); - - for (slot = 0; slot < SBUS_SLOTS; slot++) { - if (sbus_offsets_ss10[slot].size > 0) - sbus_probe_slot_ss600mp(slot, sbus_offsets_ss10[slot].base); - } - - return 0; -} - -int ob_sbus_init(uint64_t base, int machine_id) -{ - ob_sbus_node_init(base); - - switch (machine_id) { - case 66: - return ob_sbus_init_ss600mp(); - case 64 ... 65: - return ob_sbus_init_ss10(); - case 32 ... 63: - return ob_sbus_init_ss5(); - default: - return -1; - } -} diff --git a/qemu/roms/openbios/drivers/sbus.fs b/qemu/roms/openbios/drivers/sbus.fs deleted file mode 100644 index b84a3ac72..000000000 --- a/qemu/roms/openbios/drivers/sbus.fs +++ /dev/null @@ -1,94 +0,0 @@ -\ ------------------------------------------------------------------------- -\ SBus encode/decode unit -\ ------------------------------------------------------------------------- - -: decode-unit-sbus ( str len -- id lun ) - ascii , left-split - ( addr-R len-R addr-L len-L ) - parse-hex - -rot parse-hex - swap -; - -: encode-unit-sbus ( id lun -- str len) - swap - pocket tohexstr - " ," pocket tmpstrcat >r - rot pocket tohexstr r> tmpstrcat drop -; - -\ Convert sbus unit (from decode-unit) to physical address using -\ sbus node ranges property - -: sbus-unit>addr ( phys.lo phys.hi -- phys.lo phys.hi -1 | 0 ) - " ranges" my-self ihandle>phandle - get-package-property 0= if ( phys.lo phys.hi prop prop-len ) - begin - 2over swap drop 0 swap \ force phys.lo to zero for matching - 2swap ( unit.phys.lo unit.phys.hi 0 phys.hi res prop prop-len ) - 0 -rot ( unit.phys.lo unit.phys.hi res prop prop-len ) - 2 0 do - decode-int -rot >r >r ( unit.phys.lo unit.phys.hi res phys.x -- R: prop-len prop ) - rot ( unit.phys.lo res phys.x phys.hi ) - = if - 1+ - then ( unit.phys.lo res ) - r> r> ( unit.phys.lo res prop prop-len ) - loop - rot ( prop prop-len res ) - 2 = if \ did we match the unit address? if so, return the physical address - decode-phys 2swap 2drop 2swap ( unit.phys.lo unit.phys.hi phys.lo phys.hi ) - drop 0 d+ \ force unit.phys.hi to zero and add address for final offset - -1 exit - else - decode-phys 2drop decode-int drop \ drop the size and carry on - then - dup 0= until - 2drop 2drop 0 - then -; - -: map-in-sbus ( phys.lo phys.hi size ) - >r sbus-unit>addr if - r@ " map-in" $call-parent - then - r> drop -; - -: map-out-sbus ( virt size ) - " map-out" $call-parent -; - -\ ------------------------------------------------------------------------- -\ SBus probe -\ ------------------------------------------------------------------------- - -: probe-self-sbus ( arg-adr arg-len reg-adr reg-len fcode-adr fcode-len -- ) - - 0 to probe-fcode? - - ['] decode-unit-sbus catch if - 2drop 2drop 2drop 2drop - exit - then - - h# 10000 map-in-sbus - - dup cpeek if - dup h# f1 = swap h# fd = or if - new-device - >r set-args r> - dup 1 byte-load - finish-device - - -1 to probe-fcode? - else - nip nip nip nip - ." Invalid FCode start byte" cr - then - else - nip nip nip nip - then - - h# 10000 map-out-sbus -; diff --git a/qemu/roms/openbios/drivers/scsi.h b/qemu/roms/openbios/drivers/scsi.h deleted file mode 100644 index cb975fc70..000000000 --- a/qemu/roms/openbios/drivers/scsi.h +++ /dev/null @@ -1,262 +0,0 @@ -#ifndef _LINUX_SCSI_H -#define _LINUX_SCSI_H - -/* - * This header file contains public constants and structures used by - * the scsi code for linux. - */ - -/* - $Header: /usr/src/linux/include/linux/RCS/scsi.h,v 1.3 1993/09/24 12:20:33 drew Exp $ - - For documentation on the OPCODES, MESSAGES, and SENSE values, - please consult the SCSI standard. - -*/ - -/* - * SCSI opcodes - */ - -#define TEST_UNIT_READY 0x00 -#define REZERO_UNIT 0x01 -#define REQUEST_SENSE 0x03 -#define FORMAT_UNIT 0x04 -#define READ_BLOCK_LIMITS 0x05 -#define REASSIGN_BLOCKS 0x07 -#define READ_6 0x08 -#define WRITE_6 0x0a -#define SEEK_6 0x0b -#define READ_REVERSE 0x0f -#define WRITE_FILEMARKS 0x10 -#define SPACE 0x11 -#define INQUIRY 0x12 -#define RECOVER_BUFFERED_DATA 0x14 -#define MODE_SELECT 0x15 -#define RESERVE 0x16 -#define RELEASE 0x17 -#define COPY 0x18 -#define ERASE 0x19 -#define MODE_SENSE 0x1a -#define START_STOP 0x1b -#define RECEIVE_DIAGNOSTIC 0x1c -#define SEND_DIAGNOSTIC 0x1d -#define ALLOW_MEDIUM_REMOVAL 0x1e - -#define SET_WINDOW 0x24 -#define READ_CAPACITY 0x25 -#define READ_10 0x28 -#define WRITE_10 0x2a -#define SEEK_10 0x2b -#define WRITE_VERIFY 0x2e -#define VERIFY 0x2f -#define SEARCH_HIGH 0x30 -#define SEARCH_EQUAL 0x31 -#define SEARCH_LOW 0x32 -#define SET_LIMITS 0x33 -#define PRE_FETCH 0x34 -#define READ_POSITION 0x34 -#define SYNCHRONIZE_CACHE 0x35 -#define LOCK_UNLOCK_CACHE 0x36 -#define READ_DEFECT_DATA 0x37 -#define MEDIUM_SCAN 0x38 -#define COMPARE 0x39 -#define COPY_VERIFY 0x3a -#define WRITE_BUFFER 0x3b -#define READ_BUFFER 0x3c -#define UPDATE_BLOCK 0x3d -#define READ_LONG 0x3e -#define WRITE_LONG 0x3f -#define CHANGE_DEFINITION 0x40 -#define WRITE_SAME 0x41 -#define READ_TOC 0x43 -#define LOG_SELECT 0x4c -#define LOG_SENSE 0x4d -#define MODE_SELECT_10 0x55 -#define RESERVE_10 0x56 -#define RELEASE_10 0x57 -#define MODE_SENSE_10 0x5a -#define PERSISTENT_RESERVE_IN 0x5e -#define PERSISTENT_RESERVE_OUT 0x5f -#define REPORT_LUNS 0xa0 -#define MOVE_MEDIUM 0xa5 -#define READ_12 0xa8 -#define WRITE_12 0xaa -#define WRITE_VERIFY_12 0xae -#define SEARCH_HIGH_12 0xb0 -#define SEARCH_EQUAL_12 0xb1 -#define SEARCH_LOW_12 0xb2 -#define READ_ELEMENT_STATUS 0xb8 -#define SEND_VOLUME_TAG 0xb6 -#define WRITE_LONG_2 0xea -#define READ_16 0x88 -#define WRITE_16 0x8a -#define VERIFY_16 0x8f -#define SERVICE_ACTION_IN 0x9e -/* values for service action in */ -#define SAI_READ_CAPACITY_16 0x10 - -#define SCSI_RETRY_10(c) ((c) == READ_6 || (c) == WRITE_6 || (c) == SEEK_6) - -/* - * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft - * T10/1561-D Revision 4 Draft dated 7th November 2002. - */ -#define SAM_STAT_GOOD 0x00 -#define SAM_STAT_CHECK_CONDITION 0x02 -#define SAM_STAT_CONDITION_MET 0x04 -#define SAM_STAT_BUSY 0x08 -#define SAM_STAT_INTERMEDIATE 0x10 -#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14 -#define SAM_STAT_RESERVATION_CONFLICT 0x18 -#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ -#define SAM_STAT_TASK_SET_FULL 0x28 -#define SAM_STAT_ACA_ACTIVE 0x30 -#define SAM_STAT_TASK_ABORTED 0x40 - -/* - * Status codes - */ - -#define GOOD 0x00 -#define CHECK_CONDITION 0x01 -#define CONDITION_GOOD 0x02 -#define BUSY 0x04 -#define INTERMEDIATE_GOOD 0x08 -#define INTERMEDIATE_C_GOOD 0x0a -#define RESERVATION_CONFLICT 0x0c -#define COMMAND_TERMINATED 0x11 -#define QUEUE_FULL 0x14 - -#define STATUS_MASK 0x3e - -/* - * SENSE KEYS - */ - -#define NO_SENSE 0x00 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define MEDIUM_ERROR 0x03 -#define HARDWARE_ERROR 0x04 -#define ILLEGAL_REQUEST 0x05 -#define UNIT_ATTENTION 0x06 -#define DATA_PROTECT 0x07 -#define BLANK_CHECK 0x08 -#define COPY_ABORTED 0x0a -#define ABORTED_COMMAND 0x0b -#define VOLUME_OVERFLOW 0x0d -#define MISCOMPARE 0x0e - - -/* - * DEVICE TYPES - */ - -#define TYPE_DISK 0x00 -#define TYPE_TAPE 0x01 -#define TYPE_PRINTER 0x02 -#define TYPE_PROCESSOR 0x03 /* HP scanners use this */ -#define TYPE_WORM 0x04 /* Treated as ROM by our system */ -#define TYPE_ROM 0x05 -#define TYPE_SCANNER 0x06 -#define TYPE_MOD 0x07 /* Magneto-optical disk - - * - treated as TYPE_DISK */ -#define TYPE_MEDIUM_CHANGER 0x08 -#define TYPE_COMM 0x09 /* Communications device */ -#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ -#define TYPE_NO_LUN 0x7f - -/* - * standard mode-select header prepended to all mode-select commands - * - * moved here from cdrom.h -- kraxel - */ - -struct ccs_modesel_head -{ - uint8_t _r1; /* reserved */ - uint8_t medium; /* device-specific medium type */ - uint8_t _r2; /* reserved */ - uint8_t block_desc_length; /* block descriptor length */ - uint8_t density; /* device-specific density code */ - uint8_t number_blocks_hi; /* number of blocks in this block desc */ - uint8_t number_blocks_med; - uint8_t number_blocks_lo; - uint8_t _r3; - uint8_t block_length_hi; /* block length for blocks in this desc */ - uint8_t block_length_med; - uint8_t block_length_lo; -}; - -/* - * MESSAGE CODES - */ - -#define COMMAND_COMPLETE 0x00 -#define EXTENDED_MESSAGE 0x01 -#define EXTENDED_MODIFY_DATA_POINTER 0x00 -#define EXTENDED_SDTR 0x01 -#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ -#define EXTENDED_WDTR 0x03 -#define SAVE_POINTERS 0x02 -#define RESTORE_POINTERS 0x03 -#define DISCONNECT 0x04 -#define INITIATOR_ERROR 0x05 -#define ABORT 0x06 -#define MESSAGE_REJECT 0x07 -#define NOP 0x08 -#define MSG_PARITY_ERROR 0x09 -#define LINKED_CMD_COMPLETE 0x0a -#define LINKED_FLG_CMD_COMPLETE 0x0b -#define BUS_DEVICE_RESET 0x0c - -#define INITIATE_RECOVERY 0x0f /* SCSI-II only */ -#define RELEASE_RECOVERY 0x10 /* SCSI-II only */ - -#define SIMPLE_QUEUE_TAG 0x20 -#define HEAD_OF_QUEUE_TAG 0x21 -#define ORDERED_QUEUE_TAG 0x22 - -/* - * Here are some scsi specific ioctl commands which are sometimes useful. - */ -/* These are a few other constants only used by scsi devices */ -/* Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395 */ - -#define SCSI_IOCTL_GET_IDLUN 0x5382 /* conflicts with CDROMAUDIOBUFSIZ */ - -/* Used to turn on and off tagged queuing for scsi devices */ - -#define SCSI_IOCTL_TAGGED_ENABLE 0x5383 -#define SCSI_IOCTL_TAGGED_DISABLE 0x5384 - -/* Used to obtain the host number of a device. */ -#define SCSI_IOCTL_PROBE_HOST 0x5385 - -/* Used to get the bus number for a device */ -#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 - -/* Used to get the PCI location of a device */ -#define SCSI_IOCTL_GET_PCI 0x5387 - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ - -#endif diff --git a/qemu/roms/openbios/drivers/tcx.fs b/qemu/roms/openbios/drivers/tcx.fs deleted file mode 100644 index af8991fd0..000000000 --- a/qemu/roms/openbios/drivers/tcx.fs +++ /dev/null @@ -1,280 +0,0 @@ -\ -\ Fcode payload for QEMU TCX graphics card -\ -\ This is the Forth source for an Fcode payload to initialise -\ the QEMU TCX graphics card. -\ -\ (C) Copyright 2013 Mark Cave-Ayland -\ - -fcode-version3 - -\ -\ Instead of using fixed values for the framebuffer address and the width -\ and height, grab the ones passed in by QEMU/generated by OpenBIOS -\ - -: (find-xt) \ ( str len -- xt | -1 ) - $find if - exit - else - 2drop - -1 - then -; - -: (is-openbios) \ ( -- true | false ) - " openbios-video-width" (find-xt) -1 <> if - -1 - else - 0 - then -; - -" openbios-video-width" (find-xt) cell+ value openbios-video-width-xt -" openbios-video-height" (find-xt) cell+ value openbios-video-height-xt -" depth-bits" (find-xt) cell+ value depth-bits-xt -" line-bytes" (find-xt) cell+ value line-bytes-xt - -: openbios-video-width - (is-openbios) if - openbios-video-width-xt @ - else - h# 400 - then -; - -: openbios-video-height - (is-openbios) if - openbios-video-height-xt @ - else - h# 300 - then -; - -: depth-bits - (is-openbios) if - depth-bits-xt @ - else - h# 8 - then -; - -: line-bytes - (is-openbios) if - line-bytes-xt @ - else - h# 400 - then -; - -\ -\ Registers -\ - -h# 0 constant tcx-off-rom -h# 10000 constant /tcx-off-rom - -h# 200000 constant tcx-off-cmap -h# 4000 constant /tcx-off-cmap-24 -h# 4 constant /tcx-off-cmap-8 - -h# 240000 constant tcx-off-dhc -h# 4000 constant /tcx-off-dhc-24 -h# 4 constant /tcx-off-dhc-8 - -h# 280000 constant tcx-off-alt -h# 8000 constant /tcx-off-alt-24 -h# 1 constant /tcx-off-alt-8 - -h# 301000 constant tcx-off-thc-24 -h# 300000 constant tcx-off-thc-8 -h# 1000 constant /tcx-off-thc-24 -h# 81c constant /tcx-off-thc-8 - -h# 701000 constant tcx-off-tec -h# 1000 constant /tcx-off-tec - -h# 800000 constant tcx-off-dfb8 -h# 100000 constant /tcx-off-dfb8 - -h# 2000000 constant tcx-off-dfb24 -h# 400000 constant /tcx-off-dfb24-24 -h# 1 constant /tcx-off-dfb24-8 - -h# 4000000 constant tcx-off-stip -h# 800000 constant /tcx-off-stip - -h# 6000000 constant tcx-off-blit -h# 800000 constant /tcx-off-blit - -h# a000000 constant tcx-off-rdfb32 -h# 400000 constant /tcx-off-rdfb32-24 -h# 1 constant /tcx-off-rdfb32-8 - -h# c000000 constant tcx-off-rstip -h# 800000 constant /tcx-off-rstip-24 -h# 1 constant /tcx-off-rstip-8 - -h# e000000 constant tcx-off-rblit -h# 800000 constant /tcx-off-rblit-24 -h# 1 constant /tcx-off-rblit-8 - -: >tcx-reg-spec ( offset size -- encoded-reg ) - >r 0 my-address d+ my-space encode-phys r> encode-int encode+ -; - -: tcx-8bit-reg - \ WARNING: order is important (at least to Solaris) - tcx-off-dfb8 /tcx-off-dfb8 >tcx-reg-spec - tcx-off-dfb24 /tcx-off-dfb24-8 >tcx-reg-spec encode+ - tcx-off-stip /tcx-off-stip >tcx-reg-spec encode+ - tcx-off-blit /tcx-off-blit >tcx-reg-spec encode+ - tcx-off-rdfb32 /tcx-off-rdfb32-8 >tcx-reg-spec encode+ - tcx-off-rstip /tcx-off-rstip-8 >tcx-reg-spec encode+ - tcx-off-rblit /tcx-off-rblit-8 >tcx-reg-spec encode+ - tcx-off-tec /tcx-off-tec >tcx-reg-spec encode+ - tcx-off-cmap /tcx-off-cmap-8 >tcx-reg-spec encode+ - tcx-off-thc-8 /tcx-off-thc-8 >tcx-reg-spec encode+ - tcx-off-rom /tcx-off-rom >tcx-reg-spec encode+ - tcx-off-dhc /tcx-off-dhc-8 >tcx-reg-spec encode+ - tcx-off-alt /tcx-off-alt-8 >tcx-reg-spec encode+ - " reg" property -; - -: tcx-24bit-reg - \ WARNING: order is important (at least to Solaris) - tcx-off-dfb8 /tcx-off-dfb8 >tcx-reg-spec - tcx-off-dfb24 /tcx-off-dfb24-24 >tcx-reg-spec encode+ - tcx-off-stip /tcx-off-stip >tcx-reg-spec encode+ - tcx-off-blit /tcx-off-blit >tcx-reg-spec encode+ - tcx-off-rdfb32 /tcx-off-rdfb32-24 >tcx-reg-spec encode+ - tcx-off-rstip /tcx-off-rstip-24 >tcx-reg-spec encode+ - tcx-off-rblit /tcx-off-rblit-24 >tcx-reg-spec encode+ - tcx-off-tec /tcx-off-tec >tcx-reg-spec encode+ - tcx-off-cmap /tcx-off-cmap-24 >tcx-reg-spec encode+ - tcx-off-thc-24 /tcx-off-thc-24 >tcx-reg-spec encode+ - tcx-off-rom /tcx-off-rom >tcx-reg-spec encode+ - tcx-off-dhc /tcx-off-dhc-24 >tcx-reg-spec encode+ - tcx-off-alt /tcx-off-alt-24 >tcx-reg-spec encode+ - " reg" property -; - -: do-map-in ( offset size -- virt ) - >r my-space r> " map-in" $call-parent -; - -: do-map-out ( virt size ) - " map-out" $call-parent -; - -\ -\ DAC -\ - --1 value tcx-dac --1 value /tcx-dac --1 value fb-addr - -: dac! ( data reg# -- ) - >r dup 2dup bljoin r> tcx-dac + l! -; - -external - -: color! ( r g b c# -- ) - 0 dac! ( r g b ) - swap rot ( b g r ) - 4 dac! ( b g ) - 4 dac! ( b ) - 4 dac! ( ) -; - -headerless - -\ -\ Mapping -\ - -: dac-map - tcx-off-cmap /tcx-dac do-map-in to tcx-dac -; - -: fb-map - tcx-off-dfb8 h# c0000 do-map-in to fb-addr -; - -: map-regs - dac-map fb-map -; - -\ -\ Installation -\ - -" SUNW,tcx" device-name -" display" device-type - -: qemu-tcx-driver-install ( -- ) - tcx-dac -1 = if - map-regs - - \ Initial pallette taken from Sun's "Writing FCode Programs" - h# ff h# ff h# ff h# 0 color! \ Background white - h# 0 h# 0 h# 0 h# ff color! \ Foreground black - h# 64 h# 41 h# b4 h# 1 color! \ SUN-blue logo - - fb-addr to frame-buffer-adr - default-font set-font - - \ Sun TCX adapters don't have an address property, but it is useful for - \ OpenBIOS developers. Unfortunately NetBSD SPARC32 has a bug that causes - \ it to fail initialising TCX if the address property is present; so work - \ around this by adding an underscore prefix - frame-buffer-adr encode-int " _address" property - - openbios-video-width openbios-video-height over char-width / over char-height / - fb8-install - then -; - -: qemu-tcx-driver-init - - \ Handle differences between 8-bit/24-bit mode - depth-bits 8 = if - tcx-8bit-reg - /tcx-off-cmap-8 to /tcx-dac - " true" encode-string " tcx-8-bit" property - else - tcx-24bit-reg - /tcx-off-cmap-24 to /tcx-dac - - \ Even with a 24-bit enabled TCX card, the control plane is - \ used in 8-bit mode. So force the video subsystem into 8-bit - \ mode before initialisation. - 8 depth-bits-xt ! - openbios-video-width line-bytes-xt ! - then - - h# 1d encode-int " vbporch" property - h# a0 encode-int " hbporch" property - h# 06 encode-int " vsync" property - h# 88 encode-int " hsync" property - h# 03 encode-int " vfporch" property - h# 18 encode-int " hfporch" property - h# 03dfd240 encode-int " pixfreq" property - h# 3c encode-int " vfreq" property - - openbios-video-height encode-int " height" property - openbios-video-width encode-int " width" property - line-bytes encode-int " linebytes" property - - h# 39 encode-int 0 encode-int encode+ " intr" property - 5 encode-int " interrupts" property - - ['] qemu-tcx-driver-install is-install -; - -qemu-tcx-driver-init - -end0 diff --git a/qemu/roms/openbios/drivers/timer.c b/qemu/roms/openbios/drivers/timer.c deleted file mode 100644 index d6794ae9c..000000000 --- a/qemu/roms/openbios/drivers/timer.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * OpenBIOS native timer driver - * - * (C) 2004 Stefan Reinauer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "drivers/drivers.h" -#include "timer.h" -#include "asm/io.h" - -#if defined(CONFIG_X86) || defined(CONFIG_AMD64) - -void setup_timers(void) -{ - /* nothing to do */ -} - -static void load_timer2(unsigned int ticks) -{ - /* Set up the timer gate, turn off the speaker */ - outb((inb(PPC_PORTB) & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB); - outb(TIMER2_SEL | WORD_ACCESS | MODE0 | BINARY_COUNT, - TIMER_MODE_PORT); - outb(ticks & 0xFF, TIMER2_PORT); - outb(ticks >> 8, TIMER2_PORT); -} - -void udelay(unsigned int usecs) -{ - load_timer2((usecs * TICKS_PER_MS) / 1000); - while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0); -} - -unsigned long currticks(void) -{ - static unsigned long totticks = 0UL; /* High resolution */ - unsigned long ticks = 0; - unsigned char portb = inb(PPC_PORTB); - - /* - * Read the timer, and hope it hasn't wrapped around - * (call this again within 54ms), then restart it - */ - outb(TIMER2_SEL | LATCH_COUNT, TIMER_MODE_PORT); - ticks = inb(TIMER2_PORT); - ticks |= inb(TIMER2_PORT) << 8; - outb(TIMER2_SEL | WORD_ACCESS | MODE0 | BINARY_COUNT, - TIMER_MODE_PORT); - outb(0, TIMER2_PORT); - outb(0, TIMER2_PORT); - - /* - * Check if the timer was running. If not, - * result is rubbish and need to start it - */ - if (portb & PPCB_T2GATE) { - totticks += (0x10000 - ticks); - } else { - /* Set up the timer gate, turn off the speaker */ - outb((portb & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB); - } - return totticks / TICKS_PER_MS; -} -#endif - -#ifdef CONFIG_PPC - -void setup_timers(void) -{ - /* nothing to do */ -} - -/* - * TODO: pass via lb table - */ -unsigned long timer_freq = 10000000 / 4; - -void udelay(unsigned int usecs) -{ - unsigned long ticksperusec = timer_freq / 1000000; - _wait_ticks(ticksperusec * usecs); -} - -#endif - -void ndelay(unsigned int nsecs) -{ - udelay((nsecs + 999) / 1000); -} - -void mdelay(unsigned int msecs) -{ - udelay(msecs * 1000); -} diff --git a/qemu/roms/openbios/drivers/timer.h b/qemu/roms/openbios/drivers/timer.h deleted file mode 100644 index 7e86db3fa..000000000 --- a/qemu/roms/openbios/drivers/timer.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Taken from Etherboot */ -/* Defines for routines to implement a low-overhead timer for drivers */ - - /* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, or (at - * your option) any later version. - */ - -#ifndef TIMER_H -#define TIMER_H - -/* Ports for the 8254 timer chip */ -#define TIMER2_PORT 0x42 -#define TIMER_MODE_PORT 0x43 - -/* Meaning of the mode bits */ -#define TIMER0_SEL 0x00 -#define TIMER1_SEL 0x40 -#define TIMER2_SEL 0x80 -#define READBACK_SEL 0xC0 - -#define LATCH_COUNT 0x00 -#define LOBYTE_ACCESS 0x10 -#define HIBYTE_ACCESS 0x20 -#define WORD_ACCESS 0x30 - -#define MODE0 0x00 -#define MODE1 0x02 -#define MODE2 0x04 -#define MODE3 0x06 -#define MODE4 0x08 -#define MODE5 0x0A - -#define BINARY_COUNT 0x00 -#define BCD_COUNT 0x01 - -/* Timers tick over at this rate */ -#define CLOCK_TICK_RATE 1193180U -#define TICKS_PER_MS (CLOCK_TICK_RATE/1000) - -/* Parallel Peripheral Controller Port B */ -#define PPC_PORTB 0x61 - -/* Meaning of the port bits */ -#define PPCB_T2OUT 0x20 /* Bit 5 */ -#define PPCB_SPKR 0x02 /* Bit 1 */ -#define PPCB_T2GATE 0x01 /* Bit 0 */ - -extern void ndelay(unsigned int nsecs); -extern void udelay(unsigned int usecs); -extern void mdelay(unsigned int msecs); -extern unsigned long currticks(void); -extern unsigned long get_timer_freq(void); - -/* arch/ppc/timebase.S */ -void _wait_ticks(unsigned long nticks); - -#define TICKS_PER_SEC 1000 - -#endif /* TIMER_H */ diff --git a/qemu/roms/openbios/drivers/usb.c b/qemu/roms/openbios/drivers/usb.c deleted file mode 100644 index c6e37174e..000000000 --- a/qemu/roms/openbios/drivers/usb.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Driver for USB ported from CoreBoot - * - * Copyright (C) 2014 BALATON Zoltan - * - * This file was part of the libpayload project. - * - * Copyright (C) 2008-2010 coresystems GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "config.h" -#include "drivers/usb.h" -#include "usb.h" -#include "timer.h" -#include "libc/byteorder.h" - -hci_t *usb_hcs = 0; - -static void usb_nop_init (usbdev_t *dev); - -static void -usb_nop_destroy (usbdev_t *dev) -{ - if (dev->descriptor != 0) - free (dev->descriptor); - usb_nop_init (dev); - dev->address = -1; - dev->hub = -1; - dev->port = -1; -} - -static void -usb_nop_poll (usbdev_t *dev) -{ - return; -} - -static void -usb_nop_init (usbdev_t *dev) -{ - dev->descriptor = 0; - dev->destroy = usb_nop_destroy; - dev->poll = usb_nop_poll; -} - -hci_t * -new_controller (void) -{ - hci_t *controller = malloc (sizeof (hci_t)); - - if (controller) { - /* atomic */ - controller->next = usb_hcs; - usb_hcs = controller; - /* atomic end */ - } - - return controller; -} - -void -detach_controller (hci_t *controller) -{ - if (controller == NULL) - return; - if (usb_hcs == controller) { - usb_hcs = controller->next; - } else { - hci_t *it = usb_hcs; - while (it != NULL) { - if (it->next == controller) { - it->next = controller->next; - return; - } - it = it->next; - } - } -} - -/** - * Shut down all controllers - */ -int -usb_exit (void) -{ - while (usb_hcs != NULL) { - usb_hcs->shutdown(usb_hcs); - } - return 0; -} - -/** - * Polls all hubs on all USB controllers, to find out about device changes - */ -void -usb_poll (void) -{ - if (usb_hcs == 0) - return; - hci_t *controller = usb_hcs; - while (controller != NULL) { - int i; - for (i = 0; i < 128; i++) { - if (controller->devices[i] != 0) { - controller->devices[i]->poll (controller->devices[i]); - } - } - controller = controller->next; - } -} - -void -init_device_entry (hci_t *controller, int i) -{ - if (controller->devices[i] != 0) - usb_debug("warning: device %d reassigned?\n", i); - controller->devices[i] = malloc(sizeof(usbdev_t)); - controller->devices[i]->controller = controller; - controller->devices[i]->address = -1; - controller->devices[i]->hub = -1; - controller->devices[i]->port = -1; - controller->devices[i]->init = usb_nop_init; - controller->devices[i]->init (controller->devices[i]); -} - -void -set_feature (usbdev_t *dev, int endp, int feature, int rtype) -{ - dev_req_t dr; - - dr.bmRequestType = rtype; - dr.data_dir = host_to_device; - dr.bRequest = SET_FEATURE; - dr.wValue = __cpu_to_le16(feature); - dr.wIndex = __cpu_to_le16(endp); - dr.wLength = 0; - dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0); -} - -void -get_status (usbdev_t *dev, int intf, int rtype, int len, void *data) -{ - dev_req_t dr; - - dr.bmRequestType = rtype; - dr.data_dir = device_to_host; - dr.bRequest = GET_STATUS; - dr.wValue = 0; - dr.wIndex = __cpu_to_le16(intf); - dr.wLength = __cpu_to_le16(len); - dev->controller->control (dev, IN, sizeof (dr), &dr, len, data); -} - -u8 * -get_descriptor (usbdev_t *dev, unsigned char bmRequestType, int descType, - int descIdx, int langID) -{ - u8 buf[8]; - u8 *result; - dev_req_t dr; - int size; - - dr.bmRequestType = bmRequestType; - dr.data_dir = device_to_host; // always like this for descriptors - dr.bRequest = GET_DESCRIPTOR; - dr.wValue = __cpu_to_le16((descType << 8) | descIdx); - dr.wIndex = __cpu_to_le16(langID); - dr.wLength = __cpu_to_le16(8); - if (dev->controller->control (dev, IN, sizeof (dr), &dr, 8, buf)) { - usb_debug ("getting descriptor size (type %x) failed\n", - descType); - } - - if (descType == 1) { - device_descriptor_t *dd = (device_descriptor_t *) buf; - usb_debug ("maxPacketSize0: %x\n", dd->bMaxPacketSize0); - if (dd->bMaxPacketSize0 != 0) - dev->endpoints[0].maxpacketsize = dd->bMaxPacketSize0; - } - - /* special case for configuration descriptors: they carry all their - subsequent descriptors with them, and keep the entire size at a - different location */ - size = buf[0]; - if (buf[1] == 2) { - int realsize = __le16_to_cpu(((unsigned short *) (buf + 2))[0]); - size = realsize; - } - result = malloc (size); - memset (result, 0, size); - dr.wLength = __cpu_to_le16(size); - if (dev->controller-> - control (dev, IN, sizeof (dr), &dr, size, result)) { - usb_debug ("getting descriptor (type %x, size %x) failed\n", - descType, size); - } - - return result; -} - -void -set_configuration (usbdev_t *dev) -{ - dev_req_t dr; - - dr.bmRequestType = 0; - dr.bRequest = SET_CONFIGURATION; - dr.wValue = __cpu_to_le16(dev->configuration[5]); - dr.wIndex = 0; - dr.wLength = 0; - dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0); -} - -int -clear_feature (usbdev_t *dev, int endp, int feature, int rtype) -{ - dev_req_t dr; - - dr.bmRequestType = rtype; - dr.data_dir = host_to_device; - dr.bRequest = CLEAR_FEATURE; - dr.wValue = __cpu_to_le16(feature); - dr.wIndex = __cpu_to_le16(endp); - dr.wLength = 0; - return dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0); -} - -int -clear_stall (endpoint_t *ep) -{ - usbdev_t *dev = ep->dev; - int endp = ep->endpoint; - int rtype = gen_bmRequestType (host_to_device, standard_type, - endp ? endp_recp : dev_recp); - - int ret = clear_feature (dev, endp, ENDPOINT_HALT, rtype); - ep->toggle = 0; - return ret; -} - -/* returns free address or -1 */ -static int -get_free_address (hci_t *controller) -{ - int i; - for (i = 1; i < 128; i++) { - if (controller->devices[i] == 0) - return i; - } - usb_debug ("no free address found\n"); - return -1; // no free address -} - -int -generic_set_address (hci_t *controller, int speed, int hubport, int hubaddr) -{ - int adr = get_free_address (controller); // address to set - dev_req_t dr; - - memset (&dr, 0, sizeof (dr)); - dr.data_dir = host_to_device; - dr.req_type = standard_type; - dr.req_recp = dev_recp; - dr.bRequest = SET_ADDRESS; - dr.wValue = __cpu_to_le16(adr); - dr.wIndex = 0; - dr.wLength = 0; - - init_device_entry(controller, adr); - usbdev_t *dev = controller->devices[adr]; - // dummy values for registering the address - dev->address = 0; - dev->hub = hubaddr; - dev->port = hubport; - dev->speed = speed; - dev->endpoints[0].dev = dev; - dev->endpoints[0].endpoint = 0; - dev->endpoints[0].maxpacketsize = 8; - dev->endpoints[0].toggle = 0; - dev->endpoints[0].direction = SETUP; - mdelay (50); - if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0)) { - return -1; - } - mdelay (50); - - return adr; -} - -/* Normalize bInterval to log2 of microframes */ -static int -usb_decode_interval(const int speed, const endpoint_type type, const unsigned char bInterval) -{ -#define LOG2(a) ((sizeof(unsigned) << 3) - __builtin_clz(a) - 1) - switch (speed) { - case LOW_SPEED: - switch (type) { - case ISOCHRONOUS: case INTERRUPT: - return LOG2(bInterval) + 3; - default: - return 0; - } - case FULL_SPEED: - switch (type) { - case ISOCHRONOUS: - return (bInterval - 1) + 3; - case INTERRUPT: - return LOG2(bInterval) + 3; - default: - return 0; - } - case HIGH_SPEED: - switch (type) { - case ISOCHRONOUS: case INTERRUPT: - return bInterval - 1; - default: - return LOG2(bInterval); - } - case SUPER_SPEED: - switch (type) { - case ISOCHRONOUS: case INTERRUPT: - return bInterval - 1; - default: - return 0; - } - default: - return 0; - } -#undef LOG2 -} - -static int -set_address (hci_t *controller, int speed, int hubport, int hubaddr) -{ - int adr = controller->set_address(controller, speed, hubport, hubaddr); - if (adr < 0 || !controller->devices[adr]) { - usb_debug ("set_address failed\n"); - return -1; - } - configuration_descriptor_t *cd; - device_descriptor_t *dd; - - usbdev_t *dev = controller->devices[adr]; - dev->address = adr; - dev->hub = hubaddr; - dev->port = hubport; - dev->speed = speed; - dev->descriptor = get_descriptor (dev, gen_bmRequestType - (device_to_host, standard_type, dev_recp), 1, 0, 0); - dd = (device_descriptor_t *) dev->descriptor; - - usb_debug ("* found device (0x%04x:0x%04x, USB %x.%x)", - __le16_to_cpu(dd->idVendor), __le16_to_cpu(dd->idProduct), - __le16_to_cpu(dd->bcdUSB) >> 8, __le16_to_cpu(dd->bcdUSB) & 0xff); - dev->quirks = USB_QUIRK_NONE; - - usb_debug ("\ndevice has %x configurations\n", dd->bNumConfigurations); - if (dd->bNumConfigurations == 0) { - /* device isn't usable */ - usb_debug ("... no usable configuration!\n"); - dev->address = 0; - return -1; - } - - dev->configuration = get_descriptor (dev, gen_bmRequestType - (device_to_host, standard_type, dev_recp), 2, 0, 0); - cd = (configuration_descriptor_t *) dev->configuration; - interface_descriptor_t *interface = - (interface_descriptor_t *) (((char *) cd) + cd->bLength); - { - int i; - int num = cd->bNumInterfaces; - interface_descriptor_t *current = interface; - usb_debug ("device has %x interfaces\n", num); - if (num > 1) { - usb_debug ("\nNOTICE: This driver defaults to using the first interface.\n" - "This might be the wrong choice and lead to limited functionality\n" - "of the device.\n"); - /* we limit to the first interface, as there was no need to - * implement something else for the time being. If you need - * it, see the SetInterface and GetInterface functions in - * the USB specification, and adapt appropriately. - */ - num = (num > 1) ? 1 : num; - } - for (i = 0; i < num; i++) { - int j; - usb_debug (" #%x has %x endpoints, interface %x:%x, protocol %x\n", - current->bInterfaceNumber, current->bNumEndpoints, current->bInterfaceClass, current->bInterfaceSubClass, current->bInterfaceProtocol); - endpoint_descriptor_t *endp = - (endpoint_descriptor_t *) (((char *) current) - + current->bLength); - /* Skip any non-endpoint descriptor */ - if (endp->bDescriptorType != 0x05) - endp = (endpoint_descriptor_t *)(((char *)endp) + ((char *)endp)[0]); - - memset (dev->endpoints, 0, sizeof (dev->endpoints)); - dev->num_endp = 1; // 0 always exists - dev->endpoints[0].dev = dev; - dev->endpoints[0].maxpacketsize = dd->bMaxPacketSize0; - dev->endpoints[0].direction = SETUP; - dev->endpoints[0].type = CONTROL; - dev->endpoints[0].interval = usb_decode_interval(dev->speed, CONTROL, endp->bInterval); - for (j = 1; j <= current->bNumEndpoints; j++) { -#ifdef CONFIG_DEBUG_USB - static const char *transfertypes[4] = { - "control", "isochronous", "bulk", "interrupt" - }; - usb_debug (" #%x: Endpoint %x (%s), max packet size %x, type %s\n", j, endp->bEndpointAddress & 0x7f, ((endp->bEndpointAddress & 0x80) != 0) ? "in" : "out", __le16_to_cpu(endp->wMaxPacketSize), transfertypes[endp->bmAttributes]); -#endif - endpoint_t *ep = - &dev->endpoints[dev->num_endp++]; - ep->dev = dev; - ep->endpoint = endp->bEndpointAddress; - ep->toggle = 0; - ep->maxpacketsize = __le16_to_cpu(endp->wMaxPacketSize); - ep->direction = - ((endp->bEndpointAddress & 0x80) == - 0) ? OUT : IN; - ep->type = endp->bmAttributes; - ep->interval = usb_decode_interval(dev->speed, ep->type, endp->bInterval); - endp = (endpoint_descriptor_t - *) (((char *) endp) + endp->bLength); - } - current = (interface_descriptor_t *) endp; - } - } - - if (controller->finish_device_config && - controller->finish_device_config(dev)) - return adr; /* Device isn't configured correctly, - only control transfers may work. */ - - set_configuration(dev); - - int class = dd->bDeviceClass; - if (class == 0) - class = interface->bInterfaceClass; - - usb_debug(", class: "); - switch (class) { - case audio_device: - usb_debug("audio\n"); - break; - case comm_device: - usb_debug("communication\n"); - break; - case hid_device: - usb_debug ("HID\n"); -#ifdef CONFIG_USB_HID - controller->devices[adr]->init = usb_hid_init; - return adr; -#else - usb_debug ("NOTICE: USB HID support not compiled in\n"); -#endif - break; - case physical_device: - usb_debug("physical\n"); - break; - case imaging_device: - usb_debug("camera\n"); - break; - case printer_device: - usb_debug("printer\n"); - break; - case msc_device: - usb_debug ("MSC\n"); -#ifdef CONFIG_USB_MSC - controller->devices[adr]->init = usb_msc_init; - return adr; -#else - usb_debug ("NOTICE: USB MSC support not compiled in\n"); -#endif - break; - case hub_device: - usb_debug ("hub\n"); -#ifdef CONFIG_USB_HUB - controller->devices[adr]->init = usb_hub_init; - return adr; -#else - usb_debug ("NOTICE: USB hub support not compiled in.\n"); -#endif - break; - case cdc_device: - usb_debug("CDC\n"); - break; - case ccid_device: - usb_debug("smartcard / CCID\n"); - break; - case security_device: - usb_debug("content security\n"); - break; - case video_device: - usb_debug("video\n"); - break; - case healthcare_device: - usb_debug("healthcare\n"); - break; - case diagnostic_device: - usb_debug("diagnostic\n"); - break; - case wireless_device: - usb_debug("wireless\n"); - break; - default: - usb_debug("unsupported class %x\n", class); - break; - } - controller->devices[adr]->init = usb_generic_init; - return adr; -} - -/* - * Should be called by the hub drivers whenever a physical detach occurs - * and can be called by usb class drivers if they are unsatisfied with a - * malfunctioning device. - */ -void -usb_detach_device(hci_t *controller, int devno) -{ - /* check if device exists, as we may have - been called yet by the usb class driver */ - if (controller->devices[devno]) { - controller->devices[devno]->destroy (controller->devices[devno]); - free(controller->devices[devno]); - controller->devices[devno] = NULL; - if (controller->destroy_device) - controller->destroy_device(controller, devno); - } -} - -int -usb_attach_device(hci_t *controller, int hubaddress, int port, int speed) -{ -#ifdef CONFIG_USB_DEBUG - static const char* speeds[] = { "full", "low", "high" }; - usb_debug ("%sspeed device\n", (speed <= 2) ? speeds[speed] : "invalid value - no"); -#endif - int newdev = set_address (controller, speed, port, hubaddress); - if (newdev == -1) - return -1; - usbdev_t *newdev_t = controller->devices[newdev]; - // determine responsible driver - current done in set_address - newdev_t->init (newdev_t); - /* init() may have called usb_detach_device() yet, so check */ - return controller->devices[newdev] ? newdev : -1; -} - -static void -usb_generic_destroy (usbdev_t *dev) -{ - if (usb_generic_remove) - usb_generic_remove(dev); -} - -void -usb_generic_init (usbdev_t *dev) -{ - dev->data = NULL; - dev->destroy = usb_generic_destroy; - - if (usb_generic_create) - usb_generic_create(dev); -} diff --git a/qemu/roms/openbios/drivers/usb.h b/qemu/roms/openbios/drivers/usb.h deleted file mode 100644 index 2e23a1370..000000000 --- a/qemu/roms/openbios/drivers/usb.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Driver for USB ported from CoreBoot - * - * Copyright (C) 2014 BALATON Zoltan - * - * This file was part of the libpayload project. - * - * Copyright (C) 2008 coresystems GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef __USB_H -#define __USB_H -#include - -typedef enum { host_to_device = 0, device_to_host = 1 } dev_req_dir; -typedef enum { standard_type = 0, class_type = 1, vendor_type = - 2, reserved_type = 3 -} dev_req_type; -typedef enum { dev_recp = 0, iface_recp = 1, endp_recp = 2, other_recp = 3 -} dev_req_recp; - -typedef enum { - GET_STATUS = 0, - CLEAR_FEATURE = 1, - SET_FEATURE = 3, - SET_ADDRESS = 5, - GET_DESCRIPTOR = 6, - SET_DESCRIPTOR = 7, - GET_CONFIGURATION = 8, - SET_CONFIGURATION = 9, - GET_INTERFACE = 10, - SET_INTERFACE = 11, - SYNCH_FRAME = 12 -} bRequest_Codes; - -typedef enum { - ENDPOINT_HALT = 0, - DEVICE_REMOTE_WAKEUP = 1, - TEST_MODE = 2 -} feature_selectors; - -enum { - audio_device = 0x01, - comm_device = 0x02, - hid_device = 0x03, - physical_device = 0x05, - imaging_device = 0x06, - printer_device = 0x07, - msc_device = 0x08, - hub_device = 0x09, - cdc_device = 0x0a, - ccid_device = 0x0b, - security_device = 0x0d, - video_device = 0x0e, - healthcare_device = 0x0f, - diagnostic_device = 0xdc, - wireless_device = 0xe0, - misc_device = 0xef, -}; - -enum { hid_subclass_none = 0, hid_subclass_boot = 1 }; - -enum { - hid_boot_proto_none = 0, - hid_boot_proto_keyboard = 1, - hid_boot_proto_mouse = 2 -}; - -typedef struct { - union { - struct { -#ifdef CONFIG_BIG_ENDIAN - dev_req_dir data_dir:1; - dev_req_type req_type:2; - dev_req_recp req_recp:5; -#else - dev_req_recp req_recp:5; - dev_req_type req_type:2; - dev_req_dir data_dir:1; -#endif - } __attribute__ ((packed)); - unsigned char bmRequestType; - } __attribute__ ((packed)); - unsigned char bRequest; - unsigned short wValue; - unsigned short wIndex; - unsigned short wLength; -} __attribute__ ((packed)) dev_req_t; - -struct usbdev_hc; -typedef struct usbdev_hc hci_t; - -struct usbdev; -typedef struct usbdev usbdev_t; - -typedef enum { SETUP, IN, OUT } direction_t; -typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3 -} endpoint_type; - -typedef struct { - usbdev_t *dev; - int endpoint; - direction_t direction; - int toggle; - int maxpacketsize; - endpoint_type type; - int interval; /* expressed as binary logarithm of the number - of microframes (i.e. t = 125us * 2^interval) */ -} endpoint_t; - -enum { FULL_SPEED = 0, LOW_SPEED = 1, HIGH_SPEED = 2, SUPER_SPEED = 3 }; - -struct usbdev { - hci_t *controller; - endpoint_t endpoints[32]; - int num_endp; - int address; // usb address - int hub; // hub, device is attached to - int port; // port where device is attached - int speed; // 1: lowspeed, 0: fullspeed, 2: highspeed - u32 quirks; // quirks field. got to love usb - void *data; - u8 *descriptor; - u8 *configuration; - void (*init) (usbdev_t *dev); - void (*destroy) (usbdev_t *dev); - void (*poll) (usbdev_t *dev); -}; - -typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3} hc_type; - -struct usbdev_hc { - hci_t *next; - u32 reg_base; - hc_type type; - usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable - - /* start(): Resume operation. */ - void (*start) (hci_t *controller); - /* stop(): Stop operation but keep controller initialized. */ - void (*stop) (hci_t *controller); - /* reset(): Perform a controller reset. The controller needs to - be (re)initialized afterwards to work (again). */ - void (*reset) (hci_t *controller); - /* init(): Initialize a (previously reset) controller - to a working state. */ - void (*init) (hci_t *controller); - /* shutdown(): Stop operation, detach host controller and shutdown - this driver instance. After calling shutdown() any - other usage of this hci_t* is invalid. */ - void (*shutdown) (hci_t *controller); - - int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize); - int (*control) (usbdev_t *dev, direction_t pid, int dr_length, - void *devreq, int data_length, u8 *data); - void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming); - void (*destroy_intr_queue) (endpoint_t *ep, void *queue); - u8* (*poll_intr_queue) (void *queue); - void *instance; - - /* set_address(): Tell the usb device its address and - return it. xHCI controllers want to - do this by themself. Also, the usbdev - structure has to be allocated and - initialized. */ - int (*set_address) (hci_t *controller, int speed, int hubport, int hubaddr); - /* finish_device_config(): Another hook for xHCI, - returns 0 on success. */ - int (*finish_device_config) (usbdev_t *dev); - /* destroy_device(): Finally, destroy all structures that - were allocated during set_address() - and finish_device_config(). */ - void (*destroy_device) (hci_t *controller, int devaddr); -}; - -typedef struct { - unsigned char bDescLength; - unsigned char bDescriptorType; - unsigned char bNbrPorts; - union { - struct { -#ifdef CONFIG_BIG_ENDIAN - unsigned long:8; - unsigned long arePortIndicatorsSupported:1; - unsigned long ttThinkTime:2; - unsigned long overcurrentProtectionMode:2; - unsigned long isCompoundDevice:1; - unsigned long logicalPowerSwitchingMode:2; -#else - unsigned long logicalPowerSwitchingMode:2; - unsigned long isCompoundDevice:1; - unsigned long overcurrentProtectionMode:2; - unsigned long ttThinkTime:2; - unsigned long arePortIndicatorsSupported:1; - unsigned long:8; -#endif - } __attribute__ ((packed)); - unsigned short wHubCharacteristics; - } __attribute__ ((packed)); - unsigned char bPowerOn2PwrGood; - unsigned char bHubContrCurrent; - char DeviceRemovable[]; -} __attribute__ ((packed)) hub_descriptor_t; - -typedef struct { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short bcdUSB; - unsigned char bDeviceClass; - unsigned char bDeviceSubClass; - unsigned char bDeviceProtocol; - unsigned char bMaxPacketSize0; - unsigned short idVendor; - unsigned short idProduct; - unsigned short bcdDevice; - unsigned char iManufacturer; - unsigned char iProduct; - unsigned char iSerialNumber; - unsigned char bNumConfigurations; -} __attribute__ ((packed)) device_descriptor_t; - -typedef struct { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short wTotalLength; - unsigned char bNumInterfaces; - unsigned char bConfigurationValue; - unsigned char iConfiguration; - unsigned char bmAttributes; - unsigned char bMaxPower; -} __attribute__ ((packed)) configuration_descriptor_t; - -typedef struct { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned char bInterfaceNumber; - unsigned char bAlternateSetting; - unsigned char bNumEndpoints; - unsigned char bInterfaceClass; - unsigned char bInterfaceSubClass; - unsigned char bInterfaceProtocol; - unsigned char iInterface; -} __attribute__ ((packed)) interface_descriptor_t; - -typedef struct { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned char bEndpointAddress; - unsigned char bmAttributes; - unsigned short wMaxPacketSize; - unsigned char bInterval; -} __attribute__ ((packed)) endpoint_descriptor_t; - -typedef struct { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short bcdHID; - unsigned char bCountryCode; - unsigned char bNumDescriptors; - unsigned char bReportDescriptorType; - unsigned short wReportDescriptorLength; -} __attribute__ ((packed)) hid_descriptor_t; - -hci_t *new_controller (void); -void detach_controller (hci_t *controller); -void usb_poll (void); -void init_device_entry (hci_t *controller, int num); - -void set_feature (usbdev_t *dev, int endp, int feature, int rtype); -void get_status (usbdev_t *dev, int endp, int rtype, int len, void *data); -void set_configuration (usbdev_t *dev); -int clear_feature (usbdev_t *dev, int endp, int feature, int rtype); -int clear_stall (endpoint_t *ep); - -void usb_hub_init (usbdev_t *dev); -void usb_hid_init (usbdev_t *dev); -void usb_msc_init (usbdev_t *dev); -void usb_generic_init (usbdev_t *dev); - -u8 *get_descriptor (usbdev_t *dev, unsigned char bmRequestType, - int descType, int descIdx, int langID); - -static inline unsigned char -gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp) -{ - return (dir << 7) | (type << 5) | recp; -} - -/* default "set address" handler */ -int generic_set_address (hci_t *controller, int speed, int hubport, int hubaddr); - -void usb_detach_device(hci_t *controller, int devno); -int usb_attach_device(hci_t *controller, int hubaddress, int port, int speed); - -u32 usb_quirk_check(u16 vendor, u16 device); -int usb_interface_check(u16 vendor, u16 device); - -#define USB_QUIRK_MSC_FORCE_PROTO_SCSI (1 << 0) -#define USB_QUIRK_MSC_FORCE_PROTO_ATAPI (1 << 1) -#define USB_QUIRK_MSC_FORCE_PROTO_UFI (1 << 2) -#define USB_QUIRK_MSC_FORCE_PROTO_RBC (1 << 3) -#define USB_QUIRK_MSC_FORCE_TRANS_BBB (1 << 4) -#define USB_QUIRK_MSC_FORCE_TRANS_CBI (1 << 5) -#define USB_QUIRK_MSC_FORCE_TRANS_CBI_I (1 << 6) -#define USB_QUIRK_MSC_NO_TEST_UNIT_READY (1 << 7) -#define USB_QUIRK_MSC_SHORT_INQUIRY (1 << 8) -#define USB_QUIRK_TEST (1 << 31) -#define USB_QUIRK_NONE 0 - -#ifdef CONFIG_DEBUG_USB -#define usb_debug(fmt, args...) do { printk(fmt , ##args); } while (0) -#else -#define usb_debug(fmt, args...) -#endif - -/** - * To be implemented by libpayload-client. It's called by the USB stack - * when a new USB device is found which isn't claimed by a built in driver, - * so the client has the chance to know about it. - * - * @param dev descriptor for the USB device - */ -void __attribute__((weak)) usb_generic_create (usbdev_t *dev); - -/** - * To be implemented by libpayload-client. It's called by the USB stack - * when it finds out that a USB device is removed which wasn't claimed by a - * built in driver. - * - * @param dev descriptor for the USB device - */ -void __attribute__((weak)) usb_generic_remove (usbdev_t *dev); - -#endif diff --git a/qemu/roms/openbios/drivers/usbhid.c b/qemu/roms/openbios/drivers/usbhid.c deleted file mode 100644 index a423278a8..000000000 --- a/qemu/roms/openbios/drivers/usbhid.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Driver for HID devices ported from CoreBoot - * - * Copyright (C) 2014 BALATON Zoltan - * - * This file was part of the libpayload project. - * - * Copyright (C) 2008-2010 coresystems GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include -#include "libc/byteorder.h" -#include "libc/vsprintf.h" -#include "drivers/usb.h" -#include "usb.h" - -DECLARE_UNNAMED_NODE(usb_kbd, INSTALL_OPEN, sizeof(int)); - -static void -keyboard_open(int *idx) -{ - RET(-1); -} - -static void -keyboard_close(int *idx) -{ -} - -static void keyboard_read(void); - -NODE_METHODS( usb_kbd ) = { - { "open", keyboard_open }, - { "close", keyboard_close }, - { "read", keyboard_read }, -}; - -#ifdef CONFIG_USB_DEBUG -static const char *boot_protos[3] = { "(none)", "keyboard", "mouse" }; -#endif -typedef enum { hid_proto_boot = 0, hid_proto_report = 1 } hid_proto; -enum { GET_REPORT = 0x1, GET_IDLE = 0x2, GET_PROTOCOL = 0x3, SET_REPORT = - 0x9, SET_IDLE = 0xa, SET_PROTOCOL = 0xb -}; - -typedef union { - struct { - u8 modifiers; - u8 repeats; - u8 keys[6]; - }; - u8 buffer[8]; -} usb_hid_keyboard_event_t; - -typedef struct { - void* queue; - hid_descriptor_t *descriptor; - - usb_hid_keyboard_event_t previous; - int lastkeypress; - int repeat_delay; -} usbhid_inst_t; - -#define HID_INST(dev) ((usbhid_inst_t*)(dev)->data) - -static void -usb_hid_destroy (usbdev_t *dev) -{ - if (HID_INST(dev)->queue) { - int i; - for (i = 0; i <= dev->num_endp; i++) { - if (dev->endpoints[i].endpoint == 0) - continue; - if (dev->endpoints[i].type != INTERRUPT) - continue; - if (dev->endpoints[i].direction != IN) - continue; - break; - } - dev->controller->destroy_intr_queue( - &dev->endpoints[i], HID_INST(dev)->queue); - HID_INST(dev)->queue = NULL; - } - free (dev->data); -} - -/* keybuffer is global to all USB keyboards */ -static int keycount; -#define KEYBOARD_BUFFER_SIZE 16 -static short keybuffer[KEYBOARD_BUFFER_SIZE]; - -const char *countries[36][2] = { - { "unknown", "us" }, - { "Arabic", "ae" }, - { "Belgian", "be" }, - { "Canadian-Bilingual", "ca" }, - { "Canadian-French", "ca" }, - { "Czech Republic", "cz" }, - { "Danish", "dk" }, - { "Finnish", "fi" }, - { "French", "fr" }, - { "German", "de" }, - { "Greek", "gr" }, - { "Hebrew", "il" }, - { "Hungary", "hu" }, - { "International (ISO)", "iso" }, - { "Italian", "it" }, - { "Japan (Katakana)", "jp" }, - { "Korean", "us" }, - { "Latin American", "us" }, - { "Netherlands/Dutch", "nl" }, - { "Norwegian", "no" }, - { "Persian (Farsi)", "ir" }, - { "Poland", "pl" }, - { "Portuguese", "pt" }, - { "Russia", "ru" }, - { "Slovakia", "sl" }, - { "Spanish", "es" }, - { "Swedish", "se" }, - { "Swiss/French", "ch" }, - { "Swiss/German", "ch" }, - { "Switzerland", "ch" }, - { "Taiwan", "tw" }, - { "Turkish-Q", "tr" }, - { "UK", "uk" }, - { "US", "us" }, - { "Yugoslavia", "yu" }, - { "Turkish-F", "tr" }, - /* 36 - 255: Reserved */ -}; - - - -struct layout_maps { - const char *country; - const short map[4][0x80]; -}; - -static const struct layout_maps *map; - -#define KEY_BREAK 0x101 /* Not on PC KBD */ -#define KEY_DOWN 0x102 /* Down arrow key */ -#define KEY_UP 0x103 /* Up arrow key */ -#define KEY_LEFT 0x104 /* Left arrow key */ -#define KEY_RIGHT 0x105 /* Right arrow key */ -#define KEY_HOME 0x106 /* home key */ -#define KEY_BACKSPACE 0x107 /* not on pc */ -#define KEY_F0 0x108 /* function keys; 64 reserved */ -#define KEY_F(n) (KEY_F0 + (n)) - -#define KEY_DC 0x14a /* delete character */ -#define KEY_IC 0x14b /* insert char or enter ins mode */ - -#define KEY_NPAGE 0x152 /* next page */ -#define KEY_PPAGE 0x153 /* previous page */ - -#define KEY_ENTER 0x157 /* enter or send (unreliable) */ - -#define KEY_PRINT 0x15a /* print/copy */ - -#define KEY_END 0x166 /* end key */ - -static const struct layout_maps keyboard_layouts[] = { -// #ifdef CONFIG_PC_KEYBOARD_LAYOUT_US -{ .country = "us", .map = { - { /* No modifier */ - -1, -1, -1, -1, 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - /* 0x10 */ - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', - /* 0x20 */ - '3', '4', '5', '6', '7', '8', '9', '0', - '\n', '\e', '\b', '\t', ' ', '-', '=', '[', - /* 0x30 */ - ']', '\\', -1, ';', '\'', '`', ',', '.', - '/', -1 /* CapsLk */, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), - /* 0x40 */ - KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), KEY_F(11), KEY_F(12), KEY_PRINT, -1 /* ScrLk */, - KEY_BREAK, KEY_IC, KEY_HOME, KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT, - /* 50 */ - KEY_LEFT, KEY_DOWN, KEY_UP, -1 /*NumLck*/, '/', '*', '-' /* = ? */, '+', - KEY_ENTER, KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT, -1, KEY_RIGHT, KEY_HOME, - /* 60 */ - KEY_UP, KEY_PPAGE, -1, KEY_DC, -1 /* < > | */, -1 /* Win Key Right */, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - /* 70 */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - }, - { /* Shift modifier */ - -1, -1, -1, -1, 'A', 'B', 'C', 'D', - 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - /* 0x10 */ - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', - /* 0x20 */ - '#', '$', '%', '^', '&', '*', '(', ')', - '\n', '\e', '\b', '\t', ' ', '_', '+', '{', - /* 0x30 */ - '}', '|', -1, ':', '"', '~', '<', '>', - '?', -1 /* CapsLk */, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), - /* 0x40 */ - KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), KEY_F(11), KEY_F(12), KEY_PRINT, -1 /* ScrLk */, - KEY_BREAK, KEY_IC, KEY_HOME, KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT, - /* 50 */ - KEY_LEFT, KEY_DOWN, KEY_UP, -1 /*NumLck*/, '/', '*', '-' /* = ? */, '+', - KEY_ENTER, KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT, -1, KEY_RIGHT, KEY_HOME, - /* 60 */ - KEY_UP, KEY_PPAGE, -1, KEY_DC, -1 /* < > | */, -1 /* Win Key Right */, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - /* 70 */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - }, - { /* Alt */ - -1, -1, -1, -1, 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - /* 0x10 */ - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', - /* 0x20 */ - '3', '4', '5', '6', '7', '8', '9', '0', - '\n', '\e', '\b', '\t', ' ', '-', '=', '[', - /* 0x30 */ - ']', '\\', -1, ';', '\'', '`', ',', '.', - '/', -1 /* CapsLk */, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), - /* 0x40 */ - KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), KEY_F(11), KEY_F(12), KEY_PRINT, -1 /* ScrLk */, - KEY_BREAK, KEY_IC, KEY_HOME, KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT, - /* 50 */ - KEY_LEFT, KEY_DOWN, KEY_UP, -1 /*NumLck*/, '/', '*', '-' /* = ? */, '+', - KEY_ENTER, KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT, -1, KEY_RIGHT, KEY_HOME, - /* 60 */ - KEY_UP, KEY_PPAGE, -1, KEY_DC, -1 /* < > | */, -1 /* Win Key Right */, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - /* 70 */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - }, - { /* Shift+Alt modifier */ - -1, -1, -1, -1, 'A', 'B', 'C', 'D', - 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - /* 0x10 */ - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', - /* 0x20 */ - '#', '$', '%', '^', '&', '*', '(', ')', - '\n', '\e', '\b', '\t', ' ', '-', '=', '[', - /* 0x30 */ - ']', '\\', -1, ':', '\'', '`', ',', '.', - '/', -1 /* CapsLk */, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), - /* 0x40 */ - KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), KEY_F(11), KEY_F(12), KEY_PRINT, -1 /* ScrLk */, - KEY_BREAK, KEY_IC, KEY_HOME, KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT, - /* 50 */ - KEY_LEFT, KEY_DOWN, KEY_UP, -1 /*NumLck*/, '/', '*', '-' /* = ? */, '+', - KEY_ENTER, KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT, -1, KEY_RIGHT, KEY_HOME, - /* 60 */ - KEY_UP, KEY_PPAGE, -1, KEY_DC, -1 /* < > | */, -1 /* Win Key Right */, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - /* 70 */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - } -}}, -//#endif -}; - -#define MOD_SHIFT (1 << 0) -#define MOD_ALT (1 << 1) -#define MOD_CTRL (1 << 2) - -static void usb_hid_keyboard_queue(int ch) { - /* ignore key presses if buffer full */ - if (keycount < KEYBOARD_BUFFER_SIZE) - keybuffer[keycount++] = ch; -} - -#define KEYBOARD_REPEAT_MS 30 -#define INITIAL_REPEAT_DELAY 10 -#define REPEAT_DELAY 2 - -static void -usb_hid_process_keyboard_event(usbhid_inst_t *const inst, - const usb_hid_keyboard_event_t *const current) -{ - const usb_hid_keyboard_event_t *const previous = &inst->previous; - - int i, keypress = 0, modifiers = 0; - - if (current->modifiers & 0x01) /* Left-Ctrl */ modifiers |= MOD_CTRL; - if (current->modifiers & 0x02) /* Left-Shift */ modifiers |= MOD_SHIFT; - if (current->modifiers & 0x04) /* Left-Alt */ modifiers |= MOD_ALT; - if (current->modifiers & 0x08) /* Left-GUI */ ; - if (current->modifiers & 0x10) /* Right-Ctrl */ modifiers |= MOD_CTRL; - if (current->modifiers & 0x20) /* Right-Shift */ modifiers |= MOD_SHIFT; - if (current->modifiers & 0x40) /* Right-AltGr */ modifiers |= MOD_ALT; - if (current->modifiers & 0x80) /* Right-GUI */ ; - - /* Did the event change at all? */ - if (inst->lastkeypress && - !memcmp(current, previous, sizeof(*current))) { - /* No. Then it's a key repeat event. */ - if (inst->repeat_delay) { - inst->repeat_delay--; - } else { - usb_hid_keyboard_queue(inst->lastkeypress); - inst->repeat_delay = REPEAT_DELAY; - } - - return; - } - - inst->lastkeypress = 0; - - for (i=0; i<6; i++) { - int j; - int skip = 0; - // No more keys? skip - if (current->keys[i] == 0) - return; - - for (j=0; j<6; j++) { - if (current->keys[i] == previous->keys[j]) { - skip = 1; - break; - } - } - if (skip) - continue; - - - /* Mask off MOD_CTRL */ - keypress = map->map[modifiers & 0x03][current->keys[i]]; - - if (modifiers & MOD_CTRL) { - switch (keypress) { - case 'a' ... 'z': - keypress &= 0x1f; - break; - default: - continue; - } - } - - if (keypress == -1) { - /* Debug: Print unknown keys */ - usb_debug ("usbhid: <%x> %x [ %x %x %x %x %x %x ] %d\n", - current->modifiers, current->repeats, - current->keys[0], current->keys[1], - current->keys[2], current->keys[3], - current->keys[4], current->keys[5], i); - - /* Unknown key? Try next one in the queue */ - continue; - } - - usb_hid_keyboard_queue(keypress); - - /* Remember for authentic key repeat */ - inst->lastkeypress = keypress; - inst->repeat_delay = INITIAL_REPEAT_DELAY; - } -} - -static void -usb_hid_poll (usbdev_t *dev) -{ - usb_hid_keyboard_event_t current; - const u8 *buf; - - while ((buf=dev->controller->poll_intr_queue (HID_INST(dev)->queue))) { - memcpy(¤t.buffer, buf, 8); - usb_hid_process_keyboard_event(HID_INST(dev), ¤t); - HID_INST(dev)->previous = current; - } -} - -static void -usb_hid_set_idle (usbdev_t *dev, interface_descriptor_t *interface, u16 duration) -{ - dev_req_t dr; - dr.data_dir = host_to_device; - dr.req_type = class_type; - dr.req_recp = iface_recp; - dr.bRequest = SET_IDLE; - dr.wValue = __cpu_to_le16((duration >> 2) << 8); - dr.wIndex = __cpu_to_le16(interface->bInterfaceNumber); - dr.wLength = 0; - dev->controller->control (dev, OUT, sizeof (dev_req_t), &dr, 0, 0); -} - -static void -usb_hid_set_protocol (usbdev_t *dev, interface_descriptor_t *interface, hid_proto proto) -{ - dev_req_t dr; - dr.data_dir = host_to_device; - dr.req_type = class_type; - dr.req_recp = iface_recp; - dr.bRequest = SET_PROTOCOL; - dr.wValue = __cpu_to_le16(proto); - dr.wIndex = __cpu_to_le16(interface->bInterfaceNumber); - dr.wLength = 0; - dev->controller->control (dev, OUT, sizeof (dev_req_t), &dr, 0, 0); -} - -static int usb_hid_set_layout (const char *country) -{ - /* FIXME should be per keyboard */ - int i; - - for (i=0; icountry); - return 0; - } - - usb_debug(" Keyboard layout '%s' not found, using '%s'\n", - country, map->country); - - /* Nothing found, not changed */ - return -1; -} - -void -usb_hid_init (usbdev_t *dev) -{ - configuration_descriptor_t *cd = (configuration_descriptor_t*)dev->configuration; - interface_descriptor_t *interface = (interface_descriptor_t*)(((char *) cd) + cd->bLength); - - if (interface->bInterfaceSubClass == hid_subclass_boot) { - u8 countrycode = 0; - usb_debug (" supports boot interface..\n"); - usb_debug (" it's a %s\n", - boot_protos[interface->bInterfaceProtocol]); - switch (interface->bInterfaceProtocol) { - case hid_boot_proto_keyboard: - dev->data = malloc (sizeof (usbhid_inst_t)); - if (!dev->data) { - printk("Not enough memory for USB HID device.\n"); - return; - } - memset(&HID_INST(dev)->previous, 0x00, - sizeof(HID_INST(dev)->previous)); - usb_debug (" configuring...\n"); - usb_hid_set_protocol(dev, interface, hid_proto_boot); - usb_hid_set_idle(dev, interface, KEYBOARD_REPEAT_MS); - usb_debug (" activating...\n"); -#if 0 - HID_INST (dev)->descriptor = - (hid_descriptor_t *) - get_descriptor(dev, gen_bmRequestType - (device_to_host, standard_type, iface_recp), - 0x21, 0, 0); - countrycode = HID_INST(dev)->descriptor->bCountryCode; -#endif - /* 35 countries defined: */ - if (countrycode > 35) - countrycode = 0; - usb_debug (" Keyboard has %s layout (country code %02x)\n", - countries[countrycode][0], countrycode); - - /* Set keyboard layout accordingly */ - usb_hid_set_layout(countries[countrycode][1]); - - // only add here, because we only support boot-keyboard HID devices - dev->destroy = usb_hid_destroy; - dev->poll = usb_hid_poll; - int i; - for (i = 0; i <= dev->num_endp; i++) { - if (dev->endpoints[i].endpoint == 0) - continue; - if (dev->endpoints[i].type != INTERRUPT) - continue; - if (dev->endpoints[i].direction != IN) - continue; - break; - } - usb_debug (" found endpoint %x for interrupt-in\n", i); - /* 20 buffers of 8 bytes, for every 10 msecs */ - HID_INST(dev)->queue = dev->controller->create_intr_queue (&dev->endpoints[i], 8, 20, 10); - keycount = 0; - usb_debug (" configuration done.\n"); - break; - default: - usb_debug("NOTICE: HID interface protocol %d%s not supported.\n", - interface->bInterfaceProtocol, - (interface->bInterfaceProtocol == hid_boot_proto_mouse ? - " (USB mouse)" : "")); - break; - } - } -} - -static int usbhid_havechar (void) -{ - return (keycount != 0); -} - -static int usbhid_getchar (void) -{ - short ret; - - if (keycount == 0) - return 0; - ret = keybuffer[0]; - memmove(keybuffer, keybuffer + 1, --keycount); - - return (int)ret; -} - -/* ( addr len -- actual ) */ -static void keyboard_read(void) -{ - char *addr; - int len, key, i; - - usb_poll(); - len=POP(); - addr=(char *)cell2pointer(POP()); - - for (i = 0; i < len; i++) { - if (!usbhid_havechar()) - break; - key = usbhid_getchar(); - *addr++ = (char)key; - } - PUSH(i); -} - -void ob_usb_hid_add_keyboard(const char *path) -{ - char name[128]; - phandle_t aliases; - - snprintf(name, sizeof(name), "%s/keyboard", path); - usb_debug("Found keyboard at %s\n", name); - REGISTER_NAMED_NODE(usb_kbd, name); - - push_str(name); - fword("find-device"); - - push_str("keyboard"); - fword("device-type"); - - aliases = find_dev("/aliases"); - set_property(aliases, "adb-keyboard", name, strlen(name) + 1); -} diff --git a/qemu/roms/openbios/drivers/usbohci.c b/qemu/roms/openbios/drivers/usbohci.c deleted file mode 100644 index 774164b0b..000000000 --- a/qemu/roms/openbios/drivers/usbohci.c +++ /dev/null @@ -1,926 +0,0 @@ -/* - * Driver for USB OHCI ported from CoreBoot - * - * Copyright (C) 2014 BALATON Zoltan - * - * This file was part of the libpayload project. - * - * Copyright (C) 2010 Patrick Georgi - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -//#define USB_DEBUG_ED - -#include "config.h" -#include -#include -#include "timer.h" -#include "drivers/pci.h" -#include "pci.h" -#include -#include "usbohci_private.h" -#include "usbohci.h" - -static void ohci_start (hci_t *controller); -static void ohci_stop (hci_t *controller); -static void ohci_reset (hci_t *controller); -static void ohci_shutdown (hci_t *controller); -static int ohci_bulk (endpoint_t *ep, int size, u8 *data, int finalize); -static int ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, - int dalen, u8 *data); -static void* ohci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming); -static void ohci_destroy_intr_queue (endpoint_t *ep, void *queue); -static u8* ohci_poll_intr_queue (void *queue); -static void ohci_process_done_queue(ohci_t *ohci, int spew_debug); - -#ifdef USB_DEBUG_ED -static void -dump_td (td_t *cur) -{ - usb_debug("+---------------------------------------------------+\n"); - if (((__le32_to_cpu(cur->config) & (3UL << 19)) >> 19) == 0) - usb_debug("|..[SETUP]..........................................|\n"); - else if (((__le32_to_cpu(cur->config) & (3UL << 8)) >> 8) == 2) - usb_debug("|..[IN].............................................|\n"); - else if (((__le32_to_cpu(cur->config) & (3UL << 8)) >> 8) == 1) - usb_debug("|..[OUT]............................................|\n"); - else - usb_debug("|..[]...............................................|\n"); - usb_debug("|:|============ OHCI TD at [0x%08lx] ==========|:|\n", virt_to_phys(cur)); - usb_debug("|:| ERRORS = [%ld] | CONFIG = [0x%08x] | |:|\n", - 3 - ((__le32_to_cpu(cur->config) & (3UL << 26)) >> 26), __le32_to_cpu(cur->config)); - usb_debug("|:+-----------------------------------------------+:|\n"); - usb_debug("|:| C | Condition Code | [%02ld] |:|\n", - (__le32_to_cpu(cur->config) & (0xFUL << 28)) >> 28); - usb_debug("|:| O | Direction/PID | [%ld] |:|\n", - (__le32_to_cpu(cur->config) & (3UL << 19)) >> 19); - usb_debug("|:| N | Buffer Rounding | [%ld] |:|\n", - (__le32_to_cpu(cur->config) & (1UL << 18)) >> 18); - usb_debug("|:| F | Delay Intterrupt | [%ld] |:|\n", - (__le32_to_cpu(cur->config) & (7UL << 21)) >> 21); - usb_debug("|:| I | Data Toggle | [%ld] |:|\n", - (__le32_to_cpu(cur->config) & (3UL << 24)) >> 24); - usb_debug("|:| G | Error Count | [%ld] |:|\n", - (__le32_to_cpu(cur->config) & (3UL << 26)) >> 26); - usb_debug("|:+-----------------------------------------------+:|\n"); - usb_debug("|:| Current Buffer Pointer [0x%08x] |:|\n", __le32_to_cpu(cur->current_buffer_pointer)); - usb_debug("|:+-----------------------------------------------+:|\n"); - usb_debug("|:| Next TD [0x%08x] |:|\n", __le32_to_cpu(cur->next_td)); - usb_debug("|:+-----------------------------------------------+:|\n"); - usb_debug("|:| Current Buffer End [0x%08x] |:|\n", __le32_to_cpu(cur->buffer_end)); - usb_debug("|:|-----------------------------------------------|:|\n"); - usb_debug("|...................................................|\n"); - usb_debug("+---------------------------------------------------+\n"); -} - -static void -dump_ed (ed_t *cur) -{ - td_t *tmp_td = NULL; - usb_debug("+===================================================+\n"); - usb_debug("| ############# OHCI ED at [0x%08lx] ########### |\n", virt_to_phys(cur)); - usb_debug("+---------------------------------------------------+\n"); - usb_debug("| Next Endpoint Descriptor [0x%08lx] |\n", __le32_to_cpu(cur->next_ed) & ~0xFUL); - usb_debug("+---------------------------------------------------+\n"); - usb_debug("| | @ 0x%08x : |\n", __le32_to_cpu(cur->config)); - usb_debug("| C | Maximum Packet Length | [%04ld] |\n", - ((__le32_to_cpu(cur->config) & (0x3fffUL << 16)) >> 16)); - usb_debug("| O | Function Address | [%04d] |\n", - __le32_to_cpu(cur->config) & 0x7F); - usb_debug("| N | Endpoint Number | [%02ld] |\n", - (__le32_to_cpu(cur->config) & (0xFUL << 7)) >> 7); - usb_debug("| F | Endpoint Direction | [%ld] |\n", - ((__le32_to_cpu(cur->config) & (3UL << 11)) >> 11)); - usb_debug("| I | Endpoint Speed | [%ld] |\n", - ((__le32_to_cpu(cur->config) & (1UL << 13)) >> 13)); - usb_debug("| G | Skip | [%ld] |\n", - ((__le32_to_cpu(cur->config) & (1UL << 14)) >> 14)); - usb_debug("| | Format | [%ld] |\n", - ((__le32_to_cpu(cur->config) & (1UL << 15)) >> 15)); - usb_debug("+---------------------------------------------------+\n"); - usb_debug("| TD Queue Tail Pointer [0x%08lx] |\n", - __le32_to_cpu(cur->tail_pointer) & ~0xFUL); - usb_debug("+---------------------------------------------------+\n"); - usb_debug("| TD Queue Head Pointer [0x%08lx] |\n", - __le32_to_cpu(cur->head_pointer) & ~0xFUL); - usb_debug("| CarryToggleBit [%d] Halted [%d] |\n", - (u16)(__le32_to_cpu(cur->head_pointer) & 0x2UL)>>1, (u16)(__le32_to_cpu(cur->head_pointer) & 0x1UL)); - - tmp_td = (td_t *)phys_to_virt((__le32_to_cpu(cur->head_pointer) & ~0xFUL)); - if ((__le32_to_cpu(cur->head_pointer) & ~0xFUL) != (__le32_to_cpu(cur->tail_pointer) & ~0xFUL)) { - usb_debug("|:::::::::::::::::: OHCI TD CHAIN ::::::::::::::::::|\n"); - while (virt_to_phys(tmp_td) != (__le32_to_cpu(cur->tail_pointer) & ~0xFUL)) - { - dump_td(tmp_td); - tmp_td = (td_t *)phys_to_virt((__le32_to_cpu(tmp_td->next_td) & ~0xFUL)); - } - usb_debug("|:::::::::::::::: EOF OHCI TD CHAIN ::::::::::::::::|\n"); - usb_debug("+---------------------------------------------------+\n"); - } else { - usb_debug("+---------------------------------------------------+\n"); - } -} -#endif - -static void -ohci_reset (hci_t *controller) -{ - if (controller == NULL) - return; - - OHCI_INST(controller)->opreg->HcCommandStatus = __cpu_to_le32(HostControllerReset); - mdelay(2); /* wait 2ms */ - OHCI_INST(controller)->opreg->HcControl = 0; - mdelay(10); /* wait 10ms */ -} - -static void -ohci_reinit (hci_t *controller) -{ -} - -hci_t * -ohci_init (void *bar) -{ - int i; - - hci_t *controller = new_controller (); - - if (!controller) { - printk("Could not create USB controller instance.\n"); - return NULL; - } - - controller->instance = malloc (sizeof (ohci_t)); - if(!controller->instance) { - printk("Not enough memory creating USB controller instance.\n"); - return NULL; - } - - controller->type = OHCI; - - controller->start = ohci_start; - controller->stop = ohci_stop; - controller->reset = ohci_reset; - controller->init = ohci_reinit; - controller->shutdown = ohci_shutdown; - controller->bulk = ohci_bulk; - controller->control = ohci_control; - controller->set_address = generic_set_address; - controller->finish_device_config = NULL; - controller->destroy_device = NULL; - controller->create_intr_queue = ohci_create_intr_queue; - controller->destroy_intr_queue = ohci_destroy_intr_queue; - controller->poll_intr_queue = ohci_poll_intr_queue; - for (i = 0; i < 128; i++) { - controller->devices[i] = 0; - } - init_device_entry (controller, 0); - OHCI_INST (controller)->roothub = controller->devices[0]; - - controller->reg_base = (u32)(unsigned long)bar; - OHCI_INST (controller)->opreg = (opreg_t*)phys_to_virt(controller->reg_base); - usb_debug("OHCI Version %x.%x\n", - (READ_OPREG(OHCI_INST(controller), HcRevision) >> 4) & 0xf, - READ_OPREG(OHCI_INST(controller), HcRevision) & 0xf); - - if ((READ_OPREG(OHCI_INST(controller), HcControl) & HostControllerFunctionalStateMask) == USBReset) { - /* cold boot */ - OHCI_INST (controller)->opreg->HcControl &= __cpu_to_le32(~RemoteWakeupConnected); - OHCI_INST (controller)->opreg->HcFmInterval = - __cpu_to_le32((11999 * FrameInterval) | ((((11999 - 210)*6)/7) * FSLargestDataPacket)); - /* TODO: right value for PowerOnToPowerGoodTime ? */ - OHCI_INST (controller)->opreg->HcRhDescriptorA = - __cpu_to_le32(NoPowerSwitching | NoOverCurrentProtection | (10 * PowerOnToPowerGoodTime)); - OHCI_INST (controller)->opreg->HcRhDescriptorB = __cpu_to_le32(0 * DeviceRemovable); - udelay(100); /* TODO: reset asserting according to USB spec */ - } else if ((READ_OPREG(OHCI_INST(controller), HcControl) & HostControllerFunctionalStateMask) != USBOperational) { - OHCI_INST (controller)->opreg->HcControl = - __cpu_to_le32((READ_OPREG(OHCI_INST(controller), HcControl) & ~HostControllerFunctionalStateMask) - | USBResume); - udelay(100); /* TODO: resume time according to USB spec */ - } - int interval = OHCI_INST (controller)->opreg->HcFmInterval; - - OHCI_INST (controller)->opreg->HcCommandStatus = __cpu_to_le32(HostControllerReset); - udelay (10); /* at most 10us for reset to complete. State must be set to Operational within 2ms (5.1.1.4) */ - OHCI_INST (controller)->opreg->HcFmInterval = interval; - ofmem_posix_memalign((void **)&(OHCI_INST (controller)->hcca), 256, 256); - memset((void*)OHCI_INST (controller)->hcca, 0, 256); - - usb_debug("HCCA addr %p\n", OHCI_INST(controller)->hcca); - /* Initialize interrupt table. */ - u32 *const intr_table = OHCI_INST(controller)->hcca->HccaInterruptTable; - ed_t *const periodic_ed; - ofmem_posix_memalign((void **)&periodic_ed, sizeof(ed_t), sizeof(ed_t)); - memset((void *)periodic_ed, 0, sizeof(*periodic_ed)); - for (i = 0; i < 32; ++i) - intr_table[i] = __cpu_to_le32(virt_to_phys(periodic_ed)); - OHCI_INST (controller)->periodic_ed = periodic_ed; - - OHCI_INST (controller)->opreg->HcHCCA = __cpu_to_le32(virt_to_phys(OHCI_INST(controller)->hcca)); - /* Make sure periodic schedule is enabled. */ - OHCI_INST (controller)->opreg->HcControl |= __cpu_to_le32(PeriodicListEnable); - OHCI_INST (controller)->opreg->HcControl &= __cpu_to_le32(~IsochronousEnable); // unused by this driver - // disable everything, contrary to what OHCI spec says in 5.1.1.4, as we don't need IRQs - OHCI_INST (controller)->opreg->HcInterruptEnable = __cpu_to_le32(1<<31); - OHCI_INST (controller)->opreg->HcInterruptDisable = __cpu_to_le32(~(1<<31)); - OHCI_INST (controller)->opreg->HcInterruptStatus = __cpu_to_le32(~0); - OHCI_INST (controller)->opreg->HcPeriodicStart = - __cpu_to_le32((READ_OPREG(OHCI_INST(controller), HcFmInterval) & FrameIntervalMask) / 10 * 9); - OHCI_INST (controller)->opreg->HcControl = __cpu_to_le32((READ_OPREG(OHCI_INST(controller), HcControl) - & ~HostControllerFunctionalStateMask) | USBOperational); - - mdelay(100); - - controller->devices[0]->controller = controller; - controller->devices[0]->init = ohci_rh_init; - controller->devices[0]->init (controller->devices[0]); - return controller; -} - -hci_t * -ohci_pci_init (pci_addr addr) -{ - u32 reg_base; - uint16_t cmd; - - cmd = pci_config_read16(addr, PCI_COMMAND); - cmd |= PCI_COMMAND_BUS_MASTER; - pci_config_write16(addr, PCI_COMMAND, cmd); - - /* regarding OHCI spec, Appendix A, BAR_OHCI register description, Table A-4 - * BASE ADDRESS only [31-12] bits. All other usually 0, but not all. - * OHCI mandates MMIO, so bit 0 is clear */ - reg_base = pci_config_read32 (addr, PCI_BASE_ADDR_0) & 0xfffff000; - - return ohci_init((void *)(unsigned long)reg_base); -} - -static void -ohci_shutdown (hci_t *controller) -{ - if (controller == 0) - return; - detach_controller (controller); - ohci_stop(controller); - OHCI_INST (controller)->roothub->destroy (OHCI_INST (controller)-> - roothub); - controller->reset (controller); - free ((void *)OHCI_INST (controller)->periodic_ed); - free (OHCI_INST (controller)); - free (controller); -} - -static void -ohci_start (hci_t *controller) -{ -// TODO: turn on all operation of OHCI, but assume that it's initialized. -} - -static void -ohci_stop (hci_t *controller) -{ -// TODO: turn off all operation of OHCI -} - -static int -wait_for_ed(usbdev_t *dev, ed_t *head, int pages) -{ - usb_debug("Waiting for %d pages on dev %p with head %p\n", pages, dev, head); - /* wait for results */ - /* TOTEST: how long to wait? - * give 2s per TD (2 pages) plus another 2s for now - */ - int timeout = pages*1000 + 2000; - while (((__le32_to_cpu(head->head_pointer) & ~3) != __le32_to_cpu(head->tail_pointer)) && - !(__le32_to_cpu(head->head_pointer) & 1) && - ((__le32_to_cpu((((td_t*)phys_to_virt(__le32_to_cpu(head->head_pointer) & ~3)))->config) - & TD_CC_MASK) >= TD_CC_NOACCESS) && timeout--) { - /* don't log every ms */ - if (!(timeout % 100)) - usb_debug("intst: %x; ctrl: %x; cmdst: %x; head: %x -> %x, tail: %x, condition: %x\n", - READ_OPREG(OHCI_INST(dev->controller), HcInterruptStatus), - READ_OPREG(OHCI_INST(dev->controller), HcControl), - READ_OPREG(OHCI_INST(dev->controller), HcCommandStatus), - __le32_to_cpu(head->head_pointer), - __le32_to_cpu(((td_t*)phys_to_virt(__le32_to_cpu(head->head_pointer) & ~3))->next_td), - __le32_to_cpu(head->tail_pointer), - (__le32_to_cpu(((td_t*)phys_to_virt(__le32_to_cpu(head->head_pointer) & ~3))->config) & TD_CC_MASK) >> TD_CC_SHIFT); - mdelay(1); - } - if (timeout < 0) - usb_debug("Error: ohci: endpoint " - "descriptor processing timed out.\n"); - /* Clear the done queue. */ - ohci_process_done_queue(OHCI_INST(dev->controller), 1); - - if (__le32_to_cpu(head->head_pointer) & 1) { - usb_debug("HALTED!\n"); - return 1; - } - return 0; -} - -static void -ohci_free_ed (ed_t *const head) -{ - /* In case the transfer canceled, we have to free unprocessed TDs. */ - while ((__le32_to_cpu(head->head_pointer) & ~0x3) != __le32_to_cpu(head->tail_pointer)) { - /* Save current TD pointer. */ - td_t *const cur_td = - (td_t*)phys_to_virt(__le32_to_cpu(head->head_pointer) & ~0x3); - /* Advance head pointer. */ - head->head_pointer = cur_td->next_td; - /* Free current TD. */ - free((void *)cur_td); - } - - /* Always free the dummy TD */ - if ((__le32_to_cpu(head->head_pointer) & ~0x3) == __le32_to_cpu(head->tail_pointer)) - free(phys_to_virt(__le32_to_cpu(head->head_pointer) & ~0x3)); - /* and the ED. */ - free((void *)head); -} - -static int -ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen, - unsigned char *data) -{ - td_t *cur; - - // pages are specified as 4K in OHCI, so don't use getpagesize() - int first_page = (unsigned long)data / 4096; - int last_page = (unsigned long)(data+dalen-1)/4096; - if (last_page < first_page) last_page = first_page; - int pages = (dalen==0)?0:(last_page - first_page + 1); - - /* First TD. */ - td_t *const first_td; - ofmem_posix_memalign((void **)&first_td, sizeof(td_t), sizeof(td_t)); - memset((void *)first_td, 0, sizeof(*first_td)); - cur = first_td; - - cur->config = __cpu_to_le32(TD_DIRECTION_SETUP | - TD_DELAY_INTERRUPT_NOINTR | - TD_TOGGLE_FROM_TD | - TD_TOGGLE_DATA0 | - TD_CC_NOACCESS); - cur->current_buffer_pointer = __cpu_to_le32(virt_to_phys(devreq)); - cur->buffer_end = __cpu_to_le32(virt_to_phys((char *)devreq + drlen - 1)); - - while (pages > 0) { - /* One more TD. */ - td_t *const next; - ofmem_posix_memalign((void **)&next, sizeof(td_t), sizeof(td_t)); - memset((void *)next, 0, sizeof(*next)); - /* Linked to the previous. */ - cur->next_td = __cpu_to_le32(virt_to_phys(next)); - /* Advance to the new TD. */ - cur = next; - - cur->config = __cpu_to_le32((dir == IN ? TD_DIRECTION_IN : TD_DIRECTION_OUT) | - TD_DELAY_INTERRUPT_NOINTR | - TD_TOGGLE_FROM_ED | - TD_CC_NOACCESS); - cur->current_buffer_pointer = __cpu_to_le32(virt_to_phys(data)); - pages--; - int consumed = (4096 - ((unsigned long)data % 4096)); - if (consumed >= dalen) { - // end of data is within same page - cur->buffer_end = __cpu_to_le32(virt_to_phys(data + dalen - 1)); - dalen = 0; - /* assert(pages == 0); */ - } else { - dalen -= consumed; - data += consumed; - pages--; - int second_page_size = dalen; - if (dalen > 4096) { - second_page_size = 4096; - } - cur->buffer_end = __cpu_to_le32(virt_to_phys(data + second_page_size - 1)); - dalen -= second_page_size; - data += second_page_size; - } - } - - /* One more TD. */ - td_t *const next_td; - ofmem_posix_memalign((void **)&next_td, sizeof(td_t), sizeof(td_t)); - memset((void *)next_td, 0, sizeof(*next_td)); - /* Linked to the previous. */ - cur->next_td = __cpu_to_le32(virt_to_phys(next_td)); - /* Advance to the new TD. */ - cur = next_td; - cur->config = __cpu_to_le32((dir == IN ? TD_DIRECTION_OUT : TD_DIRECTION_IN) | - TD_DELAY_INTERRUPT_ZERO | /* Write done head after this TD. */ - TD_TOGGLE_FROM_TD | - TD_TOGGLE_DATA1 | - TD_CC_NOACCESS); - cur->current_buffer_pointer = 0; - cur->buffer_end = 0; - - /* Final dummy TD. */ - td_t *const final_td; - ofmem_posix_memalign((void **)&final_td, sizeof(td_t), sizeof(td_t)); - memset((void *)final_td, 0, sizeof(*final_td)); - /* Linked to the previous. */ - cur->next_td = __cpu_to_le32(virt_to_phys(final_td)); - - /* Data structures */ - ed_t *head; - ofmem_posix_memalign((void **)&head, sizeof(ed_t), sizeof(ed_t)); - memset((void*)head, 0, sizeof(*head)); - head->config = __cpu_to_le32((dev->address << ED_FUNC_SHIFT) | - (0 << ED_EP_SHIFT) | - (OHCI_FROM_TD << ED_DIR_SHIFT) | - (dev->speed?ED_LOWSPEED:0) | - (dev->endpoints[0].maxpacketsize << ED_MPS_SHIFT)); - head->tail_pointer = __cpu_to_le32(virt_to_phys(final_td)); - head->head_pointer = __cpu_to_le32(virt_to_phys(first_td)); - - usb_debug("ohci_control(): doing transfer with %x. first_td at %x\n", - __le32_to_cpu(head->config) & ED_FUNC_MASK, __le32_to_cpu(head->head_pointer)); -#ifdef USB_DEBUG_ED - dump_ed(head); -#endif - - /* activate schedule */ - OHCI_INST(dev->controller)->opreg->HcControlHeadED = __cpu_to_le32(virt_to_phys(head)); - OHCI_INST(dev->controller)->opreg->HcControl |= __cpu_to_le32(ControlListEnable); - OHCI_INST(dev->controller)->opreg->HcCommandStatus = __cpu_to_le32(ControlListFilled); - - int failure = wait_for_ed(dev, head, - (dalen==0)?0:(last_page - first_page + 1)); - /* Wait some frames before and one after disabling list access. */ - mdelay(4); - OHCI_INST(dev->controller)->opreg->HcControl &= __cpu_to_le32(~ControlListEnable); - mdelay(1); - - /* free memory */ - ohci_free_ed(head); - - return failure; -} - -/* finalize == 1: if data is of packet aligned size, add a zero length packet */ -static int -ohci_bulk (endpoint_t *ep, int dalen, u8 *data, int finalize) -{ - int i; - usb_debug("bulk: %x bytes from %p, finalize: %x, maxpacketsize: %x\n", dalen, data, finalize, ep->maxpacketsize); - - td_t *cur, *next; - - // pages are specified as 4K in OHCI, so don't use getpagesize() - int first_page = (unsigned long)data / 4096; - int last_page = (unsigned long)(data+dalen-1)/4096; - if (last_page < first_page) last_page = first_page; - int pages = (dalen==0)?0:(last_page - first_page + 1); - int td_count = (pages+1)/2; - - if (finalize && ((dalen % ep->maxpacketsize) == 0)) { - td_count++; - } - - /* First TD. */ - td_t *const first_td; - ofmem_posix_memalign((void **)&first_td, sizeof(td_t), sizeof(td_t)); - memset((void *)first_td, 0, sizeof(*first_td)); - cur = next = first_td; - - for (i = 0; i < td_count; ++i) { - /* Advance to next TD. */ - cur = next; - cur->config = __cpu_to_le32((ep->direction == IN ? TD_DIRECTION_IN : TD_DIRECTION_OUT) | - TD_DELAY_INTERRUPT_NOINTR | - TD_TOGGLE_FROM_ED | - TD_CC_NOACCESS); - cur->current_buffer_pointer = __cpu_to_le32(virt_to_phys(data)); - pages--; - if (dalen == 0) { - /* magic TD for empty packet transfer */ - cur->current_buffer_pointer = 0; - cur->buffer_end = 0; - /* assert((pages == 0) && finalize); */ - } - int consumed = (4096 - ((unsigned long)data % 4096)); - if (consumed >= dalen) { - // end of data is within same page - cur->buffer_end = __cpu_to_le32(virt_to_phys(data + dalen - 1)); - dalen = 0; - /* assert(pages == finalize); */ - } else { - dalen -= consumed; - data += consumed; - pages--; - int second_page_size = dalen; - if (dalen > 4096) { - second_page_size = 4096; - } - cur->buffer_end = __cpu_to_le32(virt_to_phys(data + second_page_size - 1)); - dalen -= second_page_size; - data += second_page_size; - } - /* One more TD. */ - ofmem_posix_memalign((void **)&next, sizeof(td_t), sizeof(td_t)); - memset((void *)next, 0, sizeof(*next)); - /* Linked to the previous. */ - cur->next_td = __cpu_to_le32(virt_to_phys(next)); - } - - /* Write done head after last TD. */ - cur->config &= __cpu_to_le32(~TD_DELAY_INTERRUPT_MASK); - /* Advance to final, dummy TD. */ - cur = next; - - /* Data structures */ - ed_t *head; - ofmem_posix_memalign((void **)&head, sizeof(ed_t), sizeof(ed_t)); - memset((void*)head, 0, sizeof(*head)); - head->config = __cpu_to_le32((ep->dev->address << ED_FUNC_SHIFT) | - ((ep->endpoint & 0xf) << ED_EP_SHIFT) | - (((ep->direction==IN)?OHCI_IN:OHCI_OUT) << ED_DIR_SHIFT) | - (ep->dev->speed?ED_LOWSPEED:0) | - (ep->maxpacketsize << ED_MPS_SHIFT)); - head->tail_pointer = __cpu_to_le32(virt_to_phys(cur)); - head->head_pointer = __cpu_to_le32(virt_to_phys(first_td) | (ep->toggle?ED_TOGGLE:0)); - - usb_debug("doing bulk transfer with %x(%x). first_td at %lx, last %lx\n", - __le32_to_cpu(head->config) & ED_FUNC_MASK, - (__le32_to_cpu(head->config) & ED_EP_MASK) >> ED_EP_SHIFT, - virt_to_phys(first_td), virt_to_phys(cur)); - - /* activate schedule */ - OHCI_INST(ep->dev->controller)->opreg->HcBulkHeadED = __cpu_to_le32(virt_to_phys(head)); - OHCI_INST(ep->dev->controller)->opreg->HcControl |= __cpu_to_le32(BulkListEnable); - OHCI_INST(ep->dev->controller)->opreg->HcCommandStatus = __cpu_to_le32(BulkListFilled); - - int failure = wait_for_ed(ep->dev, head, - (dalen==0)?0:(last_page - first_page + 1)); - /* Wait some frames before and one after disabling list access. */ - mdelay(4); - OHCI_INST(ep->dev->controller)->opreg->HcControl &= __cpu_to_le32(~BulkListEnable); - mdelay(1); - - ep->toggle = __le32_to_cpu(head->head_pointer) & ED_TOGGLE; - - /* free memory */ - ohci_free_ed(head); - - if (failure) { - /* try cleanup */ - clear_stall(ep); - } - - return failure; -} - - -struct _intr_queue; - -struct _intrq_td { - volatile td_t td; - u8 *data; - struct _intrq_td *next; - struct _intr_queue *intrq; -}; - -struct _intr_queue { - volatile ed_t ed; - struct _intrq_td *head; - struct _intrq_td *tail; - u8 *data; - int reqsize; - endpoint_t *endp; - unsigned int remaining_tds; - int destroy; -}; - -typedef struct _intrq_td intrq_td_t; -typedef struct _intr_queue intr_queue_t; - -#define INTRQ_TD_FROM_TD(x) ((intrq_td_t *)x) - -static void -ohci_fill_intrq_td(intrq_td_t *const td, intr_queue_t *const intrq, - u8 *const data) -{ - memset(td, 0, sizeof(*td)); - td->td.config = __cpu_to_le32(TD_QUEUETYPE_INTR | - (intrq->endp->direction == IN ? TD_DIRECTION_IN : TD_DIRECTION_OUT) | - TD_DELAY_INTERRUPT_ZERO | - TD_TOGGLE_FROM_ED | - TD_CC_NOACCESS); - td->td.current_buffer_pointer = __cpu_to_le32(virt_to_phys(data)); - td->td.buffer_end = __cpu_to_le32(virt_to_phys(data) + intrq->reqsize - 1); - td->intrq = intrq; - td->data = data; -} - -/* create and hook-up an intr queue into device schedule */ -static void * -ohci_create_intr_queue(endpoint_t *const ep, const int reqsize, - const int reqcount, const int reqtiming) -{ - int i; - intrq_td_t *first_td = NULL, *last_td = NULL; - - if (reqsize > 4096) - return NULL; - - intr_queue_t *const intrq; - ofmem_posix_memalign((void **)&intrq, sizeof(intrq->ed), sizeof(*intrq)); - memset(intrq, 0, sizeof(*intrq)); - intrq->data = (u8 *)malloc(reqcount * reqsize); - intrq->reqsize = reqsize; - intrq->endp = ep; - - /* Create #reqcount TDs. */ - u8 *cur_data = intrq->data; - for (i = 0; i < reqcount; ++i) { - intrq_td_t *const td; - ofmem_posix_memalign((void **)&td, sizeof(td->td), sizeof(*td)); - ++intrq->remaining_tds; - ohci_fill_intrq_td(td, intrq, cur_data); - cur_data += reqsize; - if (!first_td) - first_td = td; - else - last_td->td.next_td = __cpu_to_le32(virt_to_phys(&td->td)); - last_td = td; - } - - /* Create last, dummy TD. */ - intrq_td_t *dummy_td; - ofmem_posix_memalign((void **)&dummy_td, sizeof(dummy_td->td), sizeof(*dummy_td)); - memset(dummy_td, 0, sizeof(*dummy_td)); - dummy_td->intrq = intrq; - if (last_td) - last_td->td.next_td = __cpu_to_le32(virt_to_phys(&dummy_td->td)); - last_td = dummy_td; - - /* Initialize ED. */ - intrq->ed.config = __cpu_to_le32((ep->dev->address << ED_FUNC_SHIFT) | - ((ep->endpoint & 0xf) << ED_EP_SHIFT) | - (((ep->direction == IN) ? OHCI_IN : OHCI_OUT) << ED_DIR_SHIFT) | - (ep->dev->speed ? ED_LOWSPEED : 0) | - (ep->maxpacketsize << ED_MPS_SHIFT)); - intrq->ed.tail_pointer = __cpu_to_le32(virt_to_phys(last_td)); - intrq->ed.head_pointer = __cpu_to_le32(virt_to_phys(first_td) | (ep->toggle ? ED_TOGGLE : 0)); - -#ifdef USB_DEBUG_ED - dump_ed(&intrq->ed); -#endif - /* Insert ED into periodic table. */ - int nothing_placed = 1; - ohci_t *const ohci = OHCI_INST(ep->dev->controller); - u32 *const intr_table = ohci->hcca->HccaInterruptTable; - const u32 dummy_ptr = __cpu_to_le32(virt_to_phys(ohci->periodic_ed)); - for (i = 0; i < 32; i += reqtiming) { - /* Advance to the next free position. */ - while ((i < 32) && (intr_table[i] != dummy_ptr)) ++i; - if (i < 32) { - usb_debug("Placed endpoint %lx to %d\n", virt_to_phys(&intrq->ed), i); - intr_table[i] = __cpu_to_le32(virt_to_phys(&intrq->ed)); - nothing_placed = 0; - } - } - if (nothing_placed) { - usb_debug("Error: Failed to place ohci interrupt endpoint " - "descriptor into periodic table: no space left\n"); - ohci_destroy_intr_queue(ep, intrq); - return NULL; - } - - return intrq; -} - -/* remove queue from device schedule, dropping all data that came in */ -static void -ohci_destroy_intr_queue(endpoint_t *const ep, void *const q_) -{ - intr_queue_t *const intrq = (intr_queue_t *)q_; - - int i; - - /* Remove interrupt queue from periodic table. */ - ohci_t *const ohci = OHCI_INST(ep->dev->controller); - u32 *const intr_table = ohci->hcca->HccaInterruptTable; - for (i=0; i < 32; ++i) { - if (intr_table[i] == __cpu_to_le32(virt_to_phys(intrq))) - intr_table[i] = __cpu_to_le32(virt_to_phys(ohci->periodic_ed)); - } - /* Wait for frame to finish. */ - mdelay(1); - - /* Free unprocessed TDs. */ - while ((__le32_to_cpu(intrq->ed.head_pointer) & ~0x3) != __le32_to_cpu(intrq->ed.tail_pointer)) { - td_t *const cur_td = (td_t *)phys_to_virt(__le32_to_cpu(intrq->ed.head_pointer) & ~0x3); - intrq->ed.head_pointer = cur_td->next_td; - free(INTRQ_TD_FROM_TD(cur_td)); - --intrq->remaining_tds; - } - /* Free final, dummy TD. */ - free(phys_to_virt(__le32_to_cpu(intrq->ed.head_pointer) & ~0x3)); - /* Free data buffer. */ - free(intrq->data); - - /* Free TDs already fetched from the done queue. */ - ohci_process_done_queue(ohci, 1); - while (intrq->head) { - intrq_td_t *const cur_td = (intrq_td_t *const )__le32_to_cpu(intrq->head); - intrq->head = intrq->head->next; - free(cur_td); - --intrq->remaining_tds; - } - - /* Mark interrupt queue to be destroyed. - ohci_process_done_queue() will free the remaining TDs - and finish the interrupt queue off once all TDs are gone. */ - intrq->destroy = 1; - - /* Save data toggle. */ - ep->toggle = __le32_to_cpu(intrq->ed.head_pointer) & ED_TOGGLE; -} - -/* read one intr-packet from queue, if available. extend the queue for new input. - return NULL if nothing new available. - Recommended use: while (data=poll_intr_queue(q)) process(data); - */ -static u8 * -ohci_poll_intr_queue(void *const q_) -{ - intr_queue_t *const intrq = (intr_queue_t *)q_; - - u8 *data = NULL; - - /* Process done queue first, then check if we have work to do. */ - ohci_process_done_queue(OHCI_INST(intrq->endp->dev->controller), 0); - - if (intrq->head) { - /* Save pointer to processed TD and advance. */ - intrq_td_t *const cur_td = intrq->head; - intrq->head = cur_td->next; - - /* Return data buffer of this TD. */ - data = cur_td->data; - - /* Requeue this TD (i.e. copy to dummy and requeue as dummy). */ - intrq_td_t *const dummy_td = - INTRQ_TD_FROM_TD(phys_to_virt(__le32_to_cpu(intrq->ed.tail_pointer))); - ohci_fill_intrq_td(dummy_td, intrq, data); - /* Reset all but intrq pointer (i.e. init as dummy). */ - memset(cur_td, 0, sizeof(*cur_td)); - cur_td->intrq = intrq; - /* Insert into interrupt queue as dummy. */ - dummy_td->td.next_td = __le32_to_cpu(virt_to_phys(&cur_td->td)); - intrq->ed.tail_pointer = __le32_to_cpu(virt_to_phys(&cur_td->td)); - } - - return data; -} - -static void -ohci_process_done_queue(ohci_t *const ohci, const int spew_debug) -{ - int i, j; - - /* Temporary queue of interrupt queue TDs (to reverse order). */ - intrq_td_t *temp_tdq = NULL; - - /* Check if done head has been written. */ - if (!(READ_OPREG(ohci, HcInterruptStatus) & WritebackDoneHead)) - return; - /* Fetch current done head. - Lsb is only interesting for hw interrupts. */ - u32 phys_done_queue = __le32_to_cpu(ohci->hcca->HccaDoneHead) & ~1; - /* Tell host controller, he may overwrite the done head pointer. */ - ohci->opreg->HcInterruptStatus = __cpu_to_le32(WritebackDoneHead); - - i = 0; - /* Process done queue (it's in reversed order). */ - while (phys_done_queue) { - td_t *const done_td = (td_t *)phys_to_virt(phys_done_queue); - - /* Advance pointer to next TD. */ - phys_done_queue = __le32_to_cpu(done_td->next_td); - - switch (__le32_to_cpu(done_td->config) & TD_QUEUETYPE_MASK) { - case TD_QUEUETYPE_ASYNC: - /* Free processed async TDs. */ - free((void *)done_td); - break; - case TD_QUEUETYPE_INTR: { - intrq_td_t *const td = INTRQ_TD_FROM_TD(done_td); - intr_queue_t *const intrq = td->intrq; - /* Check if the corresponding interrupt - queue is still beeing processed. */ - if (intrq->destroy) { - /* Free this TD, and */ - free(td); - --intrq->remaining_tds; - /* the interrupt queue if it has no more TDs. */ - if (!intrq->remaining_tds) - free(intrq); - usb_debug("Freed TD from orphaned interrupt " - "queue, %d TDs remain.\n", - intrq->remaining_tds); - } else { - /* Save done TD to be processed. */ - td->next = temp_tdq; - temp_tdq = td; - } - break; - } - default: - break; - } - ++i; - } - if (spew_debug) - usb_debug("Processed %d done TDs.\n", i); - - j = 0; - /* Process interrupt queue TDs in right order. */ - while (temp_tdq) { - /* Save pointer of current TD and advance. */ - intrq_td_t *const cur_td = temp_tdq; - temp_tdq = temp_tdq->next; - - /* The interrupt queue for the current TD. */ - intr_queue_t *const intrq = cur_td->intrq; - /* Append to interrupt queue. */ - if (!intrq->head) { - /* First element. */ - intrq->head = intrq->tail = cur_td; - } else { - /* Insert at tail. */ - intrq->tail->next = cur_td; - intrq->tail = cur_td; - } - /* It's always the last element. */ - cur_td->next = NULL; - ++j; - } - if (spew_debug) - usb_debug("processed %d done tds, %d intr tds thereof.\n", i, j); -} - -int ob_usb_ohci_init (const char *path, uint32_t addr) -{ - hci_t *ctrl; - int i; - - usb_debug("ohci_init: %s addr = %x\n", path, addr); - ctrl = ohci_pci_init(addr); - if (!ctrl) - return 0; - - /* Init ports */ - usb_poll(); - - /* Look for a keyboard */ - for (i = 0; i < 128; i++) { - if (ctrl->devices[i] && ctrl->devices[i]->configuration) { - configuration_descriptor_t *cd; - interface_descriptor_t *intf; - - cd = (configuration_descriptor_t *)ctrl->devices[i]->configuration; - intf = (interface_descriptor_t *)(ctrl->devices[i]->configuration + cd->bLength); - usb_debug("Device at port %d is class %d\n", i, intf->bInterfaceClass); - if (intf->bInterfaceClass == hid_device && - intf->bInterfaceSubClass == hid_subclass_boot && - intf->bInterfaceProtocol == hid_boot_proto_keyboard ) { - break; - } - } - } - if ( i < 128 ) - ob_usb_hid_add_keyboard(path); - - return 1; -} diff --git a/qemu/roms/openbios/drivers/usbohci.h b/qemu/roms/openbios/drivers/usbohci.h deleted file mode 100644 index 690332871..000000000 --- a/qemu/roms/openbios/drivers/usbohci.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Driver for USB OHCI ported from CoreBoot - * - * Copyright (C) 2014 BALATON Zoltan - * - * This file was part of the libpayload project. - * - * Copyright (C) 2010 Patrick Georgi - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef __OHCI_H -#define __OHCI_H - -#include "config.h" -#include "usbohci_private.h" - -hci_t *ohci_pci_init (u32 addr); -hci_t *ohci_init (void *bar); - -void ohci_rh_init (usbdev_t *dev); - -#endif diff --git a/qemu/roms/openbios/drivers/usbohci_private.h b/qemu/roms/openbios/drivers/usbohci_private.h deleted file mode 100644 index 99c964100..000000000 --- a/qemu/roms/openbios/drivers/usbohci_private.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Driver for USB OHCI ported from CoreBoot - * - * Copyright (C) 2014 BALATON Zoltan - * - * This file was part of the libpayload project. - * - * Copyright (C) 2010 Patrick Georgi - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef __OHCI_PRIVATE_H -#define __OHCI_PRIVATE_H - -#include "libc/byteorder.h" -#include "usb.h" - -#define READ_OPREG(ohci, field) (__le32_to_cpu((ohci)->opreg->field)) -#define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit)) - - // FIXME: fake - typedef enum { CMD} reg; - - extern enum { - NumberDownstreamPorts = 1<<0, - PowerSwitchingMode = 1<<8, - NoPowerSwitching = 1<<9, - DeviceType = 1<<10, - OverCurrentProtectionMode = 1<<11, - NoOverCurrentProtection = 1<<12, - PowerOnToPowerGoodTime = 1<<24 - } HcRhDescriptorAReg; - - extern enum { - NumberDownstreamPortsMask = MASK(0, 8), - PowerOnToPowerGoodTimeMask = MASK(24, 8) - } HcRhDescriptorAMask; - - extern enum { - DeviceRemovable = 1<<0, - PortPowerControlMask = 1<<16 - } HcRhDescriptorBReg; - - extern enum { - CurrentConnectStatus = 1<<0, - PortEnableStatus = 1<<1, - PortSuspendStatus = 1<<2, - PortOverCurrentIndicator = 1<<3, - PortResetStatus = 1<<4, - PortPowerStatus = 1<<8, - LowSpeedDeviceAttached = 1<<9, - ConnectStatusChange = 1<<16, - PortEnableStatusChange = 1<<17, - PortSuspendStatusChange = 1<<18, - PortOverCurrentIndicatorChange = 1<<19, - PortResetStatusChange = 1<<20 - } HcRhPortStatusRead; - extern enum { - ClearPortEnable = 1<<0, - SetPortEnable = 1<<1, - SetPortSuspend = 1<<2, - ClearSuspendStatus = 1<<3, - SetPortReset = 1<<4, - SetPortPower = 1<<8, - ClearPortPower = 1<<9, - } HcRhPortStatusSet; - - extern enum { - LocalPowerStatus = 1<<0, - OverCurrentIndicator = 1<<1, - DeviceRemoteWakeupEnable = 1<<15, - LocalPowerStatusChange = 1<<16, - OverCurrentIndicatorChange = 1<<17, - ClearRemoteWakeupEnable = 1<<31 - } HcRhStatusReg; - - extern enum { - FrameInterval = 1<<0, - FSLargestDataPacket = 1<<16, - FrameIntervalToggle = 1<<31 - } HcFmIntervalOffset; - extern enum { - FrameIntervalMask = MASK(0, 14), - FSLargestDataPacketMask = MASK(16, 15), - FrameIntervalToggleMask = MASK(31, 1) - } HcFmIntervalMask; - - extern enum { - ControlBulkServiceRatio = 1<<0, - PeriodicListEnable = 1<<2, - IsochronousEnable = 1<<3, - ControlListEnable = 1<<4, - BulkListEnable = 1<<5, - HostControllerFunctionalState = 1<<6, - InterruptRouting = 1<<8, - RemoteWakeupConnected = 1<<9, - RemoteWakeupEnable = 1<<10 - } HcControlReg; - - extern enum { - ControlBulkServiceRatioMask = MASK(0, 2), - HostControllerFunctionalStateMask = MASK(6, 2) - } HcControlMask; - - enum { - USBReset = 0*HostControllerFunctionalState, - USBResume = 1*HostControllerFunctionalState, - USBOperational = 2*HostControllerFunctionalState, - USBSuspend = 3*HostControllerFunctionalState - }; - - extern enum { - HostControllerReset = 1<<0, - ControlListFilled = 1<<1, - BulkListFilled = 1<<2, - OwnershipChangeRequest = 1<<3, - SchedulingOverrunCount = 1<<16 - } HcCommandStatusReg; - - extern enum { - SchedulingOverrunCountMask = MASK(16, 2) - } HcCommandStatusMask; - - extern enum { - FrameRemaining = 1<<0, - FrameRemainingToggle = 1<<31 - } HcFmRemainingReg; - - extern enum { - SchedulingOverrung = 1<<0, - WritebackDoneHead = 1<<1, - StartofFrame = 1<<2, - ResumeDetected = 1<<3, - UnrecoverableError = 1<<4, - FrameNumberOverflow = 1<<5, - RootHubStatusChange = 1<<6, - OwnershipChange = 1<<30 - } HcInterruptStatusReg; - - typedef struct { - // Control and Status Partition - volatile u32 HcRevision; - volatile u32 HcControl; - volatile u32 HcCommandStatus; - volatile u32 HcInterruptStatus; - volatile u32 HcInterruptEnable; - volatile u32 HcInterruptDisable; - - // Memory Pointer Partition - volatile u32 HcHCCA; - volatile u32 HcPeriodCurrentED; - volatile u32 HcControlHeadED; - volatile u32 HcControlCurrentED; - volatile u32 HcBulkHeadED; - volatile u32 HcBulkCurrentED; - volatile u32 HcDoneHead; - - // Frame Counter Partition - volatile u32 HcFmInterval; - volatile u32 HcFmRemaining; - volatile u32 HcFmNumber; - volatile u32 HcPeriodicStart; - volatile u32 HcLSThreshold; - - // Root Hub Partition - volatile u32 HcRhDescriptorA; - volatile u32 HcRhDescriptorB; - volatile u32 HcRhStatus; - /* all bits in HcRhPortStatus registers are R/WC, so - _DO NOT_ use |= to set the bits, - this clears the entire state */ - volatile u32 HcRhPortStatus[]; - } __attribute__ ((packed)) opreg_t; - - typedef struct { /* should be 256 bytes according to spec */ - u32 HccaInterruptTable[32]; - volatile u16 HccaFrameNumber; - volatile u16 HccaPad1; - volatile u32 HccaDoneHead; - u8 reserved[116]; /* pad according to spec */ - u8 what[4]; /* really pad to 256 as spec only covers 252 */ - } __attribute__ ((packed)) hcca_t; - - typedef volatile struct { - u32 config; - u32 tail_pointer; - u32 head_pointer; - u32 next_ed; - } __attribute__ ((packed)) ed_t; -#define ED_HALTED 1 -#define ED_TOGGLE 2 - -#define ED_FUNC_SHIFT 0 -#define ED_FUNC_MASK MASK(0, 7) -#define ED_EP_SHIFT 7 -#define ED_EP_MASK MASK(7, 4) -#define ED_DIR_SHIFT 11 -#define ED_DIR_MASK MASK(11, 2) -#define ED_LOWSPEED (1 << 13) -#define ED_MPS_SHIFT 16 - - typedef volatile struct { - u32 config; - u32 current_buffer_pointer; - u32 next_td; - u32 buffer_end; - } __attribute__ ((packed)) td_t; -/* - * Bits 0 through 17 of .config won't be interpreted by the host controller - * (HC) and, after processing the TD, the HC has to ensure those bits have - * the same state as before. So we are free to use those bits for our own - * purpose. - */ -#define TD_QUEUETYPE_SHIFT 0 -#define TD_QUEUETYPE_MASK MASK(TD_QUEUETYPE_SHIFT, 2) -#define TD_QUEUETYPE_ASYNC (0 << TD_QUEUETYPE_SHIFT) -#define TD_QUEUETYPE_INTR (1 << TD_QUEUETYPE_SHIFT) - -#define TD_DIRECTION_SHIFT 19 -#define TD_DIRECTION_MASK MASK(TD_DIRECTION_SHIFT, 2) -#define TD_DIRECTION_SETUP OHCI_SETUP << TD_DIRECTION_SHIFT -#define TD_DIRECTION_IN OHCI_IN << TD_DIRECTION_SHIFT -#define TD_DIRECTION_OUT OHCI_OUT << TD_DIRECTION_SHIFT -#define TD_DELAY_INTERRUPT_SHIFT 21 -#define TD_DELAY_INTERRUPT_MASK MASK(TD_DELAY_INTERRUPT_SHIFT, 3) -#define TD_DELAY_INTERRUPT_ZERO 0 -#define TD_DELAY_INTERRUPT_NOINTR (7 << TD_DELAY_INTERRUPT_SHIFT) -#define TD_TOGGLE_DATA0 0 -#define TD_TOGGLE_DATA1 (1 << 24) -#define TD_TOGGLE_FROM_ED 0 -#define TD_TOGGLE_FROM_TD (1 << 25) -#define TD_CC_SHIFT 28 -#define TD_CC_MASK MASK(TD_CC_SHIFT, 4) -#define TD_CC_NOERR 0 -#define TD_CC_NOACCESS (14 << TD_CC_SHIFT) /* the lower of the two values, so "no access" can be tested with >= */ - -#define OHCI_INST(controller) ((ohci_t*)((controller)->instance)) - - typedef struct ohci { - opreg_t *opreg; - hcca_t *hcca; - usbdev_t *roothub; - ed_t *periodic_ed; - } ohci_t; - - typedef enum { OHCI_SETUP=0, OHCI_OUT=1, OHCI_IN=2, OHCI_FROM_TD=3 } ohci_pid_t; - -#endif diff --git a/qemu/roms/openbios/drivers/usbohci_rh.c b/qemu/roms/openbios/drivers/usbohci_rh.c deleted file mode 100644 index 55503be61..000000000 --- a/qemu/roms/openbios/drivers/usbohci_rh.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Driver for USB OHCI Root Hubs ported from CoreBoot - * - * Copyright (C) 2014 BALATON Zoltan - * - * This file was part of the libpayload project. - * - * Copyright (C) 2010 Patrick Georgi - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "config.h" -#include "timer.h" -#include "usbohci_private.h" -#include "usbohci.h" - -typedef struct { - int numports; - int *port; -} rh_inst_t; - -#define RH_INST(dev) ((rh_inst_t*)(dev)->data) - -static void -ohci_rh_enable_port (usbdev_t *dev, int port) -{ - /* Reset RH port should hold 50ms with pulses of at least 10ms and - * gaps of at most 3ms (usb20 spec 7.1.7.5). - * After reset, the port will be enabled automatically (ohci spec - * 7.4.4). - */ - int total_delay = 100; /* 100 * 500us == 50ms */ - while (total_delay > 0) { - if (!(READ_OPREG(OHCI_INST(dev->controller), HcRhPortStatus[port]) - & CurrentConnectStatus)) - return; - - /* start reset */ - OHCI_INST (dev->controller)->opreg->HcRhPortStatus[port] = - __cpu_to_le32(SetPortReset); - int timeout = 200; /* timeout after 200 * 500us == 100ms */ - while ((READ_OPREG(OHCI_INST(dev->controller), HcRhPortStatus[port]) - & PortResetStatus) - && timeout--) { - udelay(500); total_delay--; - } - if (READ_OPREG(OHCI_INST(dev->controller), HcRhPortStatus[port]) - & PortResetStatus) { - usb_debug("Warning: root-hub port reset timed out.\n"); - break; - } - if ((200-timeout) < 20) { - usb_debug("Warning: port reset too short: %dms; " - "should be at least 10ms.\n", - (200-timeout)/2); - total_delay = 0; /* can happen on QEMU */ - } - /* clear reset status change */ - OHCI_INST(dev->controller)->opreg->HcRhPortStatus[port] = - __cpu_to_le32(PortResetStatusChange); - usb_debug ("rh port reset finished after %dms.\n", (200-timeout)/2); - } -} - -/* disable root hub */ -static void -ohci_rh_disable_port (usbdev_t *dev, int port) -{ - OHCI_INST (dev->controller)->opreg->HcRhPortStatus[port] = - __cpu_to_le32(ClearPortEnable); // disable port - int timeout = 50; /* timeout after 50 * 100us == 5ms */ - while ((READ_OPREG(OHCI_INST (dev->controller), HcRhPortStatus[port]) - & PortEnableStatus) - && timeout--) { - udelay(100); - } -} - -static void -ohci_rh_scanport (usbdev_t *dev, int port) -{ - if (port >= RH_INST(dev)->numports) { - usb_debug("Invalid port %d\n", port); - return; - } - - /* device registered, and device change logged, so something must have happened */ - if (RH_INST (dev)->port[port] != -1) { - usb_detach_device(dev->controller, RH_INST (dev)->port[port]); - RH_INST (dev)->port[port] = -1; - } - - /* no device attached - previously registered devices are detached, nothing left to do */ - if (!(READ_OPREG(OHCI_INST(dev->controller), HcRhPortStatus[port]) & CurrentConnectStatus)) - return; - - // clear port state change - OHCI_INST(dev->controller)->opreg->HcRhPortStatus[port] = __cpu_to_le32(ConnectStatusChange); - ohci_rh_enable_port (dev, port); - - mdelay(100); // wait for signal to stabilize - - if (!(READ_OPREG(OHCI_INST(dev->controller), HcRhPortStatus[port]) & PortEnableStatus)) { - usb_debug ("port enable failed\n"); - return; - } - - int speed = (READ_OPREG(OHCI_INST(dev->controller), HcRhPortStatus[port]) & LowSpeedDeviceAttached) != 0; - RH_INST (dev)->port[port] = usb_attach_device(dev->controller, dev->address, port, speed); -} - -static int -ohci_rh_report_port_changes (usbdev_t *dev) -{ - ohci_t *const ohcic = OHCI_INST (dev->controller); - - int i; - - for (i = 0; i < RH_INST(dev)->numports; i++) { - // maybe detach+attach happened between two scans? - if (READ_OPREG(ohcic, HcRhPortStatus[i]) & ConnectStatusChange) { - ohcic->opreg->HcRhPortStatus[i] = __cpu_to_le32(ConnectStatusChange); - usb_debug("attachment change on port %d\n", i); - return i; - } - } - - // no change - return -1; -} - -static void -ohci_rh_destroy (usbdev_t *dev) -{ - int i; - for (i = 0; i < RH_INST (dev)->numports; i++) - ohci_rh_disable_port (dev, i); - free (RH_INST (dev)); -} - -static void -ohci_rh_poll (usbdev_t *dev) -{ - ohci_t *const ohcic = OHCI_INST (dev->controller); - - int port; - - /* Check if anything changed. */ - if (!(READ_OPREG(ohcic, HcInterruptStatus) & RootHubStatusChange)) - return; - ohcic->opreg->HcInterruptStatus = __cpu_to_le32(RootHubStatusChange); - usb_debug("root hub status change\n"); - - /* Scan ports with changed connection status. */ - while ((port = ohci_rh_report_port_changes (dev)) != -1) - ohci_rh_scanport (dev, port); -} - -void -ohci_rh_init (usbdev_t *dev) -{ - int i; - - dev->destroy = ohci_rh_destroy; - dev->poll = ohci_rh_poll; - - dev->data = malloc (sizeof (rh_inst_t)); - if (!dev->data) { - printk("Not enough memory for OHCI RH.\n"); - return; - } - - RH_INST (dev)->numports = READ_OPREG(OHCI_INST(dev->controller), HcRhDescriptorA) & NumberDownstreamPortsMask; - RH_INST (dev)->port = malloc(sizeof(int) * RH_INST (dev)->numports); - usb_debug("%d ports registered\n", RH_INST (dev)->numports); - - for (i = 0; i < RH_INST (dev)->numports; i++) { - ohci_rh_enable_port (dev, i); - RH_INST (dev)->port[i] = -1; - } - - /* we can set them here because a root hub _really_ shouldn't - appear elsewhere */ - dev->address = 0; - dev->hub = -1; - dev->port = -1; - - usb_debug("rh init done\n"); -} diff --git a/qemu/roms/openbios/drivers/vga.fs b/qemu/roms/openbios/drivers/vga.fs deleted file mode 100644 index 29a043a7a..000000000 --- a/qemu/roms/openbios/drivers/vga.fs +++ /dev/null @@ -1,205 +0,0 @@ -\ -\ Fcode payload for QEMU VGA graphics card -\ -\ This is the Forth source for an Fcode payload to initialise -\ the QEMU VGA graphics card. -\ -\ (C) Copyright 2013 Mark Cave-Ayland -\ - -fcode-version3 - -\ -\ Dictionary lookups for words that don't have an FCode -\ - -: (find-xt) \ ( str len -- xt | -1 ) - $find if - exit - else - -1 - then -; - -" openbios-video-width" (find-xt) cell+ value openbios-video-width-xt -" openbios-video-height" (find-xt) cell+ value openbios-video-height-xt -" depth-bits" (find-xt) cell+ value depth-bits-xt -" line-bytes" (find-xt) cell+ value line-bytes-xt - -: openbios-video-width openbios-video-width-xt @ ; -: openbios-video-height openbios-video-height-xt @ ; -: depth-bits depth-bits-xt @ ; -: line-bytes line-bytes-xt @ ; - -" fb8-fillrect" (find-xt) value fb8-fillrect-xt -: fb8-fillrect fb8-fillrect-xt execute ; - -\ -\ IO port words -\ - -" ioc!" (find-xt) value ioc!-xt -" iow!" (find-xt) value iow!-xt - -: ioc! ioc!-xt execute ; -: iow! iow!-xt execute ; - -\ -\ VGA registers -\ - -h# 3c0 constant vga-addr -h# 3c8 constant dac-write-addr -h# 3c9 constant dac-data-addr - -: vga-color! ( r g b index -- ) - \ Set the VGA colour registers - dac-write-addr ioc! rot - 2 >> dac-data-addr ioc! swap - 2 >> dac-data-addr ioc! - 2 >> dac-data-addr ioc! -; - -\ -\ VBE registers -\ - -h# 0 constant VBE_DISPI_INDEX_ID -h# 1 constant VBE_DISPI_INDEX_XRES -h# 2 constant VBE_DISPI_INDEX_YRES -h# 3 constant VBE_DISPI_INDEX_BPP -h# 4 constant VBE_DISPI_INDEX_ENABLE -h# 5 constant VBE_DISPI_INDEX_BANK -h# 6 constant VBE_DISPI_INDEX_VIRT_WIDTH -h# 7 constant VBE_DISPI_INDEX_VIRT_HEIGHT -h# 8 constant VBE_DISPI_INDEX_X_OFFSET -h# 9 constant VBE_DISPI_INDEX_Y_OFFSET -h# a constant VBE_DISPI_INDEX_NB - -h# 0 constant VBE_DISPI_DISABLED -h# 1 constant VBE_DISPI_ENABLED - -\ -\ Bochs VBE register writes -\ - -: vbe-iow! ( val addr -- ) - h# 1ce iow! - h# 1d0 iow! -; - -\ -\ Initialise Bochs VBE mode -\ - -: vbe-init ( -- ) - h# 0 vga-addr ioc! \ Enable blanking - VBE_DISPI_DISABLED VBE_DISPI_INDEX_ENABLE vbe-iow! - h# 0 VBE_DISPI_INDEX_X_OFFSET vbe-iow! - h# 0 VBE_DISPI_INDEX_Y_OFFSET vbe-iow! - openbios-video-width VBE_DISPI_INDEX_XRES vbe-iow! - openbios-video-height VBE_DISPI_INDEX_YRES vbe-iow! - depth-bits VBE_DISPI_INDEX_BPP vbe-iow! - VBE_DISPI_ENABLED VBE_DISPI_INDEX_ENABLE vbe-iow! - h# 0 vga-addr ioc! - h# 20 vga-addr ioc! \ Disable blanking -; - -\ -\ PCI -\ - -" pci-bar>pci-addr" (find-xt) value pci-bar>pci-addr-xt -: pci-bar>pci-addr pci-bar>pci-addr-xt execute ; - -h# 10 constant cfg-bar0 \ Framebuffer BAR --1 value fb-addr - -: map-fb ( -- ) - cfg-bar0 pci-bar>pci-addr if \ ( pci-addr.lo pci-addr.mid pci-addr.hi size ) - " pci-map-in" $call-parent - to fb-addr - then -; - -\ -\ Publically visible words -\ - -external - -[IFDEF] CONFIG_MOL -defer mol-color! - -\ Hook for MOL (see packages/molvideo.c) -\ -\ Perhaps for neatness this there should be a separate molvga.fs -\ but let's leave it here for now. - -: color! ( r g b index -- ) - mol-color! -; - -[ELSE] - -\ Standard VGA - -: color! ( r g b index -- ) - vga-color! -; - -[THEN] - -: fill-rectangle ( color_ind x y width height -- ) - fb8-fillrect -; - -: dimensions ( -- width height ) - openbios-video-width - openbios-video-height -; - -: set-colors ( table start count -- ) - 0 do - over dup \ ( table start table table ) - c@ swap 1+ \ ( table start r table-g ) - dup c@ swap 1+ \ ( table start r g table-b ) - c@ 3 pick \ ( table start r g b index ) - color! \ ( table start ) - 1+ - swap 3 + swap \ ( table+3 start+1 ) - loop -; - -headerless - -\ -\ Installation -\ - -: qemu-vga-driver-install ( -- ) - fb-addr -1 = if - map-fb fb-addr to frame-buffer-adr - default-font set-font - - frame-buffer-adr encode-int " address" property - - openbios-video-width openbios-video-height over char-width / over char-height / - fb8-install - then -; - -: qemu-vga-driver-init - - vbe-init - openbios-video-width encode-int " width" property - openbios-video-height encode-int " height" property - depth-bits encode-int " depth" property - line-bytes encode-int " linebytes" property - - ['] qemu-vga-driver-install is-install -; - -qemu-vga-driver-init - -end0 diff --git a/qemu/roms/openbios/drivers/vga.h b/qemu/roms/openbios/drivers/vga.h deleted file mode 100644 index a37e66e62..000000000 --- a/qemu/roms/openbios/drivers/vga.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * - * modified - * by Steve M. Gehlbach - * - * Originally from linux/drivers/video/vga16.c by - * Ben Pfaff and Petr Vandrovec - * Copyright 1999 Ben Pfaff and Petr Vandrovec - * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm - * Based on VESA framebuffer (c) 1998 Gerd Knorr - * - */ - -#ifndef VGA_H_INCL -#define VGA_H_INCL 1 - -#include "drivers/vga.h" - -//#include - -#define u8 unsigned char -#define u16 unsigned short -#define u32 unsigned int -#define __u32 u32 - -#define VERROR -1 -#define CHAR_HEIGHT 16 -#define LINES 25 -#define COLS 80 - -// macros for writing to vga regs -#define write_crtc(data,addr) outb(addr,CRT_IC); outb(data,CRT_DC) -#define write_att(data,addr) inb(IS1_RC); inb(0x80); outb(addr,ATT_IW); inb(0x80); outb(data,ATT_IW); inb(0x80) -#define write_seq(data,addr) outb(addr,SEQ_I); outb(data,SEQ_D) -#define write_gra(data,addr) outb(addr,GRA_I); outb(data,GRA_D) -u8 read_seq_b(u16 addr); -u8 read_gra_b(u16 addr); -u8 read_crtc_b(u16 addr); -u8 read_att_b(u16 addr); - - -#ifdef VGA_HARDWARE_FIXUP -void vga_hardware_fixup(void); -#else -#define vga_hardware_fixup() do{} while(0) -#endif - -#define SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */ -#define SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */ -#define SYNC_EXT 4 /* external sync */ -#define SYNC_COMP_HIGH_ACT 8 /* composite sync high active */ -#define SYNC_BROADCAST 16 /* broadcast video timings */ - /* vtotal = 144d/288n/576i => PAL */ - /* vtotal = 121d/242n/484i => NTSC */ - -#define SYNC_ON_GREEN 32 /* sync on green */ - -#define VMODE_NONINTERLACED 0 /* non interlaced */ -#define VMODE_INTERLACED 1 /* interlaced */ -#define VMODE_DOUBLE 2 /* double scan */ -#define VMODE_MASK 255 - -#define VMODE_YWRAP 256 /* ywrap instead of panning */ -#define VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ -#define VMODE_CONUPDATE 512 /* don't update x/yoffset */ - -/* VGA data register ports */ -#define CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */ -#define CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */ -#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */ -#define GRA_D 0x3CF /* Graphics Controller Data Register */ -#define SEQ_D 0x3C5 /* Sequencer Data Register */ - -#define MIS_R 0x3CC // Misc Output Read Register -#define MIS_W 0x3C2 // Misc Output Write Register - -#define IS1_RC 0x3DA /* Input Status Register 1 - color emulation */ -#define IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */ -#define PEL_D 0x3C9 /* PEL Data Register */ -#define PEL_MSK 0x3C6 /* PEL mask register */ - -/* EGA-specific registers */ -#define GRA_E0 0x3CC /* Graphics enable processor 0 */ -#define GRA_E1 0x3CA /* Graphics enable processor 1 */ - - -/* VGA index register ports */ -#define CRT_IC 0x3D4 /* CRT Controller Index - color emulation */ -#define CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */ -#define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */ -#define GRA_I 0x3CE /* Graphics Controller Index */ -#define SEQ_I 0x3C4 /* Sequencer Index */ -#define PEL_IW 0x3C8 /* PEL Write Index */ -#define PEL_IR 0x3C7 /* PEL Read Index */ -#define DAC_REG 0x3C8 /* DAC register */ -#define DAC_VAL 0x3C9 /* DAC value */ - -/* standard VGA indexes max counts */ -#define CRTC_C 25 /* 25 CRT Controller Registers sequentially set*/ - // the remainder are not in the par array -#define ATT_C 21 /* 21 Attribute Controller Registers */ -#define GRA_C 9 /* 9 Graphics Controller Registers */ -#define SEQ_C 5 /* 5 Sequencer Registers */ -#define MIS_C 1 /* 1 Misc Output Register */ - -#define CRTC_H_TOTAL 0 -#define CRTC_H_DISP 1 -#define CRTC_H_BLANK_START 2 -#define CRTC_H_BLANK_END 3 -#define CRTC_H_SYNC_START 4 -#define CRTC_H_SYNC_END 5 -#define CRTC_V_TOTAL 6 -#define CRTC_OVERFLOW 7 -#define CRTC_PRESET_ROW 8 -#define CRTC_MAX_SCAN 9 -#define CRTC_CURSOR_START 0x0A -#define CRTC_CURSOR_END 0x0B -#define CRTC_START_HI 0x0C -#define CRTC_START_LO 0x0D -#define CRTC_CURSOR_HI 0x0E -#define CRTC_CURSOR_LO 0x0F -#define CRTC_V_SYNC_START 0x10 -#define CRTC_V_SYNC_END 0x11 -#define CRTC_V_DISP_END 0x12 -#define CRTC_OFFSET 0x13 -#define CRTC_UNDERLINE 0x14 -#define CRTC_V_BLANK_START 0x15 -#define CRTC_V_BLANK_END 0x16 -#define CRTC_MODE 0x17 -#define CRTC_LINE_COMPARE 0x18 - -#define ATC_MODE 0x10 -#define ATC_OVERSCAN 0x11 -#define ATC_PLANE_ENABLE 0x12 -#define ATC_PEL 0x13 -#define ATC_COLOR_PAGE 0x14 - -#define SEQ_CLOCK_MODE 0x01 -#define SEQ_PLANE_WRITE 0x02 -#define SEQ_CHARACTER_MAP 0x03 -#define SEQ_MEMORY_MODE 0x04 - -#define GDC_SR_VALUE 0x00 -#define GDC_SR_ENABLE 0x01 -#define GDC_COMPARE_VALUE 0x02 -#define GDC_DATA_ROTATE 0x03 -#define GDC_PLANE_READ 0x04 -#define GDC_MODE 0x05 -#define GDC_MISC 0x06 -#define GDC_COMPARE_MASK 0x07 -#define GDC_BIT_MASK 0x08 - -// text attributes -#define VGA_ATTR_CLR_RED 0x4 -#define VGA_ATTR_CLR_GRN 0x2 -#define VGA_ATTR_CLR_BLU 0x1 -#define VGA_ATTR_CLR_YEL (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN) -#define VGA_ATTR_CLR_CYN (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) -#define VGA_ATTR_CLR_MAG (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED) -#define VGA_ATTR_CLR_BLK 0 -#define VGA_ATTR_CLR_WHT (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) -#define VGA_ATTR_BNK 0x80 -#define VGA_ATTR_ITN 0x08 - -/* - * vga register parameters - * these are copied to the - * registers. - * - */ -struct vga_par { - u8 crtc[CRTC_C]; - u8 atc[ATT_C]; - u8 gdc[GRA_C]; - u8 seq[SEQ_C]; - u8 misc; // the misc register, MIS_W - u8 vss; -}; - - -/* Interpretation of offset for color fields: All offsets are from the right, - * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you - * can use the offset as right argument to <<). A pixel afterwards is a bit - * stream and is written to video memory as that unmodified. This implies - * big-endian byte order if bits_per_pixel is greater than 8. - */ -struct fb_bitfield { - __u32 offset; /* beginning of bitfield */ - __u32 length; /* length of bitfield */ - __u32 msb_right; /* != 0 : Most significant bit is */ - /* right */ -}; - -struct screeninfo { - __u32 xres; /* visible resolution */ - __u32 yres; - __u32 xres_virtual; /* virtual resolution */ - __u32 yres_virtual; - __u32 xoffset; /* offset from virtual to visible */ - __u32 yoffset; /* resolution */ - - __u32 bits_per_pixel; /* guess what */ - __u32 grayscale; /* != 0 Graylevels instead of colors */ - - struct fb_bitfield red; /* bitfield in fb mem if true color, */ - struct fb_bitfield green; /* else only length is significant */ - struct fb_bitfield blue; - struct fb_bitfield transp; /* transparency */ - - __u32 nonstd; /* != 0 Non standard pixel format */ - - __u32 activate; /* see FB_ACTIVATE_* */ - - __u32 height; /* height of picture in mm */ - __u32 width; /* width of picture in mm */ - - __u32 accel_flags; /* acceleration flags (hints) */ - - /* Timing: All values in pixclocks, except pixclock (of course) */ - __u32 pixclock; /* pixel clock in ps (pico seconds) */ - __u32 left_margin; /* time from sync to picture */ - __u32 right_margin; /* time from picture to sync */ - __u32 upper_margin; /* time from sync to picture */ - __u32 lower_margin; - __u32 hsync_len; /* length of horizontal sync */ - __u32 vsync_len; /* length of vertical sync */ - __u32 sync; /* sync polarity */ - __u32 vmode; /* interlaced etc */ - __u32 reserved[6]; /* Reserved for future compatibility */ -}; -#endif diff --git a/qemu/roms/openbios/drivers/vga_load_regs.c b/qemu/roms/openbios/drivers/vga_load_regs.c deleted file mode 100644 index dda6b798a..000000000 --- a/qemu/roms/openbios/drivers/vga_load_regs.c +++ /dev/null @@ -1,496 +0,0 @@ -#include "asm/io.h" -#include "drivers/vga.h" -#include "vga.h" - -/* - * $Id$ - * $Source$ - * - * from the Linux kernel code base. - * orig by Ben Pfaff and Petr Vandrovec. - * - * modified by - * Steve M. Gehlbach - * - * NOTE: to change the horiz and vertical pixels, - * change the xres,yres,xres_virt,yres_virt setting - * in the screeninfo structure below. You may also need - * to change the border settings as well. - * - * Convert the screeninfo structure to data for - * writing to the vga registers - * - */ - -// prototypes -static int vga_decode_var(const struct screeninfo *var, struct vga_par *par); -static int vga_set_regs(const struct vga_par *par); - -u8 read_seq_b(u16 addr) { - outb(addr,SEQ_I); - return inb(SEQ_D); -} -u8 read_gra_b(u16 addr) { - outb(addr,GRA_I); - return inb(GRA_D); -} -u8 read_crtc_b(u16 addr) { - outb(addr,CRT_IC); - return inb(CRT_DC); -} -u8 read_att_b(u16 addr) { - inb(IS1_RC); - inb(0x80); - outb(addr,ATT_IW); - return inb(ATT_R); -} - - -/* -From: The Frame Buffer Device -by Geert Uytterhoeven -in the linux kernel docs. - -The following picture summarizes all timings. The horizontal retrace time is -the sum of the left margin, the right margin and the hsync length, while the -vertical retrace time is the sum of the upper margin, the lower margin and the -vsync length. - - +----------+---------------------------------------------+----------+-------+ - | | ^ | | | - | | |upper_margin | | | - | | | | | | - +----------###############################################----------+-------+ - | # ^ # | | - | # | # | | - | # | # | | - | # | # | | - | left # | # right | hsync | - | margin # | xres # margin | len | - |<-------->#<---------------+--------------------------->#<-------->|<----->| - | # | # | | - | # | # | | - | # | # | | - | # |yres # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - +----------###############################################----------+-------+ - | | ^ | | | - | | |lower_margin | | | - | | | | | | - +----------+---------------------------------------------+----------+-------+ - | | ^ | | | - | | |vsync_len | | | - | | | | | | - +----------+---------------------------------------------+----------+-------+ - -All horizontal timings are in number of dotclocks -(in picoseconds, 1E-12 s), and vertical timings in number of scanlines. - -The vga uses the following fields: - - - pixclock: pixel clock in ps (pico seconds) - - xres,yres,xres_v,yres_v - - left_margin: time from sync to picture - - right_margin: time from picture to sync - - upper_margin: time from sync to picture - - lower_margin: time from picture to sync - - hsync_len: length of horizontal sync - - vsync_len: length of vertical sync - -*/ - -/* our display parameters per the above */ - -static const struct screeninfo vga_settings = { - 640,400,640,400,/* xres,yres,xres_virt,yres_virt */ - 0,0, /* xoffset,yoffset */ - 4, /* bits_per_pixel NOT USED*/ - 0, /* greyscale ? */ - {0,0,0}, /* R */ - {0,0,0}, /* G */ - {0,0,0}, /* B */ - {0,0,0}, /* transparency */ - 0, /* standard pixel format */ - 0, // activate now - -1,-1, // height and width in mm - 0, // accel flags - 39721, // pixclock: 79442 -> 12.587 Mhz (NOT USED) - // 70616 -> 14.161 - // 39721 -> 25.175 - // 35308 -> 28.322 - - 48, 16, 39, 8, // margins left,right,upper,lower - 96, // hsync length - 2, // vsync length - 0, // sync polarity - 0, // non interlaced, single mode - {0,0,0,0,0,0} // compatibility -}; - -// ALPHA-MODE -// Hard coded to BIOS VGA mode 3 (alpha color text) -// screen size settable in screeninfo structure - -static int vga_decode_var(const struct screeninfo *var, - struct vga_par *par) -{ - u8 VgaAttributeTable[16] = - { 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x014, 0x007, 0x038, 0x039, 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, 0x03F}; - - u32 xres, right, hslen, left, xtotal; - u32 yres, lower, vslen, upper, ytotal; - u32 vxres, xoffset, vyres, yoffset; - u32 pos; - u8 r7, rMode; - int i; - - xres = (var->xres + 7) & ~7; - vxres = (var->xres_virtual + 0xF) & ~0xF; - xoffset = (var->xoffset + 7) & ~7; - left = (var->left_margin + 7) & ~7; - right = (var->right_margin + 7) & ~7; - hslen = (var->hsync_len + 7) & ~7; - - if (vxres < xres) - vxres = xres; - if (xres + xoffset > vxres) - xoffset = vxres - xres; - - xres >>= 3; - right >>= 3; - hslen >>= 3; - left >>= 3; - vxres >>= 3; - xtotal = xres + right + hslen + left; - if (xtotal >= 256) - return VERROR; //xtotal too big - if (hslen > 32) - return VERROR; //hslen too big - if (right + hslen + left > 64) - return VERROR; //hblank too big - par->crtc[CRTC_H_TOTAL] = xtotal - 5; - par->crtc[CRTC_H_BLANK_START] = xres - 1; - par->crtc[CRTC_H_DISP] = xres - 1; - pos = xres + right; - par->crtc[CRTC_H_SYNC_START] = pos; - pos += hslen; - par->crtc[CRTC_H_SYNC_END] = (pos & 0x1F) | 0x20 ; //<--- stpc text mode p178 - pos += left - 2; /* blank_end + 2 <= total + 5 */ - par->crtc[CRTC_H_BLANK_END] = (pos & 0x1F) | 0x80; - if (pos & 0x20) - par->crtc[CRTC_H_SYNC_END] |= 0x80; - - yres = var->yres; - lower = var->lower_margin; - vslen = var->vsync_len; - upper = var->upper_margin; - vyres = var->yres_virtual; - yoffset = var->yoffset; - - if (yres > vyres) - vyres = yres; - if (vxres * vyres > 65536) { - vyres = 65536 / vxres; - if (vyres < yres) - return VERROR; // out of memory - } - if (yoffset + yres > vyres) - yoffset = vyres - yres; - - if (var->vmode & VMODE_DOUBLE) { - yres <<= 1; - lower <<= 1; - vslen <<= 1; - upper <<= 1; - } - ytotal = yres + lower + vslen + upper; - if (ytotal > 1024) { - ytotal >>= 1; - yres >>= 1; - lower >>= 1; - vslen >>= 1; - upper >>= 1; - rMode = 0x04; - } else - rMode = 0x00; - if (ytotal > 1024) - return VERROR; //ytotal too big - if (vslen > 16) - return VERROR; //vslen too big - par->crtc[CRTC_V_TOTAL] = ytotal - 2; - r7 = 0x10; /* disable linecompare */ - if (ytotal & 0x100) r7 |= 0x01; - if (ytotal & 0x200) r7 |= 0x20; - par->crtc[CRTC_PRESET_ROW] = 0; - - -// GMODE <--> ALPHA-MODE -// default using alpha mode so we need to set char rows= CHAR_HEIGHT-1 - par->crtc[CRTC_MAX_SCAN] = 0x40 | (CHAR_HEIGHT-1); /* 16 scanlines, linecmp max*/ - - if (var->vmode & VMODE_DOUBLE) - par->crtc[CRTC_MAX_SCAN] |= 0x80; - par->crtc[CRTC_CURSOR_START] = 0x00; // curs enabled, start line = 0 - par->crtc[CRTC_CURSOR_END] = CHAR_HEIGHT-1; // end line = 12 - pos = yoffset * vxres + (xoffset >> 3); - par->crtc[CRTC_START_HI] = pos >> 8; - par->crtc[CRTC_START_LO] = pos & 0xFF; - par->crtc[CRTC_CURSOR_HI] = 0x00; - par->crtc[CRTC_CURSOR_LO] = 0x00; - pos = yres - 1; - par->crtc[CRTC_V_DISP_END] = pos & 0xFF; - par->crtc[CRTC_V_BLANK_START] = pos & 0xFF; - if (pos & 0x100) - r7 |= 0x0A; /* 0x02 -> DISP_END, 0x08 -> BLANK_START */ - if (pos & 0x200) { - r7 |= 0x40; /* 0x40 -> DISP_END */ - par->crtc[CRTC_MAX_SCAN] |= 0x20; /* BLANK_START */ - } - pos += lower; - par->crtc[CRTC_V_SYNC_START] = pos & 0xFF; - if (pos & 0x100) - r7 |= 0x04; - if (pos & 0x200) - r7 |= 0x80; - pos += vslen; - par->crtc[CRTC_V_SYNC_END] = (pos & 0x0F) & ~0x10; /* disabled reg write prot, IRQ */ - pos += upper - 1; /* blank_end + 1 <= ytotal + 2 */ - par->crtc[CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA, - but some SVGA chips requires all 8 bits to set */ - if (vxres >= 512) - return VERROR; //vxres too long - par->crtc[CRTC_OFFSET] = vxres >> 1; - - // put the underline off of the character, necessary in alpha color mode - par->crtc[CRTC_UNDERLINE] = 0x1f; - - par->crtc[CRTC_MODE] = rMode | 0xA3; // word mode - par->crtc[CRTC_LINE_COMPARE] = 0xFF; - par->crtc[CRTC_OVERFLOW] = r7; - - - // not used ?? - par->vss = 0x00; /* 3DA */ - - for (i = 0x00; i < 0x10; i++) { - par->atc[i] = VgaAttributeTable[i]; - } - // GMODE <--> ALPHA-MODE - par->atc[ATC_MODE] = 0x0c; // text mode - - par->atc[ATC_OVERSCAN] = 0x00; // no border - par->atc[ATC_PLANE_ENABLE] = 0x0F; - par->atc[ATC_PEL] = xoffset & 7; - par->atc[ATC_COLOR_PAGE] = 0x00; - - par->misc = 0x67; /* enable CPU, ports 0x3Dx, positive sync*/ - if (var->sync & SYNC_HOR_HIGH_ACT) - par->misc &= ~0x40; - if (var->sync & SYNC_VERT_HIGH_ACT) - par->misc &= ~0x80; - - par->seq[SEQ_CLOCK_MODE] = 0x01; //8-bit char; 0x01=alpha mode - par->seq[SEQ_PLANE_WRITE] = 0x03; // just char/attr plane - par->seq[SEQ_CHARACTER_MAP] = 0x00; - par->seq[SEQ_MEMORY_MODE] = 0x02; // A/G bit not used in stpc; O/E on, C4 off - - par->gdc[GDC_SR_VALUE] = 0x00; - // bits set in the SR_EN regs will enable set/reset action - // based on the bit settings in the SR_VAL register - par->gdc[GDC_SR_ENABLE] = 0x00; - par->gdc[GDC_COMPARE_VALUE] = 0x00; - par->gdc[GDC_DATA_ROTATE] = 0x00; - par->gdc[GDC_PLANE_READ] = 0; - par->gdc[GDC_MODE] = 0x10; //Okay - - // GMODE <--> ALPHA-MMODE - par->gdc[GDC_MISC] = 0x0e; // b0=0 ->alpha mode; memory at 0xb8000 - - par->gdc[GDC_COMPARE_MASK] = 0x00; - par->gdc[GDC_BIT_MASK] = 0xFF; - - return 0; -} - -// -// originally from the stpc web site -// -static const unsigned char VgaLookupTable[3 * 0x3f + 3] = { - // Red Green Blue - 0x000, 0x000, 0x000, // 00h - 0x000, 0x000, 0x02A, // 01h - 0x000, 0x02A, 0x000, // 02h - 0x000, 0x02A, 0x02A, // 03h - 0x02A, 0x000, 0x000, // 04h - 0x02A, 0x000, 0x02A, // 05h - 0x02A, 0x02A, 0x000, // 06h - 0x02A, 0x02A, 0x02A, // 07h - 0x000, 0x000, 0x015, // 08h - 0x000, 0x000, 0x03F, // 09h - 0x000, 0x02A, 0x015, // 0Ah - 0x000, 0x02A, 0x03F, // 0Bh - 0x02A, 0x000, 0x015, // 0Ch - 0x02A, 0x000, 0x03F, // 0Dh - 0x02A, 0x02A, 0x015, // 0Eh - 0x02A, 0x02A, 0x03F, // 0Fh - 0x000, 0x015, 0x000, // 10h - 0x000, 0x015, 0x02A, // 11h - 0x000, 0x03F, 0x000, // 12h - 0x000, 0x03F, 0x02A, // 13h - 0x02A, 0x015, 0x000, // 14h - 0x02A, 0x015, 0x02A, // 15h - 0x02A, 0x03F, 0x000, // 16h - 0x02A, 0x03F, 0x02A, // 17h - 0x000, 0x015, 0x015, // 18h - 0x000, 0x015, 0x03F, // 19h - 0x000, 0x03F, 0x015, // 1Ah - 0x000, 0x03F, 0x03F, // 1Bh - 0x02A, 0x015, 0x015, // 1Ch - 0x02A, 0x015, 0x03F, // 1Dh - 0x02A, 0x03F, 0x015, // 1Eh - 0x02A, 0x03F, 0x03F, // 1Fh - 0x015, 0x000, 0x000, // 20h - 0x015, 0x000, 0x02A, // 21h - 0x015, 0x02A, 0x000, // 22h - 0x015, 0x02A, 0x02A, // 23h - 0x03F, 0x000, 0x000, // 24h - 0x03F, 0x000, 0x02A, // 25h - 0x03F, 0x02A, 0x000, // 26h - 0x03F, 0x02A, 0x02A, // 27h - 0x015, 0x000, 0x015, // 28h - 0x015, 0x000, 0x03F, // 29h - 0x015, 0x02A, 0x015, // 2Ah - 0x015, 0x02A, 0x03F, // 2Bh - 0x03F, 0x000, 0x015, // 2Ch - 0x03F, 0x000, 0x03F, // 2Dh - 0x03F, 0x02A, 0x015, // 2Eh - 0x03F, 0x02A, 0x03F, // 2Fh - 0x015, 0x015, 0x000, // 30h - 0x015, 0x015, 0x02A, // 31h - 0x015, 0x03F, 0x000, // 32h - 0x015, 0x03F, 0x02A, // 33h - 0x03F, 0x015, 0x000, // 34h - 0x03F, 0x015, 0x02A, // 35h - 0x03F, 0x03F, 0x000, // 36h - 0x03F, 0x03F, 0x02A, // 37h - 0x015, 0x015, 0x015, // 38h - 0x015, 0x015, 0x03F, // 39h - 0x015, 0x03F, 0x015, // 3Ah - 0x015, 0x03F, 0x03F, // 3Bh - 0x03F, 0x015, 0x015, // 3Ch - 0x03F, 0x015, 0x03F, // 3Dh - 0x03F, 0x03F, 0x015, // 3Eh - 0x03F, 0x03F, 0x03F, // 3Fh -}; - -/* - * From the Linux kernel. - * orig by Ben Pfaff and Petr Vandrovec. - * see the note in the vga.h for attribution. - * - * modified by - * Steve M. Gehlbach - * for the linuxbios project - * - * Write the data in the vga parameter structure - * to the vga registers, along with other default - * settings. - * - */ -static int vga_set_regs(const struct vga_par *par) -{ - int i; - - /* update misc output register */ - outb(par->misc, MIS_W); - - /* synchronous reset on */ - outb(0x00, SEQ_I); - outb(0x00, SEQ_D); - - /* write sequencer registers */ - outb(1, SEQ_I); - outb(par->seq[1] | 0x20, SEQ_D); // blank display - for (i = 2; i < SEQ_C; i++) { - outb(i, SEQ_I); - outb(par->seq[i], SEQ_D); - } - - /* synchronous reset off */ - outb(0x00, SEQ_I); - outb(0x03, SEQ_D); - - /* deprotect CRT registers 0-7 */ - outb(0x11, CRT_IC); - outb(par->crtc[0x11], CRT_DC); - - /* write CRT registers */ - for (i = 0; i < CRTC_C; i++) { - outb(i, CRT_IC); - outb(par->crtc[i], CRT_DC); - } - /* write graphics controller registers */ - for (i = 0; i < GRA_C; i++) { - outb(i, GRA_I); - outb(par->gdc[i], GRA_D); - } - - /* write attribute controller registers */ - for (i = 0; i < ATT_C; i++) { - inb(IS1_RC); /* reset flip-flop */ - inb(0x80); //delay - outb(i, ATT_IW); - inb(0x80); //delay - - outb(par->atc[i], ATT_IW); - inb(0x80); //delay - } - - // initialize the color table - outb(0, PEL_IW); - i = 0; - // length is a magic number right now - while ( i < (0x3f*3 + 3) ) { - outb(VgaLookupTable[i++], PEL_D); - outb(VgaLookupTable[i++], PEL_D); - outb(VgaLookupTable[i++], PEL_D); - } - - outb(0x0ff, PEL_MSK); // palette mask - - // very important - // turn on video, disable palette access - inb(IS1_RC); /* reset flip-flop */ - inb(0x80); //delay - outb(0x20, ATT_IW); - - /* Wait for screen to stabilize. */ - //for(i=0;i<1000;i++) { inb(0x80); } - - outb(0x01, SEQ_I); // unblank display - outb(par->seq[1], SEQ_D); - -// turn on display, disable access to attr palette - inb(IS1_RC); - outb(0x20, ATT_IW); - -return 0; -} - -void -vga_load_regs(void) -{ - struct vga_par par; - - if (vga_decode_var(&vga_settings, &par) == 0) { - vga_set_regs(&par); - } -} diff --git a/qemu/roms/openbios/drivers/vga_set_mode.c b/qemu/roms/openbios/drivers/vga_set_mode.c deleted file mode 100644 index 339ad2966..000000000 --- a/qemu/roms/openbios/drivers/vga_set_mode.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * $Id$ - * $Source$ - * - * by - * Steve M. Gehlbach - * - * These routines set graphics mode and alpha mode - * for switching back and forth. - * - * Register settings are - * more or less as follows: - * - * Register Graphics Alpha - * 16 color - * ------------------------------------------------ - * GDC_MODE 0x00 0x10 - * GDC_MISC 0x05 0x0e - * SEQ_MEMORY_MODE 0x06 0x02 - * SEQ_PLANE_WRITE 0x0f 0x03 - * CRTC_CURSOR_START 0x20 0x00 - * CRTC_CURSOR_END 0x00 CHAR_HEIGHT-1 - * CRTC_MODE 0xe3 0xa3 - * CRTC_MAX_SCAN 0x40 0x40 | CHAR_HEIGHT-1 - * ATC_MODE 0x01 0x0c - * - */ - -#include "asm/io.h" -#include "vga.h" - -void vga_set_gmode (void) { - u8 byte; - - byte = read_att_b(ATC_MODE) & ~0x0f; - write_att(byte|0x1, ATC_MODE); -// -// display is off at this point - - byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf; - write_seq(byte|0xf,SEQ_PLANE_WRITE); // all planes - byte = read_seq_b(SEQ_MEMORY_MODE); - write_seq(byte|4,SEQ_MEMORY_MODE); - - byte = read_gra_b(GDC_MODE) & ~0x10; - write_gra(byte,GDC_MODE); - write_gra(0x05, GDC_MISC); - - write_crtc(0x20, CRTC_CURSOR_START); - write_crtc(0x00, CRTC_CURSOR_END); - byte = read_crtc_b(CRTC_MODE) & ~0xe0; - write_crtc(byte|0xe0, CRTC_MODE); - byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f; - write_crtc(byte, CRTC_MAX_SCAN); - - byte = inb(MIS_R); // get 3c2 value by reading 3cc - outb(byte & ~0xc,MIS_W); // clear last bits to set 25Mhz clock and low page - - -// turn on display, disable access to attr palette - inb(IS1_RC); - outb(0x20, ATT_IW); -} - -void vga_set_amode (void) { - u8 byte; - write_att(0x0c, ATC_MODE); - - //reset palette to normal in the case it was changed - write_att(0x0, ATC_COLOR_PAGE); -// -// display is off at this point - - write_seq(0x3,SEQ_PLANE_WRITE); // planes 0 & 1 - byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x04; - write_seq(byte,SEQ_MEMORY_MODE); - - byte = read_gra_b(GDC_MODE) & ~0x60; - write_gra(byte|0x10,GDC_MODE); - - write_gra(0x0e, GDC_MISC); - - write_crtc(0x00, CRTC_CURSOR_START); - write_crtc(CHAR_HEIGHT-1, CRTC_CURSOR_END); - - byte = read_crtc_b(CRTC_MODE) & ~0xe0; - write_crtc(byte|0xa0, CRTC_MODE); - byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f; - write_crtc(byte | (CHAR_HEIGHT-1), CRTC_MAX_SCAN); - - -// turn on display, disable access to attr palette - inb(IS1_RC); - outb(0x20, ATT_IW); -} - -/* - * by Steve M. Gehlbach, Ph.D. - * - * vga_font_load loads a font into font memory. It - * assumes alpha mode has been set. - * - * The font load code follows technique used - * in the tiara project, which came from - * the Universal Talkware Boot Loader, - * http://www.talkware.net. - */ - -void vga_font_load(unsigned char *vidmem, const unsigned char *font, int height, int num_chars) { - -/* Note: the font table is 'height' long but the font storage area - * is 32 bytes long. - */ - - int i,j; - u8 byte; - - // set sequencer map 2, odd/even off - byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf; - write_seq(byte|4,SEQ_PLANE_WRITE); - byte = read_seq_b(SEQ_MEMORY_MODE); - write_seq(byte|4,SEQ_MEMORY_MODE); - - // select graphics map 2, odd/even off, map starts at 0xa0000 - write_gra(2,GDC_PLANE_READ); - byte = read_gra_b(GDC_MODE) & ~0x10; - write_gra(byte,GDC_MODE); - write_gra(0,GDC_MISC); - - for (i = 0 ; i < num_chars ; i++) { - for (j = 0 ; j < height ; j++) { - vidmem[i*32+j] = font[i*16+j]; - } - } - - // set sequencer back to maps 0,1, odd/even on - byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf; - write_seq(byte|3,SEQ_PLANE_WRITE); - byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x4; - write_seq(byte,SEQ_MEMORY_MODE); - - // select graphics back to map 0,1, odd/even on - write_gra(0,GDC_PLANE_READ); - byte = read_gra_b(GDC_MODE); - write_gra(byte|0x10,GDC_MODE); - write_gra(0xe,GDC_MISC); - -} -- cgit 1.2.3-korg