Subject: help with nathanw_sa branch on sh3
To: None <port-sh3@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: port-sh3
Date: 12/18/2002 14:13:28
--EVF5PPMfhYS0aIcm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Folks...

I've been trying to track down lossage with the nathanw_sa branch
on the sh3 (well, my test system is really an sh4 [dreamcast], but
you get the idea :-)

The problem is most easily produced with the "sa3" test (which I
have attached at the end of this message).  Running the test will
cause an assertion failure in tlb_exception() if you are running
a DEBUG kernel:

	if (usermode) {
		KDASSERT(l->l_md.md_regs == tf);
	}

...here is what I know about the problem so far:

	* Process has 2 LWPs at the time of assertion failure.

	* LWP1 l_md.md_regs == tf1-address

	* LWP2 l_md.md_regs == tf2-address

	* When the assertion fails, LWP1 is the active LWP, but the
	  tf passed to tlb_exception() is tf2-address.

...how this can happen, I just don't know.  I guess somehow r6_bank
(though the saved value in the PCB looks fine ??) for LWP1 is getting
the wrong value stuffed into it at some point, but I'm not really sure
how that is happening.

I've stared at this code long enough that my eyes have glazed over, and
I need some help in getting this fixed ... I'm trying to knock down the
remaining TODO items which are preventing the kernel portions from being
merged into the mainline.  This sh3 bug is one of those items.

I can provide a nathanw_sa userland for sh3 if you don't particularly
feel like building one (though, it is pretty easy :-)

Thanks for any help you folks can provide.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

--EVF5PPMfhYS0aIcm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sa3.c"


#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ucontext.h>
#include <sys/types.h>
#include <sys/lwp.h>
#include <sys/sa.h>

void lstart(void *arg);

int handled;

void handler(int sig, int code, struct sigcontext *scp);
void handler2(int sig, int code, struct sigcontext *scp);
void upcall(int t, struct sa_t *sas[], int e, int i, void *);

int n;

int main(void)
{

	stack_t stack;
	int error;
	char buf[100];
	int i, ret;

	sa_register(upcall, NULL);

	do {
		stack.ss_size = 65536;
		stack.ss_sp = malloc(stack.ss_size);
		ret = sa_stacks(1, &stack);
		printf("Added %d stack%s.\n",
		    ret, (ret == 1) ? "" : "s");
	} while (ret > 0);

	sa_enable();

	printf("Uh, we shouldn't get here.\n");

	return 0;
}

void upcall(int t, struct sa_t *sas[], int e, int i, void *arg)
{
	int x;

	char buf1[1000], buf2[100];

	

	write(1, buf1, strlen(buf1));

	sprintf(buf1, "Cool, I'm an upcall. ");
	sprintf(buf2, "Type: %d\n", t);
	strcat(buf1, buf2);
	sprintf(buf2, "Arg: %p\n", arg);
	strcat(buf1, buf2);
	sprintf(buf2, "My sa_id: %d\n", sas[0]->sa_id);
	strcat(buf1, buf2);
	sprintf(buf2, "  0 context: %p ID: %x CPU: %d\n",
	    sas[0]->sa_context, sas[0]->sa_id, sas[0]->sa_cpu);
	strcat(buf1, buf2);

	sprintf(buf2, "Events: %d\n", e);
	strcat(buf1, buf2);
	for (x = 1; x < 1 + e ; x++) {
		sprintf(buf2, "  %d context: %p ID: %x CPU: %d\n",
		    x, sas[x]->sa_context, sas[x]->sa_id, sas[x]->sa_cpu);
		strcat(buf1, buf2);

	}
	sprintf(buf2, "Interrupted: %d\n", i);
		strcat(buf1, buf2);
	for (x = 1 + e; x < 1 + e + i ; x++) {
		printf("  %d ID: %d\n", x, sas[x]->sa_id);
		strcat(buf1, buf2);
	}


	if ((++n < 8) && t != 3) {
		sprintf(buf2, "Sleeping, should trigger another upcall.\n");
		strcat(buf1, buf2);
		write(1, buf1, strlen(buf1));
		sleep(5);
	}

	exit(0);
}

--EVF5PPMfhYS0aIcm--