diff --git a/headers/private/kernel/arch/sparc/arch_platform.h b/headers/private/kernel/arch/sparc/arch_platform.h new file mode 100644 index 0000000000..24e774eb2f --- /dev/null +++ b/headers/private/kernel/arch/sparc/arch_platform.h @@ -0,0 +1,50 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_SPARC_ARCH_PLATFORM_H +#define _KERNEL_SPARC_ARCH_PLATFORM_H + +#include + +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 diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/sparc/Jamfile index 3a4790e24e..8d0941693a 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/sparc/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/arch/sparc/Jamfile @@ -11,6 +11,6 @@ KernelStaticLibrary pci_arch_bus_manager : pci_io.c # openfirmware - # TODO + pci_openfirmware.cpp ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.cpp b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.cpp new file mode 100644 index 0000000000..7df3153a98 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "pci_openfirmware.h" + +#include +#include + +#include + +#include +#include +#include + +#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; +} + diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.h b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.h new file mode 100644 index 0000000000..5b8c2573b0 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware.h @@ -0,0 +1,13 @@ +/* + * Copyright 2006, Ingo Weinhold . + * 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 + +status_t sparc_openfirmware_pci_controller_init(void); + +#endif // PCI_BUS_MANAGER_SPARC_OPEN_FIRMWARE_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware_priv.h b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware_priv.h new file mode 100644 index 0000000000..6c9c917696 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/sparc/openfirmware/pci_openfirmware_priv.h @@ -0,0 +1,49 @@ +/* + * Copyright 2006, Ingo Weinhold . + * 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 +#include + +#include + + +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 diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_controller.cpp new file mode 100644 index 0000000000..ff8eea2ac0 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_controller.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2006, Ingo Weinhold. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include "pci_controller.h" + +#include + +#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; +} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.c b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.c new file mode 100644 index 0000000000..94877e26d9 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.c @@ -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); +} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.h b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.h new file mode 100644 index 0000000000..6cf0cbc70d --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/sparc/pci_io.h @@ -0,0 +1,97 @@ +/* + * Copyright 2006, Ingo Weinhold . + * 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 + +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