[v2,07/10] MIPS: traps: Handle CPU with non standard vint offset
Commit Message
Some BMIPS cpus has none standard start offset for vector interrupts.
Handle those CPUs in vector size calculation and handler setup process.
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
arch/mips/kernel/traps.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
Comments
On Fri, Oct 27, 2023 at 11:11:03PM +0100, Jiaxun Yang wrote:
> Some BMIPS cpus has none standard start offset for vector interrupts.
>
> Handle those CPUs in vector size calculation and handler setup process.
hmm, I see no connection to what this series is fixing. How does it
work without this patch ?
Thomas.
在 2023/12/22 12:19, Thomas Bogendoerfer 写道:
> On Fri, Oct 27, 2023 at 11:11:03PM +0100, Jiaxun Yang wrote:
>> Some BMIPS cpus has none standard start offset for vector interrupts.
>>
>> Handle those CPUs in vector size calculation and handler setup process.
> hmm, I see no connection to what this series is fixing. How does it
> work without this patch ?
In this series reservation of exception vector is moved to here, so it's
critical
to have correct size.
Thanks
- Jiaxun
>
> Thomas.
>
@@ -74,7 +74,6 @@
#include "access-helper.h"
-#define MAX(a, b) ((a) >= (b) ? (a) : (b))
extern void check_wait(void);
extern asmlinkage void rollback_handle_int(void);
@@ -2005,6 +2004,7 @@ void __noreturn nmi_exception_handler(struct pt_regs *regs)
unsigned long ebase;
EXPORT_SYMBOL_GPL(ebase);
unsigned long exception_handlers[32];
+static unsigned long vi_vecbase;
unsigned long vi_handlers[64];
void reserve_exception_space(phys_addr_t addr, unsigned long size)
@@ -2074,7 +2074,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
handler = (unsigned long) addr;
vi_handlers[n] = handler;
- b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
+ b = (unsigned char *)(vi_vecbase + n*VECTORSPACING);
if (srs >= srssets)
panic("Shadow register set %d not supported", srs);
@@ -2370,20 +2370,33 @@ void __init trap_init(void)
extern char except_vec3_generic;
extern char except_vec4;
extern char except_vec3_r4000;
- unsigned long i, vec_size;
+ unsigned long i, vec_size, vi_vec_offset;
phys_addr_t ebase_pa;
check_wait();
+ if (cpu_has_veic || cpu_has_vint) {
+ switch (current_cpu_type()) {
+ case CPU_BMIPS3300:
+ case CPU_BMIPS4380:
+ vi_vec_offset = 0x400;
+ break;
+ case CPU_BMIPS5000:
+ vi_vec_offset = 0x1000;
+ break;
+ default:
+ vi_vec_offset = 0x200;
+ break;
+ }
+ vec_size = vi_vec_offset + VECTORSPACING*64;
+ } else {
+ vec_size = 0x400;
+ }
+
if (!cpu_has_mips_r2_r6) {
ebase = CAC_BASE;
- vec_size = 0x400;
} else {
- if (cpu_has_veic || cpu_has_vint)
- vec_size = 0x200 + VECTORSPACING*64;
- else
- vec_size = PAGE_SIZE;
-
+ vec_size = max(vec_size, PAGE_SIZE);
ebase_pa = memblock_phys_alloc(vec_size, 1 << fls(vec_size));
if (!ebase_pa)
panic("%s: Failed to allocate %lu bytes align=0x%x\n",
@@ -2450,6 +2463,7 @@ void __init trap_init(void)
* Initialise interrupt handlers
*/
if (cpu_has_veic || cpu_has_vint) {
+ vi_vecbase = ebase + vi_vec_offset;
int nvec = cpu_has_veic ? 64 : 8;
for (i = 0; i < nvec; i++)
set_vi_handler(i, NULL);