mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-21 03:27:56 +08:00
2001-05-14 Till Straumann <strauman@slac.stanford.edu>
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.
This commit is contained in:
@@ -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 <bsp.h>
|
||||
|
||||
#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
|
||||
@@ -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 */
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <libcpu/io.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/pci.h>
|
||||
#include <bsp/consoleIo.h>
|
||||
#include <bsp/residual.h>
|
||||
#include <bsp/openpic.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
/* Author: Till Straumann <strauman@slac.stanford.edu>, 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 <bsp/pci.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
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<BusCountPCI(); bus++) {
|
||||
for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
|
||||
|
||||
pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
|
||||
hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
|
||||
|
||||
for (fun=0; fun<hd; fun++) {
|
||||
/*
|
||||
* The last devfn id/slot is special; must skip it
|
||||
*/
|
||||
if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
|
||||
break;
|
||||
(void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
|
||||
if (PCI_INVALID_VENDORDEVICEID == d)
|
||||
continue;
|
||||
#ifdef PCI_DEBUG
|
||||
printk("BSP_pciFindDevice: found 0x%08x at %i/%i/%i\n",d,bus,dev,fun);
|
||||
#endif
|
||||
(void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
|
||||
if (vendorid != s)
|
||||
continue;
|
||||
(void) pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
|
||||
if (deviceid == s) {
|
||||
if (instance--) continue;
|
||||
*pbus=bus; *pdev=dev; *pfun=fun;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user