1 From 4d48a3d1ef6f8d036bd926e3c1f70b56fcc679b2 Mon Sep 17 00:00:00 2001
2 From: Stefan Koch <stefan.koch10@gmail.com>
3 Date: Thu, 20 Oct 2016 21:32:00 +0200
4 Subject: [PATCH] lantiq: vpe
6 Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
8 arch/mips/Kconfig | 6 ++++
9 arch/mips/include/asm/mipsmtregs.h | 5 ++++
10 arch/mips/include/asm/vpe.h | 9 ++++++
11 arch/mips/kernel/vpe-mt.c | 47 ++++++++++++++++++++++++++++++
12 arch/mips/kernel/vpe.c | 35 ++++++++++++++++++++++
13 arch/mips/lantiq/prom.c | 4 +++
14 6 files changed, 106 insertions(+)
16 --- a/arch/mips/Kconfig
17 +++ b/arch/mips/Kconfig
18 @@ -2429,6 +2429,12 @@ config MIPS_VPE_LOADER
19 Includes a loader for loading an elf relocatable object
20 onto another VPE and running it.
23 + bool "IFX APRP Extensions"
24 + depends on MIPS_VPE_LOADER
26 + IFX included extensions in APRP
28 config MIPS_VPE_LOADER_CMP
31 --- a/arch/mips/include/asm/mipsmtregs.h
32 +++ b/arch/mips/include/asm/mipsmtregs.h
34 #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3)
35 #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val)
37 +#define read_c0_vpeopt() __read_32bit_c0_register($1, 7)
38 +#define write_c0_vpeopt(val) __write_32bit_c0_register($1, 7, val)
40 #define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
41 #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
43 @@ -378,6 +381,8 @@ do { \
44 #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
45 #define read_vpe_c0_vpeconf1() mftc0(1, 3)
46 #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val)
47 +#define read_vpe_c0_vpeopt() mftc0(1, 7)
48 +#define write_vpe_c0_vpeopt(val) mttc0(1, 7, val)
49 #define read_vpe_c0_count() mftc0(9, 0)
50 #define write_vpe_c0_count(val) mttc0(9, 0, val)
51 #define read_vpe_c0_status() mftc0(12, 0)
52 --- a/arch/mips/include/asm/vpe.h
53 +++ b/arch/mips/include/asm/vpe.h
54 @@ -124,4 +124,13 @@ void cleanup_tc(struct tc *tc);
56 int __init vpe_module_init(void);
57 void __exit vpe_module_exit(void);
59 +/* For the explanation of the APIs please refer the section "MT APRP Kernel
60 + * Programming" in AR9 SW Architecture Specification
62 +int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags);
63 +int32_t vpe1_sw_stop(uint32_t flags);
64 +uint32_t vpe1_get_load_addr(uint32_t flags);
65 +uint32_t vpe1_get_max_mem(uint32_t flags);
67 #endif /* _ASM_VPE_H */
68 --- a/arch/mips/kernel/vpe-mt.c
69 +++ b/arch/mips/kernel/vpe-mt.c
70 @@ -29,6 +29,7 @@ int vpe_run(struct vpe *v)
71 struct vpe_notifications *notifier;
72 unsigned int vpeflags;
74 + unsigned long physical_memsize = 0L;
76 /* check we are the Master VPE */
77 local_irq_save(flags);
78 @@ -416,6 +417,8 @@ int __init vpe_module_init(void)
81 v->ntcs = hw_tcs - aprp_cpu_index();
82 + write_tc_c0_tcbind((read_tc_c0_tcbind() &
83 + ~TCBIND_CURVPE) | 1);
85 /* add the tc to the list of this vpe's tc's. */
86 list_add(&t->tc, &v->tc);
87 @@ -519,3 +522,47 @@ void __exit vpe_module_exit(void)
92 +#ifdef CONFIG_IFX_VPE_EXT
93 +int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags)
95 + enum vpe_state state;
96 + struct vpe *v = get_vpe(tclimit);
97 + struct vpe_notifications *not;
99 + if (tcmask || flags) {
100 + pr_warn("Currently tcmask and flags should be 0. Other values are not supported\n");
104 + state = xchg(&v->state, VPE_STATE_INUSE);
105 + if (state != VPE_STATE_UNUSED) {
108 + list_for_each_entry(not, &v->notify, list) {
109 + not->stop(tclimit);
113 + v->__start = (unsigned long)sw_start_addr;
116 + pr_debug("VPE loader: VPE1 running successfully\n");
121 +EXPORT_SYMBOL(vpe1_sw_start);
123 +int32_t vpe1_sw_stop(uint32_t flags)
125 + struct vpe *v = get_vpe(tclimit);
127 + if (!vpe_free(v)) {
128 + pr_debug("RP Stopped\n");
133 +EXPORT_SYMBOL(vpe1_sw_stop);
135 --- a/arch/mips/kernel/vpe.c
136 +++ b/arch/mips/kernel/vpe.c
137 @@ -49,6 +49,41 @@ struct vpe_control vpecontrol = {
138 .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
141 +#ifdef CONFIG_IFX_VPE_EXT
142 +unsigned int vpe1_load_addr;
144 +static int __init load_address(char *str)
146 + get_option(&str, &vpe1_load_addr);
149 +__setup("vpe1_load_addr=", load_address);
151 +static unsigned int vpe1_mem;
152 +static int __init vpe1mem(char *str)
154 + vpe1_mem = memparse(str, &str);
157 +__setup("vpe1_mem=", vpe1mem);
159 +uint32_t vpe1_get_load_addr(uint32_t flags)
161 + return vpe1_load_addr;
163 +EXPORT_SYMBOL(vpe1_get_load_addr);
165 +uint32_t vpe1_get_max_mem(uint32_t flags)
172 +EXPORT_SYMBOL(vpe1_get_max_mem);
176 /* get the vpe associated with this minor */
177 struct vpe *get_vpe(int minor)
179 --- a/arch/mips/lantiq/prom.c
180 +++ b/arch/mips/lantiq/prom.c
181 @@ -34,10 +34,14 @@ unsigned long physical_memsize = 0L;
183 static struct ltq_soc_info soc_info;
185 +/* for Multithreading (APRP), vpe.c will use it */
186 +unsigned long cp0_memsize;
188 const char *get_system_type(void)
190 return soc_info.sys_type;
192 +EXPORT_SYMBOL(ltq_soc_type);
194 int ltq_soc_type(void)