// SPDX-License-Identifier: GPL-2.0
/*
* linux / arch / alpha / kernel / core_polaris . c
*
* POLARIS chip - specific code
*/
#define __EXTERN_INLINE inline
#include <asm /io.h>
#include <asm /core_polaris.h>
#undef __EXTERN_INLINE
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm /ptrace.h>
#include "proto.h"
#include "pci_impl.h"
/*
* BIOS32 - style PCI interface :
*/
#define DEBUG_CONFIG 0
#if DEBUG_CONFIG
# define DBG_CFG(args) printk args
#else
# define DBG_CFG(args)
#endif
/*
* Given a bus , device , and function number , compute resulting
* configuration space address . This is fairly straightforward
* on POLARIS , since the chip itself generates Type 0 or Type 1
* cycles automatically depending on the bus number ( Bus 0 is
* hardwired to Type 0 , all others are Type 1 . Peer bridges
* are not supported ) .
*
* All types :
*
* 3 3 3 3 | 3 3 3 3 | 3 3 2 2 | 2 2 2 2 | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1
* 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0
* + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
* | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | B | B | B | B | B | B | B | B | D | D | D | D | D | F | F | F | R | R | R | R | R | R | x | x |
* + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
*
* 23 : 16 bus number ( 8 bits = 128 possible buses )
* 15 : 11 Device number ( 5 bits )
* 10 : 8 function number
* 7 : 2 register number
*
* Notes :
* The function number selects which function of a multi - function device
* ( e . g . , scsi and ethernet ) .
*
* The register selects a DWORD ( 32 bit ) register offset . Hence it
* doesn ' t get shifted by 2 bits as we want to " drop " the bottom two
* bits .
*/
static int
mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
unsigned long *pci_addr, u8 *type1)
{
u8 bus = pbus->number;
*type1 = (bus == 0 ) ? 0 : 1 ;
*pci_addr = (bus << 16 ) | (device_fn << 8 ) | (where) |
POLARIS_DENSE_CONFIG_BASE;
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
" returning address 0x%p\n"
bus, device_fn, where, *pci_addr));
return 0 ;
}
static int
polaris_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
case 1 :
*value = __kernel_ldbu(*(vucp)addr);
break ;
case 2 :
*value = __kernel_ldwu(*(vusp)addr);
break ;
case 4 :
*value = *(vuip)addr;
break ;
}
return PCIBIOS_SUCCESSFUL;
}
static int
polaris_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
case 1 :
__kernel_stb(value, *(vucp)addr);
mb();
__kernel_ldbu(*(vucp)addr);
break ;
case 2 :
__kernel_stw(value, *(vusp)addr);
mb();
__kernel_ldwu(*(vusp)addr);
break ;
case 4 :
*(vuip)addr = value;
mb();
*(vuip)addr;
break ;
}
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops polaris_pci_ops =
{
.read = polaris_read_config,
.write = polaris_write_config,
};
void __init
polaris_init_arch(void )
{
struct pci_controller *hose;
/* May need to initialize error reporting (see PCICTL0/1), but
* for now assume that the firmware has done the right thing
* already .
*/
#if 0
printk("polaris_init_arch(): trusting firmware for setup\n" );
#endif
/*
* Create our single hose .
*/
pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0 ;
hose->sparse_mem_base = 0 ;
hose->dense_mem_base = POLARIS_DENSE_MEM_BASE - IDENT_ADDR;
hose->sparse_io_base = 0 ;
hose->dense_io_base = POLARIS_DENSE_IO_BASE - IDENT_ADDR;
hose->sg_isa = hose->sg_pci = NULL;
/* The I/O window is fixed at 2G @ 2G. */
__direct_map_base = 0 x80000000;
__direct_map_size = 0 x80000000;
}
static inline void
polaris_pci_clr_err(void )
{
*(vusp)POLARIS_W_STATUS;
/* Write 1's to settable bits to clear errors */
*(vusp)POLARIS_W_STATUS = 0 x7800;
mb();
*(vusp)POLARIS_W_STATUS;
}
void
polaris_machine_check(unsigned long vector, unsigned long la_ptr)
{
/* Clear the error before any reporting. */
mb();
mb();
draina();
polaris_pci_clr_err();
wrmces(0 x7);
mb();
process_mcheck_info(vector, la_ptr, "POLARIS" ,
mcheck_expected(0 ));
}
Messung V0.5 in Prozent C=95 H=88 G=91
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland