sparc: pci bus manager
Copied from PPC with the hooks for Apple hardware removed. To be completed with the actual PCI bus implementation for Sun machines. This is where we start doing machine specific stuff, apparently. Change-Id: I06af4de9621e9d40593d153642478d928083e49a Reviewed-on: https://review.haiku-os.org/c/1364 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <[email protected]>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_SPARC_ARCH_PLATFORM_H
|
||||
#define _KERNEL_SPARC_ARCH_PLATFORM_H
|
||||
|
||||
#include <arch/platform.h>
|
||||
|
||||
struct real_time_data;
|
||||
|
||||
enum sparc_platform_type {
|
||||
PPC_PLATFORM_OPEN_FIRMWARE = 0,
|
||||
};
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class SparcPlatform {
|
||||
public:
|
||||
SparcPlatform(sparc_platform_type platformType);
|
||||
virtual ~SparcPlatform();
|
||||
|
||||
static SparcPlatform *Default();
|
||||
|
||||
inline sparc_platform_type PlatformType() const { return fPlatformType; }
|
||||
|
||||
virtual status_t Init(struct kernel_args *kernelArgs) = 0;
|
||||
virtual status_t InitSerialDebug(struct kernel_args *kernelArgs) = 0;
|
||||
virtual status_t InitPostVM(struct kernel_args *kernelArgs) = 0;
|
||||
virtual status_t InitRTC(struct kernel_args *kernelArgs,
|
||||
struct real_time_data *data) = 0;
|
||||
|
||||
virtual char SerialDebugGetChar() = 0;
|
||||
virtual void SerialDebugPutChar(char c) = 0;
|
||||
|
||||
virtual void SetHardwareRTC(uint32 seconds) = 0;
|
||||
virtual uint32 GetHardwareRTC() = 0;
|
||||
|
||||
virtual void ShutDown(bool reboot) = 0;
|
||||
|
||||
private:
|
||||
sparc_platform_type fPlatformType;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::SparcPlatform;
|
||||
|
||||
|
||||
#endif // _KERNEL_SPARC_ARCH_PLATFORM_H
|
||||
@@ -11,6 +11,6 @@ KernelStaticLibrary pci_arch_bus_manager :
|
||||
pci_io.c
|
||||
|
||||
# openfirmware
|
||||
# TODO
|
||||
pci_openfirmware.cpp
|
||||
;
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <[email protected]>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "pci_openfirmware.h"
|
||||
|
||||
#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_openfirmware_priv.h"
|
||||
|
||||
|
||||
typedef status_t (*probeFunction)(int, const StringArrayPropertyValue&);
|
||||
|
||||
static const probeFunction sProbeFunctions[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
sparc_openfirmware_pci_controller_init(void)
|
||||
{
|
||||
char path[256];
|
||||
int cookie = 0;
|
||||
while (of_get_next_device(&cookie, 0, "pci", path, sizeof(path))
|
||||
== B_OK) {
|
||||
dprintf("sparc_openfirmware_pci_controller_init(): pci device node: %s\n", path);
|
||||
// get the device node and the "compatible" property
|
||||
int deviceNode = of_finddevice(path);
|
||||
StringArrayPropertyValue compatible;
|
||||
status_t error = openfirmware_get_property(deviceNode, "compatible",
|
||||
compatible);
|
||||
if (error != B_OK) {
|
||||
dprintf("sparc_openfirmware_pci_controller_init: Failed to get "
|
||||
"\"compatible\" property for pci device: %s\n", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
// probe
|
||||
for (int i = 0; sProbeFunctions[i]; i++) {
|
||||
error = sProbeFunctions[i](deviceNode, compatible);
|
||||
if (error == B_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - support functions
|
||||
|
||||
|
||||
char *
|
||||
StringArrayPropertyValue::NextElement(int &cookie) const
|
||||
{
|
||||
if (cookie >= length)
|
||||
return NULL;
|
||||
|
||||
char *result = value + cookie;
|
||||
cookie += strnlen(result, length - cookie) + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StringArrayPropertyValue::ContainsElement(const char *value) const
|
||||
{
|
||||
int cookie = 0;
|
||||
while (char *checkValue = NextElement(cookie)) {
|
||||
if (strcmp(checkValue, value) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
openfirmware_get_property(int package, const char *propertyName,
|
||||
PropertyValue &value)
|
||||
{
|
||||
value.length = of_getproplen(package, propertyName);
|
||||
if (value.length < 0)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
value.value = (char*)malloc(value.length);
|
||||
if (!value.value)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (of_getprop(package, propertyName, value.value, value.length)
|
||||
== OF_FAILED) {
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <[email protected]>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_H
|
||||
#define PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
status_t sparc_openfirmware_pci_controller_init(void);
|
||||
|
||||
#endif // PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_H
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <[email protected]>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_PRIV_H
|
||||
#define PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_PRIV_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
struct StringArrayPropertyValue;
|
||||
|
||||
|
||||
// implementations
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
// 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_SPARC_OPEN_FIRMWARE_PRIV_H
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pci_controller.h"
|
||||
|
||||
#include <arch_platform.h>
|
||||
|
||||
#include "pci_private.h"
|
||||
|
||||
#include "openfirmware/pci_openfirmware.h"
|
||||
|
||||
|
||||
status_t
|
||||
pci_controller_init(void)
|
||||
{
|
||||
return sparc_openfirmware_pci_controller_init();
|
||||
}
|
||||
|
||||
|
||||
phys_addr_t
|
||||
pci_ram_address(phys_addr_t physical_address_in_system_memory)
|
||||
{
|
||||
return physical_address_in_system_memory;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pci_io.h"
|
||||
#include "pci_private.h"
|
||||
|
||||
|
||||
static const uint8_t* gPCIBase;
|
||||
|
||||
|
||||
status_t
|
||||
pci_io_init()
|
||||
{
|
||||
// TODO set gPCIBase
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
pci_read_io_8(int mapped_io_addr)
|
||||
{
|
||||
return sparc_in8((vuint8*)(gPCIBase + mapped_io_addr));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_write_io_8(int mapped_io_addr, uint8 value)
|
||||
{
|
||||
sparc_out8((vuint8*)(gPCIBase + mapped_io_addr), value);
|
||||
}
|
||||
|
||||
|
||||
uint16
|
||||
pci_read_io_16(int mapped_io_addr)
|
||||
{
|
||||
return sparc_in16((vuint16*)(gPCIBase + mapped_io_addr));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_write_io_16(int mapped_io_addr, uint16 value)
|
||||
{
|
||||
sparc_out16((vuint16*)(gPCIBase + mapped_io_addr), value);
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
pci_read_io_32(int mapped_io_addr)
|
||||
{
|
||||
return sparc_in32((vuint32*)(gPCIBase + mapped_io_addr));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_write_io_32(int mapped_io_addr, uint32 value)
|
||||
{
|
||||
sparc_out32((vuint32*)(gPCIBase + mapped_io_addr), value);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2006, Ingo Weinhold <[email protected]>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef PCI_BUS_MANAGER_SPARC_IO_H
|
||||
#define PCI_BUS_MANAGER_SPARC_IO_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
static inline void
|
||||
sparc_out8(vuint8 *address, uint8 value)
|
||||
{
|
||||
*address = value;
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
sparc_out16(vuint16 *address, uint16 value)
|
||||
{
|
||||
*address = value;
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
sparc_out16_reverse(vuint16 *address, uint16 value)
|
||||
{
|
||||
asm volatile("stha %1, [%0] 0x88" : : "r"(address), "r"(value));
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
sparc_out32(vuint32 *address, uint32 value)
|
||||
{
|
||||
*address = value;
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
sparc_out32_reverse(vuint32 *address, uint32 value)
|
||||
{
|
||||
asm volatile("stwa %1, [%0] 0x88" : : "r"(address), "r"(value));
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
}
|
||||
|
||||
|
||||
static inline uint8
|
||||
sparc_in8(const vuint8 *address)
|
||||
{
|
||||
uint8 value = *address;
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16
|
||||
sparc_in16(const vuint16 *address)
|
||||
{
|
||||
uint16 value = *address;
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16
|
||||
sparc_in16_reverse(const vuint16 *address)
|
||||
{
|
||||
uint16 value;
|
||||
asm volatile("lha [%1] 0x88, %0" : "=r"(value) : "r"(address));
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
sparc_in32(const vuint32 *address)
|
||||
{
|
||||
uint32 value = *address;
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
sparc_in32_reverse(const vuint32 *address)
|
||||
{
|
||||
uint32 value;
|
||||
asm volatile("ldwa [%1] 0x88, %0" : "=r"(value) : "r"(address));
|
||||
asm volatile("MEMBAR #MemIssue");
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif // PCI_BUS_MANAGER_SPARC_IO_H
|
||||
Reference in New Issue
Block a user