Subject: Re: user space hw io: final
To: Peter L. Peres <plp@actcom.co.il>
From: Frederick Bruckman <fredb@immanent.net>
List: port-i386
Date: 12/24/2004 12:52:32
In article <Pine.LNX.4.60.0412240140480.10955@cyc.cyc.ubzr.bet>,
	plp@actcom.co.il (Peter L. Peres) writes:
> 
> I have run all the necessary debugging, getting io space permissions as 
> user root with i386_get_ioperm and then reading and writing io space 
> using inb, outb, inw, outw yields the following:
> 
> - the ioperm read map is initially always all 1's
> - setting 0's in the map at addresses where I wish to write always 
> works, even if the addresses are taken by a configured driver (setting 
> zeros according to the manual page)
> - reading from any address works
> - writing to any address always busfaults, regardless of whether the 
> address is owned by a driver or not
>
> Kernel is netbsd-1.6.1 GENERIC, /dev/io is not configured
> 
> I conclude that what I am trying to do is not possible (can't write to 
> kernel io bus space) with the current kernel.

It works for me, on current and NetBSD 2.0, except that with the default
of kern.securelevel=-1, writing always works, no matter what's in the map.

Here's my test program:


#include <stdio.h>
#include <unistd.h>

#include <machine/sysarch.h>

#define PORT 0x378
#define VAL 0xAA

int
main (int argc, char **argv) {
	uint32_t map[32];
	register uint16_t port;
	register uint8_t val;

	port = PORT;
	val = VAL;

	if (i386_get_ioperm((long *)map) == -1)
		perror("i386_get_ioperm");
	map[port / 32] &= ~(1 << (port % 32));
	if (i386_set_ioperm((long *)map) == -1)
		perror("i386_set_ioperm");

	__asm__ __volatile__("outb %0,%1" :: "a" (val), "d" (port));
	__asm__ __volatile__("inb %1,%0" : "=a" (val) : "d" (port));
	printf("wrote 0x%X, read 0x%X\n", VAL, val);
	return 0;
}


I couldn't get the port value to change, either by writing to it, or by
shorting pins.  I may have the printer port off in the CMOS settings.


Frederick