summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/mips/shared/liblnk/pmon.S
blob: 206cfe9a5712096833186e7738d70030d3810e0f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * pmon.S -- low-level entry points into PMON monitor.
 *
 * Copyright (c) 1996, 1997 Cygnus Support
 *
 * The authors hereby grant permission to use, copy, modify, distribute,
 * and license this software and its documentation for any purpose, provided
 * that existing copyright notices are retained in all copies and that this
 * notice is included verbatim in any distributions. No written agreement,
 * license, or royalty fee is required for any of the authorized uses.
 * Modifications to this software may be copyrighted by their authors
 * and need not follow the licensing terms described here, provided that
 * the new terms are clearly indicated on the first page of each file where
 * they apply.
 */

#ifdef __mips16
/* This file contains 32 bit assembly code.  */
	.set nomips16
#endif

#if __mips < 3
  /* This machine does not support 64-bit operations.  */
  #define ADDU addu
  #define SUBU subu
#else
  /* This machine supports 64-bit operations.  */
  #define ADDU daddu
  #define SUBU dsubu
#endif

#include <bsp/regs.h>

	.text
	.align	2

#ifdef LSI
  #define PMON_VECTOR 0xbfc00200
#else
  #define PMON_VECTOR 0xbfc00500
#endif

#ifndef __mips_eabi
/* Provide named functions for entry into the monitor: */
#define INDIRECT(name,index)				\
	.globl	name;					\
	.ent	name;					\
	.set	noreorder;				\
name:	la	$2,+(PMON_VECTOR+((index)*4));		\
	lw	$2,0($2);				\
	j	$2;					\
	nop;						\
	.set	reorder;				\
	.end	name

#else
#define INDIRECT(name,index)				\
	.globl	name;					\
	.ent	name;					\
	.set	noreorder;				\
name:	la	$2,+(PMON_VECTOR+((index)*4));		\
	lw	$2,0($2);				\
	SUBU	sp,sp,0x40;				\
	sd	ra,0x38(sp);				\
	sd	fp,0x30(sp);				\
	jal	$2;					\
	move	fp,sp;					\
	ld	ra,0x38(sp);				\
	ld	fp,0x30(sp);				\
	j	ra;					\
	ADDU	sp,sp,0x40;				\
	.set	reorder;				\
	.end	name
#endif


/* The following magic numbers are for the slots into the PMON monitor */
/* The first are used as the lo-level library run-time: */
INDIRECT(mon_read,0)
INDIRECT(mon_write,1)
INDIRECT(mon_open,2)
INDIRECT(mon_close,3)
/* The following are useful monitor routines: */
INDIRECT(mon_ioctl,4)
INDIRECT(mon_printf,5)
INDIRECT(mon_vsprintf,6)
INDIRECT(mon_ttctl,7)
INDIRECT(mon_cliexit,8)
INDIRECT(mon_getenv,9)
INDIRECT(mon_onintr,10)
INDIRECT(mon_flush_cache,11)
INDIRECT(mon_exception,12)
INDIRECT(mon_fpgaconfig,21)

#if 0

/* The following routine is required by the "print()" function: */
	.globl	pmon_outbyte
	.ent	pmon_outbyte
	.set	noreorder
pmon_outbyte:
	subu	sp,sp,0x20	/* allocate stack space for string */
	sd	ra,0x18(sp)	/* stack return address */
	sd	fp,0x10(sp)	/* stack frame-pointer */
	move	fp,sp		/* take a copy of the stack pointer */
	/* We leave so much space on the stack for the string (16
	   characters), since the call to mon_printf seems to corrupt
	   the 8bytes at offset 8 into the string/stack. */
	sb	a0,0x00(sp)	/* character to print */
	sb	z0,0x01(sp)	/* NUL terminator */
	jal	mon_printf	/* and output the string */
	move	a0,sp		/* take a copy of the string pointer {DELAY SLOT} */

	move	sp,fp		/* recover stack pointer */
	ld	ra,0x18(sp)	/* recover return address */
	ld	fp,0x10(sp)	/* recover frame-pointer */
	j	ra		/* return to the caller */
	addu	sp,sp,0x20	/* dump the stack space {DELAY SLOT} */
	.set	reorder
	.end	pmon_outbyte

/* The following routine is required by the "sbrk()" function: */
	.globl	get_mem_info
	.ent	get_mem_info
	.set	noreorder
get_mem_info:
	# in:  a0 = pointer to 3 word structure
	# out: void
	subu	sp,sp,0x18	/* create some stack space */
	sd	ra,0x00(sp)	/* stack return address */
	sd	fp,0x08(sp)	/* stack frame-pointer */
	sd	a0,0x10(sp)	/* stack structure pointer */
	move	fp,sp		/* take a copy of the stack pointer */

	# The monitor has already sized memory, but unfortunately we
	# do not have access to the data location containing the
	# memory size.

	jal	__sizemem
	nop

	ld	a0,0x10(sp)	# recover structure pointer
	sw	v0,0(a0)	# amount of memory available

	# Deal with getting the cache size information:
	mfc0	a1, C0_CONFIG
	nop
	nop
	andi	a2,a1,0x7 << 9	# bits 11..9 for instruction cache size
	sll	a2,a2,12 - 8
	sw 	a2,4(a0)
	andi	a2,a1,0x7 << 6	# bits 8..6 for data cache size
	sll	a2,a2,12 - 5
	sw 	a2,8(a0)	# data cache size
	#
	move	sp,fp		/* recover stack pointer */
	ld	ra,0x00(sp)	/* recover return address */
	ld	fp,0x08(sp)	/* recover frame-pointer */
	j	ra		/* return to the caller */
	addu	sp,sp,0x18	/* restore stack pointer {DELAY SLOT} */
	.set	reorder
	.end	get_mem_info

#ifdef LSI

# For the LSI MiniRISC board, we can safely assume that we have
# at least one megabyte of RAM.

	.globl	__sizemem
	.ent	__sizemem
__sizemem:
	li	v0,0x100000
	j	ra
	.end	__sizemem
#else

#endif

#endif
/* EOF pmon.S */