分类:
2008-09-17 17:48:25
#ifndef LIBBASE_REGS_CCSR_H为了读写mpc8548的 CCSR 寄存器,按照手册,读写后必须执行sync/isync指令,所以定义了这些操作:
#define LIBBASE_REGS_CCSR_H
#include
/* Reference: MPC8548ERM P2-17 */
/* Read ccsr register, CCSR_BASEADDR is OS specified */
#define CCSR_REG_OFF(off) (CCSR_BASEADDR + off)
#define CCSR_REG(reg) CCSR_REG_OFF(CCSR_OFF_##reg)
/* Register offsets definition */
/* Local-Access Registers - Configuration, Control, and Status Registers */
#define CCSR_OFF_CCSRBAR 0x00000
/* Local-Access Registers - Local-Acces Window Base and Size Registers*/
/* ... */
/* PCI1/X Registers : PCI Configuration Access Registers */
#define CCSR_OFF_PCI_CFG_ADDR 0x08000
typedef struct __attribute__ ((__packed__)) _ccsr_pci_cfg_addr_t {
u_int8_t enable:1;
u_int8_t reserved1:7;
union {
struct {
u_int8_t bus;
u_int8_t device:5;
u_int8_t function:3;
} detail;
u_int16_t data;
} id;
u_int8_t reg;
} ccsr_pci_cfg_addr_t;
#define CCSR_OFF_PCI_CFG_DATA 0x08004
typedef struct _ccsr_pci_outbound_window_t {
u_int32_t POTAR;
u_int32_t POTEAR;
u_int32_t POWBAR; /* reserved for window 0(default) */
u_int32_t RESERVED1;
u_int32_t POWAR;
u_int32_t RESERVED2;
u_int32_t RESERVED3;
u_int32_t RESERVED4;
} ccsr_pci_outbound_window_t;
#define CCSR_OFFBASE_PCI_OUTBOUND_WINDOW 0x08C00
...
#endif
#ifndef LIBBASE_LOWIO_H
#define LIBBASE_LOWIO_H
#include
/*
* Low-level I/O routines.
*/
static inline u_int8_t in_8(const volatile u_int8_t *addr)
{
u_int8_t ret;
__asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "m" (*addr));
return ret;
}
static inline void out_8(volatile u_int8_t *addr, u_int8_t val)
{
__asm__ __volatile__("stb%U0%X0 %1,%0; sync"
: "=m" (*addr) : "r" (val));
}
static inline u_int16_t in_le16(const volatile u_int16_t *addr)
{
u_int16_t ret;
__asm__ __volatile__("lhbrx %0,0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "r" (addr), "m" (*addr));
return ret;
}
static inline u_int16_t in_be16(const volatile u_int16_t *addr)
{
u_int16_t ret;
__asm__ __volatile__("lhz%U1%X1 %0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "m" (*addr));
return ret;
}
static inline void out_le16(volatile u_int16_t *addr, u_int16_t val)
{
__asm__ __volatile__("sthbrx %1,0,%2; sync" : "=m" (*addr)
: "r" (val), "r" (addr));
}
static inline void out_be16(volatile u_int16_t *addr, u_int16_t val)
{
__asm__ __volatile__("sth%U0%X0 %1,%0; sync"
: "=m" (*addr) : "r" (val));
}
static inline u_int32_t in_le32(const volatile u_int32_t *addr)
{
u_int32_t ret;
__asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "r" (addr), "m" (*addr));
return ret;
}
static inline u_int32_t in_be32(const volatile u_int32_t *addr)
{
u_int32_t ret;
__asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "m" (*addr));
return ret;
}
static inline void out_le32(volatile u_int32_t *addr, u_int32_t val)
{
__asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr)
: "r" (val), "r" (addr));
}
static inline void out_be32(volatile u_int32_t *addr, u_int32_t val)
{
__asm__ __volatile__("stw%U0%X0 %1,%0; sync"
: "=m" (*addr) : "r" (val));
}
static inline void sync(void)
{
asm volatile("sync" : : : "memory");
}
static inline void eieio(void)
{
asm volatile("eieio" : : : "memory");
}
#endif /* LIBBASE_LOWIO_H */
ccsr_pci_cfg_addr_t pci_cfg_tmp;
u_int32_t data32;
printf("CCSRBAR: %08X\n", U_INT32_REG(CCSR_REG(CCSRBAR)));
/* pci devices enumeration */
pci_cfg_tmp.enable = 1;
pci_cfg_tmp.reserved1 = 0;
printf("PCI Devices:\n");
for (pci_cfg_tmp.id.data = 0;
pci_cfg_tmp.id.data < 0xFFFF;
++pci_cfg_tmp.id.data) {
pci_cfg_tmp.reg = 0;
out_be32(&U_INT32_REG(CCSR_REG(PCI_CFG_ADDR)), *(u_int32_t*)&pci_cfg_tmp);
data32 = in_le32(&U_INT32_REG(CCSR_REG(PCI_CFG_DATA)));
if (data32 != 0xFFFFFFFF) {
printf("%04X(%02X:%02X:%02X) -> DEV_VEN(%08X)\n",
pci_cfg_tmp.id.data,
pci_cfg_tmp.id.detail.bus,
pci_cfg_tmp.id.detail.device,
pci_cfg_tmp.id.detail.function,
data32
);
}
}