aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/vpe.c100
1 files changed, 44 insertions, 56 deletions
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 97fefcc9dbe7..06be405be399 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -58,10 +58,6 @@
58 58
59typedef void *vpe_handle; 59typedef void *vpe_handle;
60 60
61// defined here because the kernel module loader doesn't have
62// anything to do with it.
63#define SHN_MIPS_SCOMMON 0xff03
64
65#ifndef ARCH_SHF_SMALL 61#ifndef ARCH_SHF_SMALL
66#define ARCH_SHF_SMALL 0 62#define ARCH_SHF_SMALL 0
67#endif 63#endif
@@ -69,11 +65,8 @@ typedef void *vpe_handle;
69/* If this is set, the section belongs in the init part of the module */ 65/* If this is set, the section belongs in the init part of the module */
70#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) 66#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
71 67
72// temp number,
73#define VPE_MAJOR 63
74
75static char module_name[] = "vpe"; 68static char module_name[] = "vpe";
76static int major = 0; 69static int major;
77 70
78/* grab the likely amount of memory we will need. */ 71/* grab the likely amount of memory we will need. */
79#ifdef CONFIG_MIPS_VPE_LOADER_TOM 72#ifdef CONFIG_MIPS_VPE_LOADER_TOM
@@ -98,22 +91,7 @@ enum tc_state {
98 TC_STATE_DYNAMIC 91 TC_STATE_DYNAMIC
99}; 92};
100 93
101struct vpe; 94struct vpe {
102typedef struct tc {
103 enum tc_state state;
104 int index;
105
106 /* parent VPE */
107 struct vpe *pvpe;
108
109 /* The list of TC's with this VPE */
110 struct list_head tc;
111
112 /* The global list of tc's */
113 struct list_head list;
114} tc_t;
115
116typedef struct vpe {
117 enum vpe_state state; 95 enum vpe_state state;
118 96
119 /* (device) minor associated with this vpe */ 97 /* (device) minor associated with this vpe */
@@ -135,7 +113,21 @@ typedef struct vpe {
135 113
136 /* shared symbol address */ 114 /* shared symbol address */
137 void *shared_ptr; 115 void *shared_ptr;
138} vpe_t; 116};
117
118struct tc {
119 enum tc_state state;
120 int index;
121
122 /* parent VPE */
123 struct vpe *pvpe;
124
125 /* The list of TC's with this VPE */
126 struct list_head tc;
127
128 /* The global list of tc's */
129 struct list_head list;
130};
139 131
140struct vpecontrol_ { 132struct vpecontrol_ {
141 /* Virtual processing elements */ 133 /* Virtual processing elements */
@@ -146,7 +138,7 @@ struct vpecontrol_ {
146} vpecontrol; 138} vpecontrol;
147 139
148static void release_progmem(void *ptr); 140static void release_progmem(void *ptr);
149static void dump_vpe(vpe_t * v); 141static void dump_vpe(struct vpe * v);
150extern void save_gp_address(unsigned int secbase, unsigned int rel); 142extern void save_gp_address(unsigned int secbase, unsigned int rel);
151 143
152/* get the vpe associated with this minor */ 144/* get the vpe associated with this minor */
@@ -197,13 +189,11 @@ struct vpe *alloc_vpe(int minor)
197{ 189{
198 struct vpe *v; 190 struct vpe *v;
199 191
200 if ((v = kmalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { 192 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
201 printk(KERN_WARNING "VPE: alloc_vpe no mem\n"); 193 printk(KERN_WARNING "VPE: alloc_vpe no mem\n");
202 return NULL; 194 return NULL;
203 } 195 }
204 196
205 memset(v, 0, sizeof(struct vpe));
206
207 INIT_LIST_HEAD(&v->tc); 197 INIT_LIST_HEAD(&v->tc);
208 list_add_tail(&v->list, &vpecontrol.vpe_list); 198 list_add_tail(&v->list, &vpecontrol.vpe_list);
209 199
@@ -216,13 +206,11 @@ struct tc *alloc_tc(int index)
216{ 206{
217 struct tc *t; 207 struct tc *t;
218 208
219 if ((t = kmalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { 209 if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) {
220 printk(KERN_WARNING "VPE: alloc_tc no mem\n"); 210 printk(KERN_WARNING "VPE: alloc_tc no mem\n");
221 return NULL; 211 return NULL;
222 } 212 }
223 213
224 memset(t, 0, sizeof(struct tc));
225
226 INIT_LIST_HEAD(&t->tc); 214 INIT_LIST_HEAD(&t->tc);
227 list_add_tail(&t->list, &vpecontrol.tc_list); 215 list_add_tail(&t->list, &vpecontrol.tc_list);
228 216
@@ -412,16 +400,17 @@ static int apply_r_mips_26(struct module *me, uint32_t *location,
412 return -ENOEXEC; 400 return -ENOEXEC;
413 } 401 }
414 402
415/* Not desperately convinced this is a good check of an overflow condition 403/*
416 anyway. But it gets in the way of handling undefined weak symbols which 404 * Not desperately convinced this is a good check of an overflow condition
417 we want to set to zero. 405 * anyway. But it gets in the way of handling undefined weak symbols which
418 if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 406 * we want to set to zero.
419 printk(KERN_ERR 407 * if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
420 "module %s: relocation overflow\n", 408 * printk(KERN_ERR
421 me->name); 409 * "module %s: relocation overflow\n",
422 return -ENOEXEC; 410 * me->name);
423 } 411 * return -ENOEXEC;
424*/ 412 * }
413 */
425 414
426 *location = (*location & ~0x03ffffff) | 415 *location = (*location & ~0x03ffffff) |
427 ((*location + (v >> 2)) & 0x03ffffff); 416 ((*location + (v >> 2)) & 0x03ffffff);
@@ -681,7 +670,7 @@ static void dump_tclist(void)
681} 670}
682 671
683/* We are prepared so configure and start the VPE... */ 672/* We are prepared so configure and start the VPE... */
684int vpe_run(vpe_t * v) 673int vpe_run(struct vpe * v)
685{ 674{
686 unsigned long val; 675 unsigned long val;
687 struct tc *t; 676 struct tc *t;
@@ -772,7 +761,7 @@ int vpe_run(vpe_t * v)
772 return 0; 761 return 0;
773} 762}
774 763
775static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs, 764static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
776 unsigned int symindex, const char *strtab, 765 unsigned int symindex, const char *strtab,
777 struct module *mod) 766 struct module *mod)
778{ 767{
@@ -792,10 +781,12 @@ static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
792 return 0; 781 return 0;
793} 782}
794 783
795/* Allocates a VPE with some program code space(the load address), copies the contents 784/*
796 of the program (p)buffer performing relocatations/etc, free's it when finished. 785 * Allocates a VPE with some program code space(the load address), copies
786 * the contents of the program (p)buffer performing relocatations/etc,
787 * free's it when finished.
797*/ 788*/
798int vpe_elfload(vpe_t * v) 789int vpe_elfload(struct vpe * v)
799{ 790{
800 Elf_Ehdr *hdr; 791 Elf_Ehdr *hdr;
801 Elf_Shdr *sechdrs; 792 Elf_Shdr *sechdrs;
@@ -931,7 +922,7 @@ cleanup:
931 return err; 922 return err;
932} 923}
933 924
934static void dump_vpe(vpe_t * v) 925static void dump_vpe(struct vpe * v)
935{ 926{
936 struct tc *t; 927 struct tc *t;
937 928
@@ -947,7 +938,7 @@ static void dump_vpe(vpe_t * v)
947static int vpe_open(struct inode *inode, struct file *filp) 938static int vpe_open(struct inode *inode, struct file *filp)
948{ 939{
949 int minor; 940 int minor;
950 vpe_t *v; 941 struct vpe *v;
951 942
952 /* assume only 1 device at the mo. */ 943 /* assume only 1 device at the mo. */
953 if ((minor = MINOR(inode->i_rdev)) != 1) { 944 if ((minor = MINOR(inode->i_rdev)) != 1) {
@@ -1001,7 +992,7 @@ static int vpe_open(struct inode *inode, struct file *filp)
1001static int vpe_release(struct inode *inode, struct file *filp) 992static int vpe_release(struct inode *inode, struct file *filp)
1002{ 993{
1003 int minor, ret = 0; 994 int minor, ret = 0;
1004 vpe_t *v; 995 struct vpe *v;
1005 Elf_Ehdr *hdr; 996 Elf_Ehdr *hdr;
1006 997
1007 minor = MINOR(inode->i_rdev); 998 minor = MINOR(inode->i_rdev);
@@ -1035,7 +1026,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
1035{ 1026{
1036 int minor; 1027 int minor;
1037 size_t ret = count; 1028 size_t ret = count;
1038 vpe_t *v; 1029 struct vpe *v;
1039 1030
1040 minor = MINOR(file->f_dentry->d_inode->i_rdev); 1031 minor = MINOR(file->f_dentry->d_inode->i_rdev);
1041 if ((v = get_vpe(minor)) == NULL) 1032 if ((v = get_vpe(minor)) == NULL)
@@ -1180,14 +1171,11 @@ static int __init vpe_module_init(void)
1180 return -ENODEV; 1171 return -ENODEV;
1181 } 1172 }
1182 1173
1183 if ((major = register_chrdev(VPE_MAJOR, module_name, &vpe_fops) < 0)) { 1174 if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) {
1184 printk("VPE loader: unable to register character device\n"); 1175 printk("VPE loader: unable to register character device\n");
1185 return -EBUSY; 1176 return major;
1186 } 1177 }
1187 1178
1188 if (major == 0)
1189 major = VPE_MAJOR;
1190
1191 dmt(); 1179 dmt();
1192 dvpe(); 1180 dvpe();
1193 1181