arch/sparc/mm/init_64.c

Source file repositories/reference/linux-study-clean/arch/sparc/mm/init_64.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/mm/init_64.c
Extension
.c
Size
77676 bytes
Lines
3150
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration 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

struct node_mem_mask {
	unsigned long mask;
	unsigned long match;
};
static struct node_mem_mask node_masks[MAX_NUMNODES];
static int num_node_masks;

#ifdef CONFIG_NUMA

struct mdesc_mlgroup {
	u64	node;
	u64	latency;
	u64	match;
	u64	mask;
};

static struct mdesc_mlgroup *mlgroups;
static int num_mlgroups;

int numa_cpu_lookup_table[NR_CPUS];
cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];

struct mdesc_mblock {
	u64	base;
	u64	size;
	u64	offset; /* RA-to-PA */
};
static struct mdesc_mblock *mblocks;
static int num_mblocks;

static struct mdesc_mblock * __init addr_to_mblock(unsigned long addr)
{
	struct mdesc_mblock *m = NULL;
	int i;

	for (i = 0; i < num_mblocks; i++) {
		m = &mblocks[i];

		if (addr >= m->base &&
		    addr < (m->base + m->size)) {
			break;
		}
	}

	return m;
}

static u64 __init memblock_nid_range_sun4u(u64 start, u64 end, int *nid)
{
	int prev_nid, new_nid;

	prev_nid = NUMA_NO_NODE;
	for ( ; start < end; start += PAGE_SIZE) {
		for (new_nid = 0; new_nid < num_node_masks; new_nid++) {
			struct node_mem_mask *p = &node_masks[new_nid];

			if ((start & p->mask) == p->match) {
				if (prev_nid == NUMA_NO_NODE)
					prev_nid = new_nid;
				break;
			}
		}

		if (new_nid == num_node_masks) {
			prev_nid = 0;
			WARN_ONCE(1, "addr[%Lx] doesn't match a NUMA node rule. Some memory will be owned by node 0.",
				  start);
			break;
		}

		if (prev_nid != new_nid)
			break;
	}
	*nid = prev_nid;

	return start > end ? end : start;
}

static u64 __init memblock_nid_range(u64 start, u64 end, int *nid)
{
	u64 ret_end, pa_start, m_mask, m_match, m_end;
	struct mdesc_mblock *mblock;
	int _nid, i;

	if (tlb_type != hypervisor)
		return memblock_nid_range_sun4u(start, end, nid);

	mblock = addr_to_mblock(start);
	if (!mblock) {
		WARN_ONCE(1, "memblock_nid_range: Can't find mblock addr[%Lx]",

Annotation

Implementation Notes