Fake pci bus manager for m68k.
We will fake hardcoded devices depending on the platform. Hopefully that will help some generic drivers (ide) to work without major modification. Synced to r22648. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22655 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
188b43270e
commit
5bbe87abba
19
src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile
Normal file
19
src/add-ons/kernel/bus_managers/pci/arch/m68k/Jamfile
Normal file
@ -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
|
||||
;
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2007, François Revol <revol@free.fr>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "pci_amiga.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
|
||||
status_t
|
||||
m68k_amiga_pci_controller_init(void)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - support functions
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2007, François Revol <revol@free.fr>.
|
||||
* 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 <SupportDefs.h>
|
||||
|
||||
status_t m68k_amiga_pci_controller_init(void);
|
||||
|
||||
#endif // PCI_BUS_MANAGER_M68K_AMIGA_H
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2007, François Revol <revol@free.fr>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "pci_apple.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
|
||||
status_t
|
||||
m68k_apple_pci_controller_init(void)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - support functions
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2007, François Revol <revol@free.fr>.
|
||||
* 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 <SupportDefs.h>
|
||||
|
||||
status_t m68k_apple_pci_controller_init(void);
|
||||
|
||||
#endif // PCI_BUS_MANAGER_M68K_APPLE_H
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright 2007, François Revol <revol@free.fr>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "pci_atari.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <PCI.h>
|
||||
|
||||
#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
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2007, François Revol <revol@free.fr>.
|
||||
* 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 <SupportDefs.h>
|
||||
|
||||
status_t m68k_atari_pci_controller_init(void);
|
||||
|
||||
#endif // PCI_BUS_MANAGER_M68K_ATARI_H
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
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
|
284
src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/uninorth.cpp
Normal file
284
src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/uninorth.cpp
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <platform/openfirmware/devices.h>
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
#include <platform/openfirmware/pci.h>
|
||||
|
||||
#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;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
#include "pci_controller.h"
|
||||
|
||||
#include <arch_platform.h>
|
||||
|
||||
#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;
|
||||
}
|
50
src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c
Normal file
50
src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.c
Normal file
@ -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);
|
||||
}
|
106
src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h
Normal file
106
src/add-ons/kernel/bus_managers/pci/arch/m68k/pci_io.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* 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 <SupportDefs.h>
|
||||
|
||||
#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
|
Loading…
Reference in New Issue
Block a user