arch/mips/pci/pci-alchemy.c
Source file repositories/reference/linux-study-clean/arch/mips/pci/pci-alchemy.c
File Facts
- System
- Linux kernel
- Corpus path
arch/mips/pci/pci-alchemy.c- Extension
.c- Size
- 14574 bytes
- Lines
- 541
- Domain
- Architecture Layer
- Bucket
- arch/mips
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/export.hlinux/types.hlinux/pci.hlinux/platform_device.hlinux/kernel.hlinux/init.hlinux/syscore_ops.hlinux/vmalloc.hlinux/dma-map-ops.hasm/mach-au1x00/au1000.hasm/tlbmisc.h
Detected Declarations
struct alchemy_pci_contextfunction mod_wired_entryfunction alchemy_pci_wired_entryfunction config_accessfunction read_config_bytefunction read_config_wordfunction read_config_dwordfunction write_config_bytefunction write_config_wordfunction write_config_dwordfunction alchemy_pci_readfunction alchemy_pci_writefunction alchemy_pci_def_idselfunction alchemy_pci_suspendfunction alchemy_pci_resumefunction alchemy_pci_probefunction read_c0_pridfunction alchemy_pci_initfunction pcibios_map_irqfunction pcibios_plat_dev_init
Annotated Snippet
struct alchemy_pci_context {
struct pci_controller alchemy_pci_ctrl; /* leave as first member! */
void __iomem *regs; /* ctrl base */
/* tools for wired entry for config space access */
unsigned long last_elo0;
unsigned long last_elo1;
int wired_entry;
struct vm_struct *pci_cfg_vm;
unsigned long pm[12];
int (*board_map_irq)(const struct pci_dev *d, u8 slot, u8 pin);
int (*board_pci_idsel)(unsigned int devsel, int assert);
};
/* for syscore_ops. There's only one PCI controller on Alchemy chips, so this
* should suffice for now.
*/
static struct alchemy_pci_context *__alchemy_pci_ctx;
/* IO/MEM resources for PCI. Keep the memres in sync with fixup_bigphys_addr
* in arch/mips/alchemy/common/setup.c
*/
static struct resource alchemy_pci_def_memres = {
.start = ALCHEMY_PCI_MEMWIN_START,
.end = ALCHEMY_PCI_MEMWIN_END,
.name = "PCI memory space",
.flags = IORESOURCE_MEM
};
static struct resource alchemy_pci_def_iores = {
.start = ALCHEMY_PCI_IOWIN_START,
.end = ALCHEMY_PCI_IOWIN_END,
.name = "PCI IO space",
.flags = IORESOURCE_IO
};
static void mod_wired_entry(int entry, unsigned long entrylo0,
unsigned long entrylo1, unsigned long entryhi,
unsigned long pagemask)
{
unsigned long old_pagemask;
unsigned long old_ctx;
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi() & MIPS_ENTRYHI_ASID;
old_pagemask = read_c0_pagemask();
write_c0_index(entry);
write_c0_pagemask(pagemask);
write_c0_entryhi(entryhi);
write_c0_entrylo0(entrylo0);
write_c0_entrylo1(entrylo1);
tlb_write_indexed();
write_c0_entryhi(old_ctx);
write_c0_pagemask(old_pagemask);
}
static void alchemy_pci_wired_entry(struct alchemy_pci_context *ctx)
{
ctx->wired_entry = read_c0_wired();
add_wired_entry(0, 0, (unsigned long)ctx->pci_cfg_vm->addr, PM_4K);
ctx->last_elo0 = ctx->last_elo1 = ~0;
}
static int config_access(unsigned char access_type, struct pci_bus *bus,
unsigned int dev_fn, unsigned char where, u32 *data)
{
struct alchemy_pci_context *ctx = bus->sysdata;
unsigned int device = PCI_SLOT(dev_fn);
unsigned int function = PCI_FUNC(dev_fn);
unsigned long offset, status, cfg_base, flags, entryLo0, entryLo1, r;
int error = PCIBIOS_SUCCESSFUL;
if (device > 19) {
*data = 0xffffffff;
return -1;
}
local_irq_save(flags);
r = __raw_readl(ctx->regs + PCI_REG_STATCMD) & 0x0000ffff;
r |= PCI_STATCMD_STATUS(0x2000);
__raw_writel(r, ctx->regs + PCI_REG_STATCMD);
wmb();
/* Allow board vendors to implement their own off-chip IDSEL.
* If it doesn't succeed, may as well bail out at this point.
*/
if (ctx->board_pci_idsel(device, 1) == 0) {
*data = 0xffffffff;
Annotation
- Immediate include surface: `linux/clk.h`, `linux/export.h`, `linux/types.h`, `linux/pci.h`, `linux/platform_device.h`, `linux/kernel.h`, `linux/init.h`, `linux/syscore_ops.h`.
- Detected declarations: `struct alchemy_pci_context`, `function mod_wired_entry`, `function alchemy_pci_wired_entry`, `function config_access`, `function read_config_byte`, `function read_config_word`, `function read_config_dword`, `function write_config_byte`, `function write_config_word`, `function write_config_dword`.
- Atlas domain: Architecture Layer / arch/mips.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.