Blame view

arch/mips/kernel/smtc-asm.S 3.52 KB
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
1
2
3
4
5
6
7
8
9
10
  /*
   * Assembly Language Functions for MIPS MT SMTC support
   */
  
  /*
   * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. */
  
  #include <asm/regdef.h>
  #include <asm/asmmacro.h>
  #include <asm/stackframe.h>
6e74bae9a   Ralf Baechle   [MIPS] SMTC Build...
11
  #include <asm/irqflags.h>
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  
  /*
   * "Software Interrupt" linkage.
   *
   * This is invoked when an "Interrupt" is sent from one TC to another,
   * where the TC to be interrupted is halted, has it's Restart address
   * and Status values saved by the "remote control" thread, then modified
   * to cause execution to begin here, in kenel mode. This code then
   * disguises the TC state as that of an exception and transfers
   * control to the general exception or vectored interrupt handler.
   */
  	.set noreorder
  
  /*
  The __smtc_ipi_vector would use k0 and k1 as temporaries and
  1) Set EXL (this is per-VPE, so this can't be done by proxy!)
  2) Restore the K/CU and IXMT bits to the pre "exception" state
     (EXL means no interrupts and access to the kernel map).
  3) Set EPC to be the saved value of TCRestart.
  4) Jump to the exception handler entry point passed by the sender.
  
  CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED??
  */
  
  /*
   * Reviled and slandered vision: Set EXL and restore K/CU/IXMT
   * state of pre-halt thread, then save everything and call
   * thought some function pointer to imaginary_exception, which
   * will parse a register value or memory message queue to
   * deliver things like interprocessor interrupts. On return
   * from that function, jump to the global ret_from_irq code
   * to invoke the scheduler and return as appropriate.
   */
  
  #define PT_PADSLOT4 (PT_R0-8)
  #define PT_PADSLOT5 (PT_R0-4)
  
  	.text
  	.align 5
  FEXPORT(__smtc_ipi_vector)
  	.set	noat
  	/* Disable thread scheduling to make Status update atomic */
  	DMT	27					# dmt	k1
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
55
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
56
57
58
59
  	/* Set EXL */
  	mfc0	k0,CP0_STATUS
  	ori	k0,k0,ST0_EXL
  	mtc0	k0,CP0_STATUS
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
60
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  	/* Thread scheduling now inhibited by EXL. Restore TE state. */
  	andi	k1,k1,VPECONTROL_TE
  	beqz	k1,1f
  	emt
  1:
  	/*
  	 * The IPI sender has put some information on the anticipated
  	 * kernel stack frame.  If we were in user mode, this will be
  	 * built above the saved kernel SP.  If we were already in the
  	 * kernel, it will be built above the current CPU SP.
  	 *
  	 * Were we in kernel mode, as indicated by CU0?
  	 */
  	sll	k1,k0,3
  	.set noreorder
  	bltz	k1,2f
  	move	k1,sp
  	.set reorder
  	/*
  	 * If previously in user mode, set CU0 and use kernel stack.
  	 */
  	li	k1,ST0_CU0
  	or	k1,k1,k0
  	mtc0	k1,CP0_STATUS
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
85
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
86
87
88
89
90
91
92
  	get_saved_sp
  	/* Interrupting TC will have pre-set values in slots in the new frame */
  2:	subu	k1,k1,PT_SIZE
  	/* Load TCStatus Value */
  	lw	k0,PT_TCSTATUS(k1)
  	/* Write it to TCStatus to restore CU/KSU/IXMT state */
  	mtc0	k0,$2,1
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
93
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
94
95
96
97
98
  	lw	k0,PT_EPC(k1)
  	mtc0	k0,CP0_EPC
  	/* Save all will redundantly recompute the SP, but use it for now */
  	SAVE_ALL
  	CLI
192ef3661   Ralf Baechle   [MIPS] TRACE_IRQF...
99
  	TRACE_IRQS_OFF
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
100
101
102
  	/* Function to be invoked passed stack pad slot 5 */
  	lw	t0,PT_PADSLOT5(sp)
  	/* Argument from sender passed in stack pad slot 4 */
f431baa55   Atsushi Nemoto   [MIPS] ret_from_i...
103
  	lw	a0,PT_PADSLOT4(sp)
cb56837ea   Ralf Baechle   [MIPS] SMTC: Fix ...
104
105
106
  	LONG_L	s0, TI_REGS($28)
  	LONG_S	sp, TI_REGS($28)
  	PTR_LA	ra, ret_from_irq
f431baa55   Atsushi Nemoto   [MIPS] ret_from_i...
107
  	jr	t0
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
108
109
110
111
112
113
114
115
116
117
118
  
  /*
   * Called from idle loop to provoke processing of queued IPIs
   * First IPI message in queue passed as argument.
   */
  
  LEAF(self_ipi)
  	/* Before anything else, block interrupts */
  	mfc0	t0,CP0_TCSTATUS
  	ori	t1,t0,TCSTATUS_IXMT
  	mtc0	t1,CP0_TCSTATUS
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
119
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
120
121
122
123
124
125
126
127
128
129
130
  	/* We know we're in kernel mode, so prepare stack frame */
  	subu	t1,sp,PT_SIZE
  	sw	ra,PT_EPC(t1)
  	sw	a0,PT_PADSLOT4(t1)
  	la	t2,ipi_decode
  	sw	t2,PT_PADSLOT5(t1)
  	/* Save pre-disable value of TCStatus */
  	sw	t0,PT_TCSTATUS(t1)
  	j	__smtc_ipi_vector
  	nop
  END(self_ipi)