arch/mips/kernel/process.c

Source file repositories/reference/linux-study-clean/arch/mips/kernel/process.c

File Facts

System
Linux kernel
Corpus path
arch/mips/kernel/process.c
Extension
.c
Size
22904 bytes
Lines
915
Domain
Architecture Layer
Bucket
arch/mips
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 mips_frame_info {
	void		*func;
	unsigned long	func_size;
	int		frame_size;
	int		pc_offset;
};

#define J_TARGET(pc,target)	\
		(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))

static inline int is_jr_ra_ins(union mips_instruction *ip)
{
#ifdef CONFIG_CPU_MICROMIPS
	/*
	 * jr16 ra
	 * jr ra
	 */
	if (mm_insn_16bit(ip->word >> 16)) {
		if (ip->mm16_r5_format.opcode == mm_pool16c_op &&
		    ip->mm16_r5_format.rt == mm_jr16_op &&
		    ip->mm16_r5_format.imm == 31)
			return 1;
		return 0;
	}

	if (ip->r_format.opcode == mm_pool32a_op &&
	    ip->r_format.func == mm_pool32axf_op &&
	    ((ip->u_format.uimmediate >> 6) & GENMASK(9, 0)) == mm_jalr_op &&
	    ip->r_format.rt == 31)
		return 1;
	return 0;
#else
	if (ip->r_format.opcode == spec_op &&
	    ip->r_format.func == jr_op &&
	    ip->r_format.rs == 31)
		return 1;
	return 0;
#endif
}

static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
{
#ifdef CONFIG_CPU_MICROMIPS
	/*
	 * swsp ra,offset
	 * swm16 reglist,offset(sp)
	 * swm32 reglist,offset(sp)
	 * sw32 ra,offset(sp)
	 * jradiussp - NOT SUPPORTED
	 *
	 * microMIPS is way more fun...
	 */
	if (mm_insn_16bit(ip->word >> 16)) {
		switch (ip->mm16_r5_format.opcode) {
		case mm_swsp16_op:
			if (ip->mm16_r5_format.rt != 31)
				return 0;

			*poff = ip->mm16_r5_format.imm;
			*poff = (*poff << 2) / sizeof(ulong);
			return 1;

		case mm_pool16c_op:
			switch (ip->mm16_m_format.func) {
			case mm_swm16_op:
				*poff = ip->mm16_m_format.imm;
				*poff += 1 + ip->mm16_m_format.rlist;
				*poff = (*poff << 2) / sizeof(ulong);
				return 1;

			default:
				return 0;
			}

		default:
			return 0;
		}
	}

	switch (ip->i_format.opcode) {
	case mm_sw32_op:
		if (ip->i_format.rs != 29)
			return 0;
		if (ip->i_format.rt != 31)
			return 0;

		*poff = ip->i_format.simmediate / sizeof(ulong);
		return 1;

	case mm_pool32b_op:

Annotation

Implementation Notes