Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

GENERIC kernel hangs on boot on WYSE Winterm s10



Hello,
I'm trying to fix a bug that causes the kernel to freeze on boot on a
WYSE Winterm s10 thin client. I've narrowed it down to a single
bus_space_write_1() call in pckbc_attach() that hangs the kernel.

The s10 is an AMD/NSC Geode based SBC, that uses the CS5536 chip for
most of its PC internals. This chip, called the companion device seems
to be a Geode-specific IC that emulates, among others, the 8048
keyboard controller (page 120 and 401 of
https://www.amd.com/system/files/TechDocs/33238G_cs5536_db.pdf ).
This computer does not have a PS/2 port so all PS/2keyboard emulation
is done by the BIOS and this chip.

Internally it runs some form of a thin client os, based on WinNT by
the looks of it. Linux 2.x, FreeDOS and openbsd boot fine.

Here is a modified version of pckbc_send_cmd function i used to narrow
down where the function is called:

src/sys/dev/ic/pckbc.c:

int
pckbc_send_cmd(bus_space_tag_t iot, bus_space_handle_t ioh_c, u_char val)
{
	printf(">>>...send_cmd: entering function, iot=0x%lx, ioh=0x%lx, val=0x%x\n",
	       (unsigned long int) iot, (unsigned long int) ioh_c, val);
	if (!pckbc_wait_output(iot, ioh_c)){
		printf(">>>...send_cmd: wait_output failed, exiting\n");
		return (0);
	}
	printf(">>>...send_cmd: attempting to write the value..\n");
	printf(">>>...send_cmd: iot=0x%lx\tioh_c=0x%lx\tval=0x%x\n",
	       (long unsigned int) iot,
	       (long unsigned int) ioh_c,
	       val);
	bus_space_write_1(iot, ioh_c, 0, val);
	printf(">>>...send_cmd: ok, exiting function");
	return (1);
}

And a revelant piece of the boot log, this is captured using a serial console:

>>>...send_cmd: entering function, iot=0xc112f620, ioh=0x64, val=0xaa
>>>>...wait_output: entering function...done, exiting function
>>>...send_cmd: attempting to write the value..
>>>...send_cmd: iot=0xc112f620	ioh_c=0x64	val=0xaa

And here is a picture of the VGA console messages (they are different,
since pkcbc0 is not a console keyboard on serial console):
https://i.ibb.co/gVQr3bj/IMG-20190118-224004.jpg (4.6MB)
The 0h@0h array is just the output of my helper function dumping the
receive buffer from struct pckbc_internal.

The kernel hangs at this point.

I have tested that a write to other address is OK, I haven't tested a
raw bus_space_write_1 call or tried an assembly snippet to write at
the address of 0x64 a value from another place in the kernel yet.

I've looked at bus_space_write_1 here:

sys/arch/i386/i386/busfunc.S:
/*
 * void bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
 *    bus_size_t offset, uint8_t value);
 */
ENTRY(bus_space_write_1)
	movl	4(%esp), %eax
	movl	8(%esp), %edx
	addl	12(%esp), %edx
	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
	movl	16(%esp), %eax
	je	1f
	movb	%al, (%edx)
	ret
1:
	outb	%al, %dx
	ret
END(bus_space_write_1)

I've came up with two hypotheses: either the companion device is
acting flaky because of this write, or this asm procedure is not
branching properly and executing movb	%al, (%edx) instead of outb	%al,
%dx .

The kernel boots OK if I use userconf to disable pckbc0 on boot.

Here's some info about the board itself:
https://www.parkytowers.me.uk/thin/wyse/s10/
Those computers are extremely weird, to the point where revision B4 of
the board refuses to boot from anything bigger than 2GB. Rev A1 is
solid and that's what I'm running netbsd on.
Rev A1 is pictured on the bottom picture on that side (the PCB with
the 44 pin IDE)

Please excuse any mistakes as this is my first time of doing this low
level programming on a PC (I've done microcontrollers a lot), as well
as NetBSD programming and mailing list usage!
Cheers,
Chris


Home | Main Index | Thread Index | Old Index