diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile new file mode 100644 index 0000000000..6c268583b9 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile @@ -0,0 +1,19 @@ +SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch m68k ; + +SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; +UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] + [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; + +SEARCH_SOURCE += [ FDirName $(SUBDIR) amiga ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) apple ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) atari ] ; + +KernelStaticLibrary pci_arch_bus_manager : + pci_controller.cpp + pci_io.c + + # platforms + pci_amiga.cpp + pci_apple.cpp + pci_atari.cpp +; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.cpp new file mode 100644 index 0000000000..a376065672 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2007, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "pci_amiga.h" + +#include +#include + +#include + + +status_t +m68k_amiga_pci_controller_init(void) +{ + return B_OK; +} + + +// #pragma mark - support functions + + diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.h new file mode 100644 index 0000000000..d9add73875 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/amiga/pci_amiga.h @@ -0,0 +1,13 @@ +/* + * Copyright 2007, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef PCI_BUS_MANAGER_M68K_AMIGA_H +#define PCI_BUS_MANAGER_M68K_AMIGA_H + +#include + +status_t m68k_amiga_pci_controller_init(void); + +#endif // PCI_BUS_MANAGER_M68K_AMIGA_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.cpp new file mode 100644 index 0000000000..756e09b054 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2007, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "pci_apple.h" + +#include +#include + +#include + + +status_t +m68k_apple_pci_controller_init(void) +{ + return B_OK; +} + + +// #pragma mark - support functions + + diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.h new file mode 100644 index 0000000000..5b49fdb4a4 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/apple/pci_apple.h @@ -0,0 +1,13 @@ +/* + * Copyright 2007, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef PCI_BUS_MANAGER_M68K_APPLE_H +#define PCI_BUS_MANAGER_M68K_APPLE_H + +#include + +status_t m68k_apple_pci_controller_init(void); + +#endif // PCI_BUS_MANAGER_M68K_APPLE_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp new file mode 100644 index 0000000000..ecd7b4778a --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp @@ -0,0 +1,262 @@ +/* + * Copyright 2007, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "pci_atari.h" + +#include +#include + +#include +#include + +#include "pci_controller.h" + +//XXX:find one and put in shared priv header! +// 0x68xx is free according to pci.ids +// 68fx (f=fake) x = 0:amiga, 1:apple, 2:atari +#define FAKEV 0x68f2 + +// bus number +#define BN 0 + +// default line size +#define DLL 1 +// default latency +#define DL 0 +// default bist +#define DB 0 + +#define PEI {0} + +#define INVV 0xffff //0x0000 ?? +#define INVD 0xffff + +struct fake_pci_device { + pci_info info; + +}; + +static struct fake_pci_device gFakePCIDevices[] = { +{ {FAKEV, 0x0000, BN, 0, 0, 0, 0xff, PCI_host, PCI_bridge, DLL, DL, DB, 0, PEI }}, /* cpu */ +{ {FAKEV, 0x0001, BN, 1, 0, 0, 0xff, 0x68/*fake*/, PCI_processor, DLL, DL, DB, 0, PEI }}, /* cpu */ +{ {FAKEV, 0x0002, BN, 2, 0, 0, 0xff, PCI_display_other, PCI_display, DLL, DL, DB, 0, $FFFF8200, PEI }}, /* gfx */ +{ {FAKEV, 0x0003, BN, 3, 0, 0, 0xff, PCI_ide, PCI_mass_storage, DLL, DL, DB, 0, $FFF00000, PEI }}, /* ide */ +{ {FAKEV, 0x0004, BN, 4, 0, 0, 0xff, PCI_scsi, PCI_mass_storage, DLL, DL, DB, 0, PEI }}, /* scsi */ +{ {FAKEV, 0x0005, BN, 5, 0, 0, 0xff, 0x, PCI_multimedia, DLL, DL, DB, 0x00, 0, $FFFF8900, PEI }}, /* snd */ +//UART ? +//centronics? +{ {INVV, INVD} } +}; +#define FAKE_DEVICES_COUNT ((sizeof(gFakePCIDevices)/sizeof(struct fake_pci_device)-1) + +#define out8rb(address, value) m68k_out8((vuint8*)(address), value) +#define out16rb(address, value) m68k_out16_reverse((vuint16*)(address), value) +#define out32rb(address, value) m68k_out32_reverse((vuint32*)(address), value) +#define in8rb(address) m68k_in8((const vuint8*)(address)) +#define in16rb(address) m68k_in16_reverse((const vuint16*)(address)) +#define in32rb(address) m68k_in32_reverse((const vuint32*)(address)) + + +static int m68k_atari_enable_config(struct m68k_atari_host_bridge *bridge, + uint8 bus, uint8 slot, uint8 function, uint8 offset); + +static status_t m68k_atari_read_pci_config(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 offset, uint8 size, uint32 *value); +static status_t m68k_atari_write_pci_config(void *cookie, uint8 bus, + uint8 device, uint8 function, uint8 offset, uint8 size, + uint32 value); +static status_t m68k_atari_get_max_bus_devices(void *cookie, int32 *count); +static status_t m68k_atari_read_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 *irq); +static status_t m68k_atari_write_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 irq); + +static pci_controller sM68kAtariPCIController = { + m68k_atari_read_pci_config, + m68k_atari_write_pci_config, + m68k_atari_get_max_bus_devices, + m68k_atari_read_pci_irq, + m68k_atari_write_pci_irq, +}; + + +static status_t +m68k_atari_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, + uint8 offset, uint8 size, uint32 *value) +{ + struct fake_pci_device *devices = (struct fake_pci_device *)cookie; + struct fake_pci_device *dev; + + if (bus != 0) + return EINVAL; + if (device >= FAKE_DEVICES_COUNT) + return EINVAL; + if (function != 0) + return EINVAL; + dev = &devices[device]; + +#define O(pn,n,s) \ + case pn: \ + if (size != s) { \ + panic("invalid pci config size %d for offset %d", size, offset); \ + return EINVAL; \ + *value = dev->n; \ + return B_OK + + if (1) { + switch (offset) { + O(PCI_vendor_id, vendor_id, 2); + O(PCI_device_id, device_id, 2); + O(PCI_revision, revision, 1); + O(PCI_class_api, class_api, 1); + O(PCI_class_sub, class_sub, 1); + O(PCI_class_base, class_base, 1); + O(PCI_line_size, line_size, 1); + O(PCI_latency, latency, 1); + O(PCI_header_type, header_type, 1); + O(PCI_bist, bist, 1); + } + } +//#undef O +#if 0 +#define PCI_command 0x04 /* (2 byte) command */ +#define PCI_status 0x06 /* (2 byte) status */ +#endif + + if (dev->header_type == 0x00 || dev->header_type == 0x01) { + switch (offset) { + case PCI_base_registers: + return EINVAL; + O(PCI_interrupt_line, h0.interrupt_line, 1); + O(PCI_interrupt_pin, h0.interrupt_pin, 1); + default: + break; + } + + if (dev->header_type == 0x00) { + switch (offset) { + default: + break; + } + + if (dev->header_type == 0x01) { + switch (offset) { + O(PCI_primary_bus, h1.primary_bus, 1); + O(PCI_secondary_bus, h1.secondary_bus, 1); + O(PCI_subordinate_bus, h1.subordinate_bus, 1); + O(PCI_secondary_latency, h1.secondary_latency, 1); + default: + break; + } + + *value = 0xffffffff; + panic("invalid pci config offset %d", offset); + return EINVAL; + //return B_OK; +} + + +static status_t m68k_atari_write_pci_config(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 offset, uint8 size, uint32 value) +{ +#if 0 + if (m68k_atari_enable_config(bridge, bus, device, function, offset)) { + switch (size) { + case 1: + out8rb(caoff, (uint8)value); + (void)in8rb(caoff); + break; + case 2: + out16rb(caoff, (uint16)value); + (void)in16rb(caoff); + break; + case 4: + out32rb(caoff, value); + (void)in32rb(caoff); + break; + } + } + +#endif + panic("write pci config dev %d offset %d", device, offset); + return B_OK; +} + + +static status_t m68k_atari_get_max_bus_devices(void *cookie, int32 *count) +{ + *count = 32; + return B_OK; +} + + +static status_t m68k_atari_read_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 *irq) +{ + return B_ERROR; +} + + +static status_t m68k_atari_write_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 irq) +{ + return B_ERROR; +} + + +// #pragma mark - + + +static int +m68k_atari_enable_config(struct m68k_atari_host_bridge *bridge, uint8 bus, + uint8 slot, uint8 function, uint8 offset) +{ +// uint32 pass; +// if (resource_int_value(device_get_name(sc->sc_dev), +// device_get_unit(sc->sc_dev), "skipslot", &pass) == 0) { +// if (pass == slot) +// return (0); +// } + + uint32 cfgval; + if (bridge->bus == bus) { + /* + * No slots less than 11 on the primary bus + */ + if (slot < 11) + return (0); + + cfgval = (1 << slot) | (function << 8) | (offset & 0xfc); + } else { + cfgval = (bus << 16) | (slot << 11) | (function << 8) | + (offset & 0xfc) | 1; + } + + do { + out32rb(bridge->address_registers, cfgval); + } while (in32rb(bridge->address_registers) != cfgval); + + return (1); +} + + +// #pragma mark - + + + + +status_t +m68k_atari_pci_controller_init(void) +{ + status_t error = pci_controller_add(&sM68kAtariPCIController, /*cookie*/); +/* if (error != B_OK) + free(bridge);*/ + return error; +} + + +// #pragma mark - support functions + + diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.h new file mode 100644 index 0000000000..e27431a044 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.h @@ -0,0 +1,13 @@ +/* + * Copyright 2007, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef PCI_BUS_MANAGER_M68K_ATARI_H +#define PCI_BUS_MANAGER_M68K_ATARI_H + +#include + +status_t m68k_atari_pci_controller_init(void); + +#endif // PCI_BUS_MANAGER_M68K_ATARI_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_openfirmware_priv.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_openfirmware_priv.h new file mode 100644 index 0000000000..bd57c6ac74 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_openfirmware_priv.h @@ -0,0 +1,50 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_PRIV_H +#define PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_PRIV_H + +#include +#include + +#include + + +struct StringArrayPropertyValue; + + +// implementations + +status_t ppc_openfirmware_probe_uninorth(int deviceNode, + const StringArrayPropertyValue &compatibleValue); + + +// property support + +struct PropertyValue { + PropertyValue() + : value(NULL) + { + } + + ~PropertyValue() + { + free(value); + } + + char *value; + int length; +}; + +struct StringArrayPropertyValue : PropertyValue { + + char *NextElement(int &cookie) const; + bool ContainsElement(const char *value) const; +}; + +status_t openfirmware_get_property(int package, const char *propertyName, + PropertyValue &value); + +#endif // PCI_BUS_MANAGER_PPC_OPEN_FIRMWARE_PRIV_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/uninorth.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/uninorth.cpp new file mode 100644 index 0000000000..4f30406170 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/uninorth.cpp @@ -0,0 +1,284 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ +/*- + * Copyright (C) 2002 Benno Rice. + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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. + * + * $FreeBSD$ + */ + +#include +#include + +#include + +#include +#include +#include + +#include "pci_controller.h" +#include "pci_io.h" +#include "pci_openfirmware_priv.h" + + +struct uninorth_range { + uint32 pci_hi; + uint32 pci_mid; + uint32 pci_lo; + uint32 host; + uint32 size_hi; + uint32 size_lo; +}; + +struct uninorth_host_bridge { + int device_node; + addr_t address_registers; + addr_t data_registers; + uint32 bus; + struct uninorth_range ranges[6]; + int range_count; +}; + + +#define out8rb(address, value) ppc_out8((vuint8*)(address), value) +#define out16rb(address, value) ppc_out16_reverse((vuint16*)(address), value) +#define out32rb(address, value) ppc_out32_reverse((vuint32*)(address), value) +#define in8rb(address) ppc_in8((const vuint8*)(address)) +#define in16rb(address) ppc_in16_reverse((const vuint16*)(address)) +#define in32rb(address) ppc_in32_reverse((const vuint32*)(address)) + + +static int uninorth_enable_config(struct uninorth_host_bridge *bridge, + uint8 bus, uint8 slot, uint8 function, uint8 offset); + +static status_t uninorth_read_pci_config(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 offset, uint8 size, uint32 *value); +static status_t uninorth_write_pci_config(void *cookie, uint8 bus, + uint8 device, uint8 function, uint8 offset, uint8 size, + uint32 value); +static status_t uninorth_get_max_bus_devices(void *cookie, int32 *count); +static status_t uninorth_read_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 *irq); +static status_t uninorth_write_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 irq); + +static pci_controller sUniNorthPCIController = { + uninorth_read_pci_config, + uninorth_write_pci_config, + uninorth_get_max_bus_devices, + uninorth_read_pci_irq, + uninorth_write_pci_irq, +}; + + +static status_t +uninorth_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, + uint8 offset, uint8 size, uint32 *value) +{ + uninorth_host_bridge *bridge = (uninorth_host_bridge*)cookie; + + addr_t caoff = bridge->data_registers + (offset & 0x07); + + if (uninorth_enable_config(bridge, bus, device, function, offset) != 0) { + switch (size) { + case 1: + *value = in8rb(caoff); + break; + case 2: + *value = in16rb(caoff); + break; + case 4: + *value = in32rb(caoff); + break; + default: + *value = 0xffffffff; + break; + } + } else + *value = 0xffffffff; + + return B_OK; +} + + +static status_t uninorth_write_pci_config(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 offset, uint8 size, uint32 value) +{ + uninorth_host_bridge *bridge = (uninorth_host_bridge*)cookie; + + addr_t caoff = bridge->data_registers + (offset & 0x07); + + if (uninorth_enable_config(bridge, bus, device, function, offset)) { + switch (size) { + case 1: + out8rb(caoff, (uint8)value); + (void)in8rb(caoff); + break; + case 2: + out16rb(caoff, (uint16)value); + (void)in16rb(caoff); + break; + case 4: + out32rb(caoff, value); + (void)in32rb(caoff); + break; + } + } + + return B_OK; +} + + +static status_t uninorth_get_max_bus_devices(void *cookie, int32 *count) +{ + *count = 32; + return B_OK; +} + + +static status_t uninorth_read_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 *irq) +{ + return B_ERROR; +} + + +static status_t uninorth_write_pci_irq(void *cookie, uint8 bus, uint8 device, + uint8 function, uint8 pin, uint8 irq) +{ + return B_ERROR; +} + + +// #pragma mark - + + +static int +uninorth_enable_config(struct uninorth_host_bridge *bridge, uint8 bus, + uint8 slot, uint8 function, uint8 offset) +{ +// uint32 pass; +// if (resource_int_value(device_get_name(sc->sc_dev), +// device_get_unit(sc->sc_dev), "skipslot", &pass) == 0) { +// if (pass == slot) +// return (0); +// } + + uint32 cfgval; + if (bridge->bus == bus) { + /* + * No slots less than 11 on the primary bus + */ + if (slot < 11) + return (0); + + cfgval = (1 << slot) | (function << 8) | (offset & 0xfc); + } else { + cfgval = (bus << 16) | (slot << 11) | (function << 8) | + (offset & 0xfc) | 1; + } + + do { + out32rb(bridge->address_registers, cfgval); + } while (in32rb(bridge->address_registers) != cfgval); + + return (1); +} + + +// #pragma mark - + +status_t +ppc_openfirmware_probe_uninorth(int deviceNode, + const StringArrayPropertyValue &compatibleValue) +{ + if (!compatibleValue.ContainsElement("uni-north")) + return B_ERROR; + + uint32 reg[2]; + if (of_getprop(deviceNode, "reg", reg, sizeof(reg)) < 8) + return B_ERROR; + + uint32 busrange[2]; + if (of_getprop(deviceNode, "bus-range", busrange, sizeof(busrange)) != 8) + return B_ERROR; + + uninorth_host_bridge *bridge + = (uninorth_host_bridge*)malloc(sizeof(uninorth_host_bridge)); + if (!bridge) + return B_NO_MEMORY; + + bridge->device_node = deviceNode; + bridge->address_registers = reg[0] + 0x800000; + bridge->data_registers = reg[0] + 0xc00000; + bridge->bus = busrange[0]; +// TODO: Check whether address and data registers have already been mapped by +// the Open Firmware. If not, map them ourselves. + + memset(bridge->ranges, 0, sizeof(bridge->ranges)); + int bytesRead = of_getprop(deviceNode, "ranges", bridge->ranges, + sizeof(bridge->ranges)); + + if (bytesRead < 0) { + dprintf("ppc_openfirmware_probe_uninorth: Could not get ranges.\n"); + return B_ERROR; + } + bridge->range_count = bytesRead / sizeof(uninorth_range); + + uninorth_range *ioRange = NULL; + uninorth_range *memoryRanges[2]; + int memoryRangeCount = 0; + + for (int i = 0; i < bridge->range_count; i++) { + uninorth_range *range = bridge->ranges + i; + switch (range->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { + case OFW_PCI_PHYS_HI_SPACE_CONFIG: + break; + case OFW_PCI_PHYS_HI_SPACE_IO: + ioRange = range; + break; + case OFW_PCI_PHYS_HI_SPACE_MEM32: + memoryRanges[memoryRangeCount++] = range; + break; + case OFW_PCI_PHYS_HI_SPACE_MEM64: + break; + } + } + + if (ioRange == NULL) { + dprintf("ppc_openfirmware_probe_uninorth: Can't find io range.\n"); + return B_ERROR; + } + + if (memoryRangeCount == 0) { + dprintf("ppc_openfirmware_probe_uninorth: Can't find mem ranges.\n"); + return B_ERROR; + } + + status_t error = pci_controller_add(&sUniNorthPCIController, bridge); + if (error != B_OK) + free(bridge); + return error; +} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_controller.cpp new file mode 100644 index 0000000000..79dce06868 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_controller.cpp @@ -0,0 +1,41 @@ +#include "pci_controller.h" + +#include + +#include "pci_priv.h" + +/* + * As we don't have any real PCI bus in any of the supported m68k platforms, + * we fake one, with hardcoded devices. + */ + +#include "amiga/pci_amiga.h" +#include "apple/pci_apple.h" +#include "atari/pci_atari.h" + + +status_t +pci_controller_init(void) +{ + switch (PPCPlatform::Default()->PlatformType()) { +/* case M68K_PLATFORM_AMIGA: + return m68k_amiga_pci_controller_init(); + break; + case M68K_PLATFORM_APPLE: + return m68k_apple_pci_controller_init(); + break;*/ + case M68K_PLATFORM_ATARI: + return m68k_atari_pci_controller_init(); + break; + default: + return EINVAL; + } + return B_OK; +} + + +void * +pci_ram_address(const void *physical_address_in_system_memory) +{ + return (void *)physical_address_in_system_memory; +} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c new file mode 100644 index 0000000000..8405007e07 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c @@ -0,0 +1,50 @@ +#include "pci_io.h" +#include "pci_priv.h" + +status_t +pci_io_init() +{ + return B_OK; +} + + +uint8 +pci_read_io_8(int mapped_io_addr) +{ + return m68k_in8((vuint8*)mapped_io_addr); +} + + +void +pci_write_io_8(int mapped_io_addr, uint8 value) +{ + m68k_out8((vuint8*)mapped_io_addr, value); +} + + +uint16 +pci_read_io_16(int mapped_io_addr) +{ + return m68k_in16((vuint16*)mapped_io_addr); +} + + +void +pci_write_io_16(int mapped_io_addr, uint16 value) +{ + m68k_out16((vuint16*)mapped_io_addr, value); +} + + +uint32 +pci_read_io_32(int mapped_io_addr) +{ + return m68k_in32((vuint32*)mapped_io_addr); +} + + +void +pci_write_io_32(int mapped_io_addr, uint32 value) +{ + m68k_out32((vuint32*)mapped_io_addr, value); +} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h new file mode 100644 index 0000000000..927fad7a01 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h @@ -0,0 +1,106 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef PCI_BUS_MANAGER_M68K_IO_H +#define PCI_BUS_MANAGER_M68K_IO_H + +#include + +#define IOBARRIER() asm volatile("nop") /* nop flushes the instruction pipeline */ +/*XXX: sync cache/pmmu?*/ + +static inline void +m68k_out8(vuint8 *address, uint8 value) +{ + *address = value; + IOBARRIER(); +} + + +static inline void +m68k_out16(vuint16 *address, uint16 value) +{ + *address = value; + IOBARRIER(); +} + +#if _XXX_HAS_REVERSE_IO +static inline void +m68k_out16_reverse(vuint16 *address, uint16 value) +{ + asm volatile("sthbrx %1, 0, %0" : : "r"(address), "r"(value)); + IOBARRIER(); +} +#endif + + +static inline void +m68k_out32(vuint32 *address, uint32 value) +{ + *address = value; + IOBARRIER(); +} + + +#if _XXX_HAS_REVERSE_IO +static inline void +m68k_out32_reverse(vuint32 *address, uint32 value) +{ + asm volatile("stwbrx %1, 0, %0" : : "r"(address), "r"(value)); + IOBARRIER(); +} +#endif + +static inline uint8 +m68k_in8(const vuint8 *address) +{ + uint8 value = *address; + IOBARRIER(); + return value; +} + + +static inline uint16 +m68k_in16(const vuint16 *address) +{ + uint16 value = *address; + IOBARRIER(); + return value; +} + + +#if _XXX_HAS_REVERSE_IO +static inline uint16 +m68k_in16_reverse(const vuint16 *address) +{ + uint16 value; + asm volatile("lhbrx %0, 0, %1" : "=r"(value) : "r"(address)); + IOBARRIER(); + return value; +} +#endif + + +static inline uint32 +m68k_in32(const vuint32 *address) +{ + uint32 value = *address; + IOBARRIER(); + return value; +} + + +#if _XXX_HAS_REVERSE_IO +static inline uint32 +m68k_in32_reverse(const vuint32 *address) +{ + uint32 value; + asm volatile("lwbrx %0, 0, %1" : "=r"(value) : "r"(address)); + IOBARRIER(); + return value; +} +#endif + +#endif // PCI_BUS_MANAGER_M68K_IO_H