From 99662046021dbc91ef652d3177c7bc299ac60df6 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 14 May 2002 17:28:05 +0000 Subject: 2001-05-14 Till Straumann Per PR216, "libbsp/powerpc/shared" BSP has been modified considerably with the goal to make it more flexible and reusable by other BSPs. The main strategies were: - eliminate hardcoded base addresses; devices use offsets and a BSP defined base address. - separate functionality into different files (e.g. reboot from inch.c to reboot.c) which can be overridden by a 'derived' BSP. - separate initialization code into separate files (e.g. PCI bridge detection/initialization was separated from the more generic PCI access routines), also to make it easier for 'derived' BSPs to substitute their own initialization code. There are also a couple of enhancements and fixes: - IRQ handling code now has a hook for attaching a VME bridge. - OpenPIC is now explicitely initialized (polarities, senses). Eliminated the implicit assumption on the presence of an ISA PIC. - UART and console driver now supports more than 1 port. The current maximum of 2 can easily be extended by enlarging a table (it would even be easier if the ISR API was not broken by design). - fixed polled_io.c so it correctly supports console on COM2 - fixed TLB invalidation code (start.S). - exception handler prints a stack backtrace. - added BSP_pciFindDevice() to scan the pci bus for a particular vendor/device/instance. --- .../lib/libbsp/powerpc/shared/console/console.inl | 51 ++++++++++ c/src/lib/libbsp/powerpc/shared/console/reboot.c | 16 +++ .../powerpc/shared/pci/detect_raven_bridge.c | 111 +++++++++++++++++++++ .../lib/libbsp/powerpc/shared/pci/pcifinddevice.c | 55 ++++++++++ 4 files changed, 233 insertions(+) create mode 100644 c/src/lib/libbsp/powerpc/shared/console/console.inl create mode 100644 c/src/lib/libbsp/powerpc/shared/console/reboot.c create mode 100644 c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c create mode 100644 c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c (limited to 'c/src/lib/libbsp/powerpc') diff --git a/c/src/lib/libbsp/powerpc/shared/console/console.inl b/c/src/lib/libbsp/powerpc/shared/console/console.inl new file mode 100644 index 0000000000..142bdd18ce --- /dev/null +++ b/c/src/lib/libbsp/powerpc/shared/console/console.inl @@ -0,0 +1,51 @@ + +/* inline routines for console i/o + * + * The purpose of this file is to provide generic inline functions, + * i.e. not using hardcoded base addresses. These are provided by + * the BSP header. + * + * $Id$ + */ + +#include + +#define INL_IN_DECL(name,base) \ +static inline unsigned char name(int off) \ +{ \ + return in_8((unsigned char*)(((unsigned long)base) + off)); \ +} + +#define INL_OUT_DECL(name,base) \ +static inline void name(int off, unsigned int val) \ +{ \ + out_8((unsigned char*)(((unsigned long)base) + off), val); \ +} + +#ifdef BSP_UART_IOBASE_COM1 +INL_IN_DECL(com1_inb, BSP_UART_IOBASE_COM1) +INL_OUT_DECL(com1_outb, BSP_UART_IOBASE_COM1) +#endif +#ifdef BSP_UART_IOBASE_COM2 +INL_IN_DECL(com2_inb, BSP_UART_IOBASE_COM2) +INL_OUT_DECL(com2_outb, BSP_UART_IOBASE_COM2) +#endif + +#if defined(BSP_CONSOLE_PORT) +#if (BSP_CONSOLE_PORT == BSP_UART_COM1) && defined(BSP_UART_IOBASE_COM1) +#define INL_CONSOLE_INB com1_inb +#define INL_CONSOLE_OUTB com1_outb +#elif (BSP_CONSOLE_PORT == BSP_UART_COM2) && defined(BSP_UART_IOBASE_COM2) +#define INL_CONSOLE_INB com2_inb +#define INL_CONSOLE_OUTB com2_outb +#endif +#endif + +#ifdef BSP_KBD_IOBASE +INL_IN_DECL(kbd_inb, BSP_KBD_IOBASE) +INL_OUT_DECL(kbd_outb, BSP_KBD_IOBASE) +#endif + +#ifdef BSP_VGA_IOBASE +INL_OUT_DECL(vga_outb, BSP_VGA_IOBASE) +#endif diff --git a/c/src/lib/libbsp/powerpc/shared/console/reboot.c b/c/src/lib/libbsp/powerpc/shared/console/reboot.c new file mode 100644 index 0000000000..a6e10db647 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/shared/console/reboot.c @@ -0,0 +1,16 @@ +/* $Id$ */ + +#include "console.inl" + +/*-------------------------------------------------------------------------+ +| Function: rtemsReboot +| Description: Reboot the PC. +| Global Variables: None. +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +void rtemsReboot(void) +{ + /* shutdown and reboot */ + kbd_outb(0x4, 0xFE); /* use keyboard controler to do the job... */ +} /* rtemsReboot */ diff --git a/c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c b/c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c new file mode 100644 index 0000000000..aab1b88187 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c @@ -0,0 +1,111 @@ +/* + * $Id$ + */ + +#include + +#include +#include +#include +#include +#include + +#define RAVEN_MPIC_IOSPACE_ENABLE 0x1 +#define RAVEN_MPIC_MEMSPACE_ENABLE 0x2 +#define RAVEN_MASTER_ENABLE 0x4 +#define RAVEN_PARITY_CHECK_ENABLE 0x40 +#define RAVEN_SYSTEM_ERROR_ENABLE 0x100 +#define RAVEN_CLEAR_EVENTS_MASK 0xf9000000 + +#define pci BSP_pci_configuration + +extern const pci_config_access_functions pci_direct_functions; +extern const pci_config_access_functions pci_indirect_functions; + +void detect_host_bridge() +{ + PPC_DEVICE *hostbridge; + unsigned int id0; + unsigned int tmp; + + /* + * This code assumes that the host bridge is located at + * bus 0, dev 0, func 0 AND that the old pre PCI 2.1 + * standart devices detection mecahnism that was used on PC + * (still used in BSD source code) works. + */ + hostbridge=residual_find_device(&residualCopy, PROCESSORDEVICE, NULL, + BridgeController, + PCIBridge, -1, 0); + if (hostbridge) { + if (hostbridge->DeviceId.Interface==PCIBridgeIndirect) { + pci.pci_functions=&pci_indirect_functions; + /* Should be extracted from residual data, + * indeed MPC106 in CHRP mode is different, + * but we should not use residual data in + * this case anyway. + */ + pci.pci_config_addr = ((volatile unsigned char *) + (ptr_mem_map->io_base+0xcf8)); + pci.pci_config_data = ptr_mem_map->io_base+0xcfc; + } else if(hostbridge->DeviceId.Interface==PCIBridgeDirect) { + pci.pci_functions=&pci_direct_functions; + pci.pci_config_data=(unsigned char *) 0x80800000; + } else { + } + } else { + /* Let us try by experimentation at our own risk! */ + pci.pci_functions = &pci_direct_functions; + /* On all direct bridges I know the host bridge itself + * appears as device 0 function 0. + */ + pci_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &id0); + if (id0==~0U) { + pci.pci_functions = &pci_indirect_functions; + pci.pci_config_addr = ((volatile unsigned char*) + (ptr_mem_map->io_base+0xcf8)); + pci.pci_config_data = ((volatile unsigned char*)ptr_mem_map->io_base+0xcfc); + } + /* Here we should check that the host bridge is actually + * present, but if it not, we are in such a desperate + * situation, that we probably can't even tell it. + */ + } + pci_read_config_dword(0, 0, 0, 0, &id0); + if(id0 == PCI_VENDOR_ID_MOTOROLA + + (PCI_DEVICE_ID_MOTOROLA_RAVEN<<16)) { + /* + * We have a Raven bridge. We will get information about its settings + */ + pci_read_config_dword(0, 0, 0, PCI_COMMAND, &id0); +#ifdef SHOW_RAVEN_SETTING + printk("RAVEN PCI command register = %x\n",id0); +#endif + id0 |= RAVEN_CLEAR_EVENTS_MASK; + pci_write_config_dword(0, 0, 0, PCI_COMMAND, id0); + pci_read_config_dword(0, 0, 0, PCI_COMMAND, &id0); +#ifdef SHOW_RAVEN_SETTING + printk("After error clearing RAVEN PCI command register = %x\n",id0); +#endif + + if (id0 & RAVEN_MPIC_IOSPACE_ENABLE) { + pci_read_config_dword(0, 0, 0,PCI_BASE_ADDRESS_0, &tmp); +#ifdef SHOW_RAVEN_SETTING + printk("Raven MPIC is accessed via IO Space Access at address : %x\n",(tmp & ~0x1)); +#endif + } + if (id0 & RAVEN_MPIC_MEMSPACE_ENABLE) { + pci_read_config_dword(0, 0, 0,PCI_BASE_ADDRESS_1, &tmp); +#ifdef SHOW_RAVEN_SETTING + printk("Raven MPIC is accessed via memory Space Access at address : %x\n", tmp); +#endif + OpenPIC=(volatile struct OpenPIC *) (tmp + PREP_ISA_MEM_BASE); + printk("OpenPIC found at %p.\n", + OpenPIC); + } + } + if (OpenPIC == (volatile struct OpenPIC *)0) { + BSP_panic("OpenPic Not found\n"); + } + +} diff --git a/c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c b/c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c new file mode 100644 index 0000000000..a1d2a0d3ad --- /dev/null +++ b/c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c @@ -0,0 +1,55 @@ + +/* Author: Till Straumann , 2001 */ + +/* find a particular PCI device + * (we assume, the firmware configured the PCI bus[es] for us) + * + * $Id$ + */ + +#define PCI_INVALID_VENDORDEVICEID 0xffffffff +#define PCI_MULTI_FUNCTION 0x80 + +#include +#include + +int +BSP_pciFindDevice(unsigned short vendorid, unsigned short deviceid, + int instance, int *pbus, int *pdev, int *pfun) +{ +unsigned int d; +unsigned short s; +unsigned char bus,dev,fun,hd; + + for (bus=0; bus