APRP operation of the 34K has been multiply broken in 2.6.24.4. The following patch set gets things working seemingly reliably. The first two were previously submitted to Ralf as essential to get RP programs to launch safely. The larger third patch is new, and gets the Linux I/O services for the RP working again, and fixes formatting in a few places. Note that SMTC has scheduling problems in 2.6.24, so testing under SMTC has been limited to boots with only one TC acting as a Linux CPU. Regards, Kevin K.
>From d164aa1b9dba720ee08a6a773e1a81b62aea7d10 Mon Sep 17 00:00:00 2001 From: Kevin D. Kissell <kevink@xxxxxxxx> Date: Thu, 10 Apr 2008 02:07:38 +0200 Subject: [PATCH] Fixes necessary for non-SMP kernels and non-relocatable binaries Signed-off-by: Kevin D. Kissell <kevink@xxxxxxxx> --- arch/mips/kernel/vpe.c | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 95446fa..4515f1e 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -782,10 +782,15 @@ static int vpe_run(struct vpe * v) /* take system out of configuration state */ clear_c0_mvpcontrol(MVPCONTROL_VPC); + /* + * SMTC/SMVP kernels manage VPE enable independently, + * but uniprocessor kernels need to turn it on, even + * if that wasn't the pre-dvpe() state. + */ #ifdef CONFIG_SMP - evpe(EVPE_ENABLE); -#else evpe(vpeflags); +#else + evpe(EVPE_ENABLE); #endif emt(dmt_flag); local_irq_restore(flags); @@ -948,12 +953,13 @@ static int vpe_elfload(struct vpe * v) struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff); for (i = 0; i < hdr->e_phnum; i++) { - if (phdr->p_type != PT_LOAD) - continue; - - memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz); - memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); - phdr++; + if (phdr->p_type == PT_LOAD) { + memcpy((void *)phdr->p_paddr, + (char *)hdr + phdr->p_offset, phdr->p_filesz); + memset((void *)phdr->p_paddr + phdr->p_filesz, + 0, phdr->p_memsz - phdr->p_filesz); + } + phdr++; } for (i = 0; i < hdr->e_shnum; i++) { -- 1.5.3.3
>From 3fb8ed1c2eab46d17ec090f1d9e3a1a54ada4e6a Mon Sep 17 00:00:00 2001 From: Kevin D. Kissell <kevink@xxxxxxxx> Date: Thu, 10 Apr 2008 02:45:26 +0200 Subject: [PATCH] Propagate max_low_pfn as max_pfn for compatibility with legacy driver and aprp code. Signed-off-by: Kevin D. Kissell <kevink@xxxxxxxx> --- arch/mips/kernel/setup.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index f8a535a..a6a0d62 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -336,6 +336,10 @@ static void __init bootmem_init(void) #endif max_low_pfn = PFN_DOWN(HIGHMEM_START); } + /* + * Propagate final value of max_low_pfn to max_pfn + */ + max_pfn = max_low_pfn; /* * Initialize the boot-time allocator with low memory only. -- 1.5.3.3
>From a523893f2d44fc47231abc698fd908666b7de570 Mon Sep 17 00:00:00 2001 From: Kevin D. Kissell <kevink@xxxxxxxx> Date: Wed, 16 Apr 2008 11:56:31 +0200 Subject: [PATCH] Functional Fixes and a little reformatting of APRP Support for MIPS MT Signed-off-by: Kevin D. Kissell <kevink@xxxxxxxx> --- arch/mips/kernel/Makefile | 2 +- arch/mips/kernel/kspd.c | 5 ++- arch/mips/kernel/rtlx.c | 101 +++++++++++++++++++++++++++------------------ include/asm-mips/rtlx.h | 4 +- 4 files changed, 68 insertions(+), 44 deletions(-) diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index ffa0836..0ce7bca 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -51,9 +51,9 @@ obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o -obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o +obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index d2c2e00..5e86c3a 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -257,7 +257,7 @@ void sp_work_handle_request(void) vcwd = vpe_getcwd(tclimit); - /* change to the cwd of the process that loaded the SP program */ + /* change to cwd of the process that loaded the SP program */ old_fs = get_fs(); set_fs(KERNEL_DS); sys_chdir(vcwd); @@ -323,6 +323,9 @@ static void sp_cleanup(void) set >>= 1; } } + + /* Put daemon cwd back to root to avoid umount problems */ + sys_chdir("/"); } static int channel_open = 0; diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 1ba00c1..c0bb347 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -73,6 +73,15 @@ static void rtlx_dispatch(void) static irqreturn_t rtlx_interrupt(int irq, void *dev_id) { int i; + unsigned int flags, vpeflags; + + /* Ought not to be strictly necessary for SMTC builds */ + local_irq_save(flags); + vpeflags = dvpe(); + set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ); + irq_enable_hazard(); + evpe(vpeflags); + local_irq_restore(flags); for (i = 0; i < RTLX_CHANNELS; i++) { wake_up(&channel_wqs[i].lx_queue); @@ -109,7 +118,8 @@ static void __used dump_rtlx(void) static int rtlx_init(struct rtlx_info *rtlxi) { if (rtlxi->id != RTLX_ID) { - printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id); + printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", + rtlxi, rtlxi->id); return -ENOEXEC; } @@ -163,51 +173,51 @@ int rtlx_open(int index, int can_sleep) if (rtlx == NULL) { if( (p = vpe_get_shared(tclimit)) == NULL) { - if (can_sleep) { - __wait_event_interruptible(channel_wqs[index].lx_queue, - (p = vpe_get_shared(tclimit)), - ret); - if (ret) - goto out_fail; - } else { - printk(KERN_DEBUG "No SP program loaded, and device " - "opened with O_NONBLOCK\n"); - ret = -ENOSYS; + if (can_sleep) { + __wait_event_interruptible(channel_wqs[index].lx_queue, + (p = vpe_get_shared(tclimit)), ret); + if (ret) goto out_fail; - } + } else { + printk(KERN_DEBUG "No SP program loaded, and device " + "opened with O_NONBLOCK\n"); + ret = -ENOSYS; + goto out_fail; + } } smp_rmb(); if (*p == NULL) { - if (can_sleep) { - DEFINE_WAIT(wait); - - for (;;) { - prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE); - smp_rmb(); - if (*p != NULL) - break; - if (!signal_pending(current)) { - schedule(); - continue; - } - ret = -ERESTARTSYS; - goto out_fail; + if (can_sleep) { + DEFINE_WAIT(wait); + + for (;;) { + prepare_to_wait(&channel_wqs[index].lx_queue, + &wait, TASK_INTERRUPTIBLE); + smp_rmb(); + if (*p != NULL) + break; + if (!signal_pending(current)) { + schedule(); + continue; } - finish_wait(&channel_wqs[index].lx_queue, &wait); - } else { - printk(" *vpe_get_shared is NULL. " - "Has an SP program been loaded?\n"); - ret = -ENOSYS; + ret = -ERESTARTSYS; goto out_fail; } + finish_wait(&channel_wqs[index].lx_queue, &wait); + } else { + printk(" *vpe_get_shared is NULL. " + "Has an SP program been loaded?\n"); + ret = -ENOSYS; + goto out_fail; + } } if ((unsigned int)*p < KSEG0) { - printk(KERN_WARNING "vpe_get_shared returned an invalid pointer " - "maybe an error code %d\n", (int)*p); - ret = -ENOSYS; - goto out_fail; + printk(KERN_WARNING "vpe_get_shared returned an invalid " + "pointer maybe an error code %d\n", (int)*p); + ret = -ENOSYS; + goto out_fail; } if ((ret = rtlx_init(*p)) < 0) @@ -233,6 +243,10 @@ out_ret: int rtlx_release(int index) { + if (rtlx == NULL) { + printk("rtlx_release() with null rtlx\n"); + return 0; + } rtlx->channel[index].lx_state = RTLX_STATE_UNUSED; return 0; } @@ -252,8 +266,8 @@ unsigned int rtlx_read_poll(int index, int can_sleep) int ret = 0; __wait_event_interruptible(channel_wqs[index].lx_queue, - chan->lx_read != chan->lx_write || sp_stopping, - ret); + (chan->lx_read != chan->lx_write) + || sp_stopping, ret); if (ret) return ret; @@ -283,7 +297,9 @@ static inline int write_spacefree(int read, int write, int size) unsigned int rtlx_write_poll(int index) { struct rtlx_channel *chan = &rtlx->channel[index]; - return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); + + return write_spacefree(chan->rt_read, chan->rt_write, + chan->buffer_size); } ssize_t rtlx_read(int index, void __user *buff, size_t count) @@ -345,8 +361,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count) rt_read = rt->rt_read; /* total number of bytes to copy */ - count = min(count, - (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size)); + count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write, + rt->buffer_size)); /* first bit from write pointer to the end of the buffer, or count */ fl = min(count, (size_t) rt->buffer_size - rt->rt_write); @@ -515,6 +531,11 @@ static int __init rtlx_module_init(void) if (cpu_has_vint) set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); + else { + printk("APRP RTLX init on non-vectored-interrupt processor\n"); + err = -ENODEV; + goto out_chrdev; + } rtlx_irq.dev_id = rtlx; setup_irq(rtlx_irq_num, &rtlx_irq); diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h index 65778c8..20b6660 100644 --- a/include/asm-mips/rtlx.h +++ b/include/asm-mips/rtlx.h @@ -29,13 +29,13 @@ extern unsigned int rtlx_read_poll(int index, int can_sleep); extern unsigned int rtlx_write_poll(int index); enum rtlx_state { - RTLX_STATE_UNUSED, + RTLX_STATE_UNUSED = 0, RTLX_STATE_INITIALISED, RTLX_STATE_REMOTE_READY, RTLX_STATE_OPENED }; -#define RTLX_BUFFER_SIZE 1024 +#define RTLX_BUFFER_SIZE 2048 /* each channel supports read and write. linux (vpe0) reads lx_buffer and writes rt_buffer -- 1.5.3.3