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:
PulkoMandy
2019-04-04 20:31:25 +00:00
committed by waddlesplash
parent d0ff1a1f2f
commit fea91fdc77
8 changed files with 403 additions and 1 deletions
@@ -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