arch/mips/bcm47xx/prom.c

Source file repositories/reference/linux-study-clean/arch/mips/bcm47xx/prom.c

File Facts

System
Linux kernel
Corpus path
arch/mips/bcm47xx/prom.c
Extension
.c
Size
5646 bytes
Lines
183
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (off + mem >= max) {
			mem = max;
			pr_debug("Assume 128MB RAM\n");
			break;
		}
		if (!memcmp((void *)prom_init, (void *)prom_init + mem, 32))
			break;
	}
	lowmem = mem;

	/* Ignoring the last page when ddr size is 128M. Cached
	 * accesses to last page is causing the processor to prefetch
	 * using address above 128M stepping out of the ddr address
	 * space.
	 */
	if (c->cputype == CPU_74K && (mem == (128  << 20)))
		mem -= 0x1000;
	memblock_add(0, mem);
}

/*
 * This is the first serial on the chip common core, it is at this position
 * for sb (ssb) and ai (bcma) bus.
 */
#define BCM47XX_SERIAL_ADDR (SSB_ENUM_BASE + SSB_CHIPCO_UART0_DATA)

void __init prom_init(void)
{
	/* Cache CBR addr before CPU/DMA setup */
	bmips_cbr_addr = BMIPS_GET_CBR();
	prom_init_mem();
	setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0);
}

#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM)

#define EXTVBASE	0xc0000000
#define ENTRYLO(x)	((pte_val(pfn_pte((x) >> PFN_PTE_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1)

#include <asm/tlbflush.h>

/* Stripped version of tlb_init, with the call to build_tlb_refill_handler
 * dropped. Calling it at this stage causes a hang.
 */
static void early_tlb_init(void)
{
	write_c0_pagemask(PM_DEFAULT_MASK);
	write_c0_wired(0);
	temp_tlb_entry = current_cpu_data.tlbsize - 1;
	local_flush_tlb_all();
}

void __init bcm47xx_prom_highmem_init(void)
{
	unsigned long off = (unsigned long)prom_init;
	unsigned long extmem = 0;
	bool highmem_region = false;

	if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA))
		return;

	if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
		highmem_region = true;

	if (lowmem != 128 << 20 || !highmem_region)
		return;

	early_tlb_init();

	/* Add one temporary TLB entry to map SDRAM Region 2.
	 *      Physical        Virtual
	 *      0x80000000      0xc0000000      (1st: 256MB)
	 *      0x90000000      0xd0000000      (2nd: 256MB)
	 */
	add_temporary_entry(ENTRYLO(0x80000000),
			    ENTRYLO(0x80000000 + (256 << 20)),
			    EXTVBASE, PM_256M);

	off = EXTVBASE + __pa(off);
	for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
		if (!memcmp((void *)prom_init, (void *)(off + extmem), 16))
			break;
	}
	extmem -= lowmem;

	early_tlb_init();

	if (!extmem)
		return;

Annotation

Implementation Notes