Turn PCI into a character driver
Change-Id: Ia9c83af4d52e82e845b6a847c3e82e33d1920ae0
This commit is contained in:
parent
3641562f44
commit
5d8311761a
18 changed files with 455 additions and 223 deletions
|
@ -1810,7 +1810,7 @@
|
|||
./usr/include/sys/verified_exec.h minix-sys
|
||||
./usr/include/sys/video.h minix-sys
|
||||
./usr/include/sys/videoio.h minix-sys
|
||||
./usr/include/sys/vm.h minix-sys
|
||||
./usr/include/sys/vm.h minix-sys obsolete
|
||||
./usr/include/sys/vmmeter.h minix-sys
|
||||
./usr/include/sys/vnode.h minix-sys
|
||||
./usr/include/sys/vnode_if.h minix-sys
|
||||
|
|
|
@ -26,6 +26,7 @@ RAMDISK_DEVICES="
|
|||
c1d4 c1d4p0 c1d4p0s0 c1d5 c1d5p0 c1d5p0s0
|
||||
c1d6 c1d6p0 c1d6p0s0 c1d7 c1d7p0 c1d7p0s0
|
||||
fd0 fd1 fd0p0 fd1p0
|
||||
pci
|
||||
ttyc1 ttyc2 ttyc3 tty00 tty01 tty02 tty03
|
||||
ttyp0 ttyp1 ttyp2 ttyp3 ttyp4 ttyp5 ttyp6 ttyp7 ttyp8 ttyp9
|
||||
ttypa ttypb ttypc ttypd ttype ttypf
|
||||
|
@ -137,6 +138,7 @@ Where key is one of the following:
|
|||
fbd # Make /dev/fbd
|
||||
hello # Make /dev/hello
|
||||
video # Make /dev/video
|
||||
pci # Make /dev/pci
|
||||
vnd0 vnd0p0 vnd0p0s0 .. # Make vnode disks /dev/vnd[0-7] and (sub)partitions
|
||||
input # Make /dev/kbdmux, /dev/kbd[0-3], idem /dev/mouse~
|
||||
EOF
|
||||
|
@ -363,6 +365,10 @@ do
|
|||
minor=`expr ${minor} + 4`
|
||||
done
|
||||
;;
|
||||
pci)
|
||||
# PCI server, manages PCI buses
|
||||
makedev pci c 134 0 ${uname} ${gname} ${permissions}
|
||||
;;
|
||||
ram|mem|kmem|null|boot|zero|imgrd)
|
||||
# Memory devices.
|
||||
makedev ram b 1 0 ${uname} kmem ${permissions}
|
||||
|
|
|
@ -9,9 +9,9 @@ SRCS= main.c pci.c pci_table.c
|
|||
SRCS+= pci_verbose.c pci_subr.c
|
||||
CPPFLAGS.pci_subr.c+= -D_PCI_SERVER
|
||||
|
||||
DPADD+= ${LIBSYS} ${LIBTIMERS}
|
||||
LDADD+= -lsys -ltimers
|
||||
DPADD+= ${LIBCHARDRIVER}
|
||||
LDADD+= -lchardriver
|
||||
|
||||
WARNS?= 3
|
||||
WARNS= 3
|
||||
|
||||
.include <minix.service.mk>
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <dev/pci/pciio.h>
|
||||
|
||||
#include <minix/chardriver.h>
|
||||
#include <minix/driver.h>
|
||||
#include <minix/rs.h>
|
||||
|
||||
|
@ -6,22 +11,9 @@
|
|||
int debug = 0;
|
||||
struct pci_acl pci_acl[NR_DRIVERS];
|
||||
|
||||
static void
|
||||
sef_local_startup()
|
||||
{
|
||||
/* Register init callbacks. */
|
||||
sef_setcb_init_fresh(sef_cb_init_fresh);
|
||||
sef_setcb_init_lu(sef_cb_init_fresh);
|
||||
sef_setcb_init_restart(sef_cb_init_fresh);
|
||||
|
||||
/* Register live update callbacks. */
|
||||
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
|
||||
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
|
||||
|
||||
/* Let SEF perform startup. */
|
||||
sef_startup();
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* Helpers *
|
||||
*======================================================================*/
|
||||
static struct rs_pci *
|
||||
find_acl(int endpoint)
|
||||
{
|
||||
|
@ -50,7 +42,6 @@ reply(message *mp, int result)
|
|||
printf("reply: unable to send to %d: %d\n", mp->m_source, r);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_init(message *mp)
|
||||
{
|
||||
|
@ -527,58 +518,239 @@ do_rescan_bus(message *mp)
|
|||
}
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* CharDriver Callbacks *
|
||||
*======================================================================*/
|
||||
static int
|
||||
pci_open(devminor_t UNUSED(minor), int UNUSED(access),
|
||||
endpoint_t UNUSED(user_endpt))
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
pci_close(devminor_t UNUSED(minor))
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
pci_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
||||
cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id)
|
||||
{
|
||||
int devind;
|
||||
int r = ENOTTY;
|
||||
|
||||
switch(request)
|
||||
{
|
||||
case PCI_IOC_BDF_CFGREAD:
|
||||
{
|
||||
struct pciio_bdf_cfgreg bdf;
|
||||
|
||||
if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&bdf,
|
||||
sizeof(bdf))) != OK)
|
||||
break;
|
||||
|
||||
r = _pci_find_dev(bdf.bus, bdf.device, bdf.function, &devind);
|
||||
if (r != 1) {
|
||||
r = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((r = _pci_attr_r32(devind, bdf.cfgreg.reg,
|
||||
&bdf.cfgreg.val)) != OK)
|
||||
break;
|
||||
|
||||
r = sys_safecopyto(endpt, grant, 0, (vir_bytes)&bdf,
|
||||
sizeof(bdf));
|
||||
break;
|
||||
}
|
||||
case PCI_IOC_BDF_CFGWRITE:
|
||||
{
|
||||
struct pciio_bdf_cfgreg bdf;
|
||||
|
||||
if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&bdf,
|
||||
sizeof(bdf))) != OK)
|
||||
break;
|
||||
|
||||
r = _pci_find_dev(bdf.bus, bdf.device, bdf.function, &devind);
|
||||
if (r != 1) {
|
||||
r = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
_pci_attr_w32(devind, bdf.cfgreg.reg, bdf.cfgreg.val);
|
||||
r = OK;
|
||||
break;
|
||||
}
|
||||
case PCI_IOC_BUSINFO:
|
||||
break;
|
||||
case PCI_IOC_MAP:
|
||||
{
|
||||
struct pciio_map map;
|
||||
struct minix_mem_range mr;
|
||||
|
||||
if ((r = sys_safecopyfrom(endpt, grant, 0,
|
||||
(vir_bytes)&map, sizeof(map))) != OK)
|
||||
break;
|
||||
|
||||
#if 1
|
||||
mr.mr_base = map.phys_offset;
|
||||
mr.mr_limit = map.phys_offset + map.size - 1;
|
||||
|
||||
r = sys_privctl(user_endpt, SYS_PRIV_ADD_MEM, &mr);
|
||||
if (r != OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
map.vaddr_ret = vm_map_phys(user_endpt,
|
||||
(void *)map.phys_offset, map.size);
|
||||
r = sys_safecopyto(endpt, grant, 0, (vir_bytes)&map,
|
||||
sizeof(map));
|
||||
break;
|
||||
}
|
||||
case PCI_IOC_UNMAP:
|
||||
{
|
||||
struct pciio_map map;
|
||||
|
||||
if ((r = sys_safecopyfrom(endpt, grant, 0,
|
||||
(vir_bytes)&map, sizeof(map))) != OK)
|
||||
break;
|
||||
|
||||
r = vm_unmap_phys(user_endpt, map.vaddr, map.size);
|
||||
break;
|
||||
}
|
||||
case PCI_IOC_RESERVE:
|
||||
{
|
||||
struct pciio_acl acl;
|
||||
|
||||
if ((r = sys_safecopyfrom(endpt, grant, 0,
|
||||
(vir_bytes)&acl, sizeof(acl))) != OK)
|
||||
break;
|
||||
|
||||
r = _pci_find_dev(acl.bus, acl.device, acl.function, &devind);
|
||||
if (r != 1) {
|
||||
r = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
r = _pci_grant_access(devind, user_endpt);
|
||||
break;
|
||||
}
|
||||
case PCI_IOC_RELEASE:
|
||||
{
|
||||
struct pciio_acl acl;
|
||||
|
||||
if ((r = sys_safecopyfrom(endpt, grant, 0,
|
||||
(vir_bytes)&acl, sizeof(acl))) != OK)
|
||||
break;
|
||||
|
||||
r = _pci_find_dev(acl.bus, acl.device, acl.function, &devind);
|
||||
if (r != 1) {
|
||||
r = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
_pci_release(endpt);
|
||||
r = OK;
|
||||
|
||||
break;
|
||||
}
|
||||
case PCI_IOC_CFGREAD:
|
||||
case PCI_IOC_CFGWRITE:
|
||||
default:
|
||||
r = ENOTTY;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
pci_other(message *m, int ipc_status)
|
||||
{
|
||||
switch(m->m_type)
|
||||
{
|
||||
case BUSC_PCI_INIT: do_init(m); break;
|
||||
case BUSC_PCI_FIRST_DEV: do_first_dev(m); break;
|
||||
case BUSC_PCI_NEXT_DEV: do_next_dev(m); break;
|
||||
case BUSC_PCI_FIND_DEV: do_find_dev(m); break;
|
||||
case BUSC_PCI_IDS: do_ids(m); break;
|
||||
case BUSC_PCI_RESERVE: do_reserve(m); break;
|
||||
case BUSC_PCI_ATTR_R8: do_attr_r8(m); break;
|
||||
case BUSC_PCI_ATTR_R16: do_attr_r16(m); break;
|
||||
case BUSC_PCI_ATTR_R32: do_attr_r32(m); break;
|
||||
case BUSC_PCI_ATTR_W8: do_attr_w8(m); break;
|
||||
case BUSC_PCI_ATTR_W16: do_attr_w16(m); break;
|
||||
case BUSC_PCI_ATTR_W32: do_attr_w32(m); break;
|
||||
case BUSC_PCI_RESCAN: do_rescan_bus(m); break;
|
||||
case BUSC_PCI_DEV_NAME_S: do_dev_name(m); break;
|
||||
case BUSC_PCI_SLOT_NAME_S: do_slot_name(m); break;
|
||||
case BUSC_PCI_SET_ACL: do_set_acl(m); break;
|
||||
case BUSC_PCI_DEL_ACL: do_del_acl(m); break;
|
||||
case BUSC_PCI_GET_BAR: do_get_bar(m); break;
|
||||
default:
|
||||
printf("PCI: unhandled message from %d, type %d\n",
|
||||
m->m_source, m->m_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct chardriver driver =
|
||||
{
|
||||
.cdr_open = pci_open,
|
||||
.cdr_close = pci_close,
|
||||
.cdr_ioctl = pci_ioctl,
|
||||
.cdr_other = pci_other,
|
||||
};
|
||||
|
||||
/*======================================================================*
|
||||
* SEF Callbacks *
|
||||
*======================================================================*/
|
||||
/* NOTE: sef_cb_init is in pci.c. */
|
||||
static void
|
||||
sef_local_startup(void)
|
||||
{
|
||||
/*
|
||||
* Register init callbacks. Use the same function for all event types
|
||||
*/
|
||||
sef_setcb_init_fresh(sef_cb_init);
|
||||
sef_setcb_init_lu(sef_cb_init);
|
||||
sef_setcb_init_restart(sef_cb_init);
|
||||
|
||||
/*
|
||||
* Register live update callbacks.
|
||||
*/
|
||||
|
||||
/* - Agree to update immediately when LU is requested in a valid
|
||||
* state. */
|
||||
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
|
||||
/* - Support live update starting from any standard state. */
|
||||
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
|
||||
|
||||
#if 0
|
||||
/* - Register a custom routine to save the state. */
|
||||
sef_setcb_lu_state_save(sef_cb_lu_state_save);
|
||||
#endif
|
||||
|
||||
/* Let SEF perform startup. */
|
||||
sef_startup();
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* main *
|
||||
*======================================================================*/
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int r;
|
||||
message m;
|
||||
int ipc_status;
|
||||
|
||||
/* SEF local startup. */
|
||||
/*
|
||||
* Perform initialization.
|
||||
*/
|
||||
sef_local_startup();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
r= driver_receive(ANY, &m, &ipc_status);
|
||||
if (r < 0)
|
||||
{
|
||||
printf("PCI: driver_receive failed: %d\n", r);
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_ipc_notify(ipc_status)) {
|
||||
printf("PCI: got notify from %d\n", m.m_source);
|
||||
|
||||
/* done, get a new message */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(m.m_type)
|
||||
{
|
||||
case BUSC_PCI_INIT: do_init(&m); break;
|
||||
case BUSC_PCI_FIRST_DEV: do_first_dev(&m); break;
|
||||
case BUSC_PCI_NEXT_DEV: do_next_dev(&m); break;
|
||||
case BUSC_PCI_FIND_DEV: do_find_dev(&m); break;
|
||||
case BUSC_PCI_IDS: do_ids(&m); break;
|
||||
case BUSC_PCI_RESERVE: do_reserve(&m); break;
|
||||
case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
|
||||
case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
|
||||
case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
|
||||
case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
|
||||
case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
|
||||
case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
|
||||
case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
|
||||
case BUSC_PCI_DEV_NAME_S: do_dev_name(&m); break;
|
||||
case BUSC_PCI_SLOT_NAME_S: do_slot_name(&m); break;
|
||||
case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
|
||||
case BUSC_PCI_DEL_ACL: do_del_acl(&m); break;
|
||||
case BUSC_PCI_GET_BAR: do_get_bar(&m); break;
|
||||
default:
|
||||
printf("PCI: got message from %d, type %d\n",
|
||||
m.m_source, m.m_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* Run the main loop.
|
||||
*/
|
||||
chardriver_task(&driver);
|
||||
return OK;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,11 @@ Configure devices on the PCI bus
|
|||
|
||||
Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
|
||||
*/
|
||||
|
||||
#include <minix/driver.h>
|
||||
|
||||
#include <minix/acpi.h>
|
||||
#include <minix/param.h>
|
||||
#include <minix/chardriver.h>
|
||||
#include <minix/driver.h>
|
||||
#include <minix/ds.h>
|
||||
#include <minix/param.h>
|
||||
#include <minix/rs.h>
|
||||
|
||||
#include <machine/pci.h>
|
||||
|
@ -2127,9 +2126,11 @@ visible(struct rs_pci *aclp, int devind)
|
|||
* sef_cb_init_fresh *
|
||||
*===========================================================================*/
|
||||
int
|
||||
sef_cb_init_fresh(int type, sef_init_info_t *info)
|
||||
sef_cb_init(int type, sef_init_info_t *info)
|
||||
{
|
||||
/* Initialize the pci driver. */
|
||||
/* Initialize the driver. */
|
||||
int do_announce_driver = -1;
|
||||
|
||||
long v;
|
||||
int i, r;
|
||||
struct rprocpub rprocpub[NR_BOOT_PROCS];
|
||||
|
@ -2165,7 +2166,26 @@ sef_cb_init_fresh(int type, sef_init_info_t *info)
|
|||
}
|
||||
}
|
||||
|
||||
return(OK);
|
||||
switch(type) {
|
||||
case SEF_INIT_FRESH:
|
||||
case SEF_INIT_RESTART:
|
||||
do_announce_driver = TRUE;
|
||||
break;
|
||||
case SEF_INIT_LU:
|
||||
do_announce_driver = FALSE;
|
||||
break;
|
||||
default:
|
||||
panic("Unknown type of restart");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Announce we are up when necessary. */
|
||||
if (TRUE == do_announce_driver) {
|
||||
chardriver_announce();
|
||||
}
|
||||
|
||||
/* Initialization completed successfully. */
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -2199,7 +2219,7 @@ map_service(struct rprocpub *rpub)
|
|||
pci_acl[i].inuse = 1;
|
||||
pci_acl[i].acl = rpub->pci_acl;
|
||||
|
||||
return(OK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -2219,13 +2239,12 @@ _pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (devind >= nr_pcidev)
|
||||
return 0;
|
||||
#if 0
|
||||
if (pcidev[devind].pd_inuse)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
*devindp= devind;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2240,10 +2259,6 @@ _pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp,
|
|||
|
||||
for (devind= 0; devind < nr_pcidev; devind++)
|
||||
{
|
||||
#if 0
|
||||
if (pcidev[devind].pd_inuse)
|
||||
continue;
|
||||
#endif
|
||||
if (!visible(aclp, devind))
|
||||
continue;
|
||||
break;
|
||||
|
@ -2266,10 +2281,6 @@ _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp)
|
|||
|
||||
for (devind= *devindp+1; devind < nr_pcidev; devind++)
|
||||
{
|
||||
#if 0
|
||||
if (pcidev[devind].pd_inuse)
|
||||
continue;
|
||||
#endif
|
||||
if (!visible(aclp, devind))
|
||||
continue;
|
||||
break;
|
||||
|
@ -2283,33 +2294,16 @@ _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp)
|
|||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* _pci_reserve *
|
||||
* _pci_grant_access *
|
||||
*===========================================================================*/
|
||||
int
|
||||
_pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
|
||||
_pci_grant_access(int devind, endpoint_t proc)
|
||||
{
|
||||
int i, r;
|
||||
int ilr;
|
||||
int i, ilr;
|
||||
int r = OK;
|
||||
struct io_range ior;
|
||||
struct minix_mem_range mr;
|
||||
|
||||
if (devind < 0 || devind >= nr_pcidev)
|
||||
{
|
||||
printf("pci_reserve_a: bad devind: %d\n", devind);
|
||||
return EINVAL;
|
||||
}
|
||||
if (!visible(aclp, devind))
|
||||
{
|
||||
printf("pci_reserve_a: %u is not allowed to reserve %d\n",
|
||||
proc, devind);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
|
||||
return EBUSY;
|
||||
pcidev[devind].pd_inuse= 1;
|
||||
pcidev[devind].pd_proc= proc;
|
||||
|
||||
for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
|
||||
{
|
||||
if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
|
||||
|
@ -2361,7 +2355,34 @@ _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
|
|||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* _pci_reserve *
|
||||
*===========================================================================*/
|
||||
int
|
||||
_pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
|
||||
{
|
||||
if (devind < 0 || devind >= nr_pcidev)
|
||||
{
|
||||
printf("pci_reserve_a: bad devind: %d\n", devind);
|
||||
return EINVAL;
|
||||
}
|
||||
if (!visible(aclp, devind))
|
||||
{
|
||||
printf("pci_reserve_a: %u is not allowed to reserve %d\n",
|
||||
proc, devind);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
|
||||
return EBUSY;
|
||||
|
||||
pcidev[devind].pd_inuse= 1;
|
||||
pcidev[devind].pd_proc= proc;
|
||||
|
||||
return _pci_grant_access(devind, proc);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
|
@ -4,12 +4,6 @@ pci.h
|
|||
Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
|
||||
*/
|
||||
|
||||
struct pci_intel_ctrl
|
||||
{
|
||||
u16_t vid;
|
||||
u16_t did;
|
||||
};
|
||||
|
||||
struct pci_isabridge
|
||||
{
|
||||
u16_t vid;
|
||||
|
@ -18,13 +12,6 @@ struct pci_isabridge
|
|||
int type;
|
||||
};
|
||||
|
||||
struct pci_pcibridge
|
||||
{
|
||||
u16_t vid;
|
||||
u16_t did;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct pci_acl
|
||||
{
|
||||
int inuse;
|
||||
|
@ -49,9 +36,10 @@ extern struct pci_isabridge pci_isabridge[];
|
|||
extern struct pci_acl pci_acl[NR_DRIVERS];
|
||||
|
||||
/* Function prototypes. */
|
||||
int sef_cb_init_fresh(int type, sef_init_info_t *info);
|
||||
int sef_cb_init(int type, sef_init_info_t *info);
|
||||
int map_service(struct rprocpub *rpub);
|
||||
|
||||
int _pci_grant_access(int devind, endpoint_t proc);
|
||||
int _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp);
|
||||
void _pci_release(endpoint_t proc);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ then if [ -e $ACPI -a -n "`sysenv acpi`" ]
|
|||
then
|
||||
/bin/service -c up $ACPI
|
||||
fi
|
||||
/bin/service -c up /service/pci
|
||||
/bin/service -c up /service/pci -dev /dev/pci
|
||||
|
||||
/bin/service -c up /service/input -dev /dev/kbdmux
|
||||
/bin/service -c up /service/pckbd
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <termios.h>
|
||||
#include <assert.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/vm.h>
|
||||
#include <sys/video.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/termios.h>
|
||||
|
@ -845,33 +844,8 @@ static int video_ioctl(devminor_t minor, unsigned long request,
|
|||
endpoint_t endpt, cp_grant_id_t grant, int flags,
|
||||
endpoint_t user_endpt, cdev_id_t id)
|
||||
{
|
||||
struct mapreqvm mapreqvm;
|
||||
int r, do_map;
|
||||
|
||||
switch (request) {
|
||||
case TIOCMAPMEM:
|
||||
case TIOCUNMAPMEM:
|
||||
do_map = (request == TIOCMAPMEM); /* else unmap */
|
||||
|
||||
if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &mapreqvm,
|
||||
sizeof(mapreqvm))) != OK)
|
||||
return r;
|
||||
|
||||
if (do_map) {
|
||||
mapreqvm.vaddr_ret = vm_map_phys(user_endpt,
|
||||
(void *) mapreqvm.phys_offset, mapreqvm.size);
|
||||
r = sys_safecopyto(endpt, grant, 0, (vir_bytes) &mapreqvm,
|
||||
sizeof(mapreqvm));
|
||||
} else {
|
||||
r = vm_unmap_phys(user_endpt, mapreqvm.vaddr, mapreqvm.size);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_video *
|
||||
|
|
|
@ -68,8 +68,9 @@
|
|||
/* 56-63 = /dev/vnd[0-7] (vnd) */
|
||||
#define INPUT_MAJOR 64 /* 64 = /dev/input (input) */
|
||||
#define USB_BASE_MAJOR 65 /* 65-133 = USB major range */
|
||||
#define PCI_MAJOR 134 /* 134 = /dev/pci (pci) */
|
||||
|
||||
#define NR_DEVICES 134 /* number of (major) devices */
|
||||
#define NR_DEVICES 135 /* number of (major) devices */
|
||||
|
||||
/* Minor device numbers for memory driver. */
|
||||
# define RAM_DEV_OLD 0 /* minor device for /dev/ram */
|
||||
|
|
|
@ -6,6 +6,6 @@ INCS= elf64.h elf_common.h elf_core.h elf_generic.h \
|
|||
ioc_block.h ioc_disk.h ioc_fb.h ioc_fbd.h ioc_file.h ioc_memory.h \
|
||||
ioc_net.h ioc_sound.h ioc_tape.h \
|
||||
kbdio.h \
|
||||
procfs.h statfs.h svrctl.h video.h vm.h
|
||||
procfs.h statfs.h svrctl.h video.h
|
||||
|
||||
.include <bsd.kinc.mk>
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef __SYS_VM_H__
|
||||
#define __SYS_VM_H__
|
||||
|
||||
/*
|
||||
sys/vm.h
|
||||
*/
|
||||
|
||||
/* used in ioctl to tty for mapvm map and unmap request. */
|
||||
struct mapreqvm
|
||||
{
|
||||
int flags; /* reserved, must be 0 */
|
||||
phys_bytes phys_offset;
|
||||
size_t size;
|
||||
int readonly;
|
||||
char reserved[36]; /* reserved, must be 0 */
|
||||
void *vaddr;
|
||||
void *vaddr_ret;
|
||||
};
|
||||
|
||||
#endif /* __SYS_VM_H__ */
|
|
@ -176,10 +176,6 @@ int do_privctl(struct proc * caller, message * m_ptr)
|
|||
if (RTS_ISSET(rp, RTS_NO_PRIV))
|
||||
return(EPERM);
|
||||
|
||||
/* Only system processes get I/O resources? */
|
||||
if (!(priv(rp)->s_flags & SYS_PROC))
|
||||
return EPERM;
|
||||
|
||||
#if 0 /* XXX -- do we need a call for this? */
|
||||
if (strcmp(rp->p_name, "fxp") == 0 ||
|
||||
strcmp(rp->p_name, "rtl8139") == 0)
|
||||
|
@ -217,10 +213,6 @@ int do_privctl(struct proc * caller, message * m_ptr)
|
|||
if (RTS_ISSET(rp, RTS_NO_PRIV))
|
||||
return(EPERM);
|
||||
|
||||
/* Only system processes get memory resources? */
|
||||
if (!(priv(rp)->s_flags & SYS_PROC))
|
||||
return EPERM;
|
||||
|
||||
/* Get the memory range */
|
||||
if((r=data_copy(caller->p_endpoint,
|
||||
m_ptr->m_lsys_krn_sys_privctl.arg_ptr, KERNEL,
|
||||
|
@ -252,10 +244,11 @@ int do_privctl(struct proc * caller, message * m_ptr)
|
|||
if (RTS_ISSET(rp, RTS_NO_PRIV))
|
||||
return(EPERM);
|
||||
|
||||
#if 0
|
||||
/* Only system processes get IRQs? */
|
||||
if (!(priv(rp)->s_flags & SYS_PROC))
|
||||
return EPERM;
|
||||
|
||||
#endif
|
||||
data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
|
||||
KERNEL, (vir_bytes) &irq, sizeof(irq));
|
||||
priv(rp)->s_flags |= CHECK_IRQ; /* Check IRQs */
|
||||
|
@ -289,8 +282,6 @@ int do_privctl(struct proc * caller, message * m_ptr)
|
|||
return EPERM;
|
||||
if(!(sp = priv(rp)))
|
||||
return EPERM;
|
||||
if (!(sp->s_flags & SYS_PROC))
|
||||
return EPERM;
|
||||
for(i = 0; i < sp->s_nr_mem_range; i++) {
|
||||
if(addr >= sp->s_mem_tab[i].mr_base &&
|
||||
limit <= sp->s_mem_tab[i].mr_limit)
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <machine/param.h>
|
||||
#include <machine/vm.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <sys/vm.h>
|
||||
|
||||
#include <lib.h>
|
||||
#include <time.h>
|
||||
|
|
|
@ -294,15 +294,13 @@ static int map_perm_check(endpoint_t caller, endpoint_t target,
|
|||
*/
|
||||
if(caller == TTY_PROC_NR)
|
||||
return OK;
|
||||
if(caller != target)
|
||||
return EPERM;
|
||||
if(caller == MEM_PROC_NR)
|
||||
return OK;
|
||||
|
||||
/* Anyone else needs explicit permission from the kernel (ultimately
|
||||
* set by PCI).
|
||||
*/
|
||||
r = sys_privquery_mem(caller, physaddr, len);
|
||||
r = sys_privquery_mem(target, physaddr, len);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -337,8 +335,8 @@ int do_map_phys(message *m)
|
|||
* help it if we can't map in lower than page granularity.
|
||||
*/
|
||||
if(map_perm_check(m->m_source, target, startaddr, len) != OK) {
|
||||
printf("VM: unauthorized mapping of 0x%lx by %d\n",
|
||||
startaddr, m->m_source);
|
||||
printf("VM: unauthorized mapping of 0x%lx by %d for %d\n",
|
||||
startaddr, m->m_source, target);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <sys/ioctl.h>
|
||||
#include <minix/partition.h>
|
||||
#include <sys/vm.h>
|
||||
#include <sys/mtio.h>
|
||||
|
||||
const char *
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
|
||||
#include "inc.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <minix/i2c.h>
|
||||
#include <dev/pci/pciio.h>
|
||||
|
||||
#include <minix/fb.h>
|
||||
#include <minix/i2c.h>
|
||||
#include <minix/keymap.h>
|
||||
#include <minix/sound.h>
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kbdio.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kbdio.h>
|
||||
#include <minix/keymap.h>
|
||||
#include <sys/vm.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
const char *
|
||||
char_ioctl_name(unsigned long req)
|
||||
|
@ -93,8 +95,15 @@ char_ioctl_name(unsigned long req)
|
|||
NAME(KIOCBELL);
|
||||
NAME(KIOCSLEDS);
|
||||
NAME(KIOCSMAP); /* not worth interpreting */
|
||||
NAME(TIOCMAPMEM);
|
||||
NAME(TIOCUNMAPMEM);
|
||||
NAME(PCI_IOC_CFGREAD);
|
||||
NAME(PCI_IOC_CFGWRITE);
|
||||
NAME(PCI_IOC_BDF_CFGREAD);
|
||||
NAME(PCI_IOC_BDF_CFGWRITE);
|
||||
NAME(PCI_IOC_BUSINFO);
|
||||
NAME(PCI_IOC_MAP);
|
||||
NAME(PCI_IOC_UNMAP);
|
||||
NAME(PCI_IOC_RESERVE);
|
||||
NAME(PCI_IOC_RELEASE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -267,7 +276,12 @@ char_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr,
|
|||
struct winsize *ws;
|
||||
struct kio_bell *bell;
|
||||
struct kio_leds *leds;
|
||||
struct mapreqvm *mapreq;
|
||||
struct pciio_cfgreg *pci_cfgreg;
|
||||
struct pciio_bdf_cfgreg *pci_bdf_cfgreg;
|
||||
struct pciio_businfo *pci_businfo;
|
||||
struct pciio_map *pci_iomap;
|
||||
struct pciio_acl *pci_acl;
|
||||
|
||||
|
||||
switch (req) {
|
||||
case MINIX_I2C_IOCTL_EXEC:
|
||||
|
@ -482,25 +496,93 @@ char_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr,
|
|||
leds->kl_bits);
|
||||
return IF_ALL;
|
||||
|
||||
case TIOCMAPMEM:
|
||||
if ((mapreq = (struct mapreqvm *)ptr) == NULL)
|
||||
return dir;
|
||||
case PCI_IOC_CFGREAD:
|
||||
if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL)
|
||||
return IF_IN;
|
||||
|
||||
/* This structure has more fields, but they're all unused.. */
|
||||
if (dir == IF_OUT) {
|
||||
put_value(proc, "phys_offset", "%"PRIu64,
|
||||
(uint64_t)mapreq->phys_offset); /* future compat */
|
||||
put_value(proc, "size", "%zu", mapreq->size);
|
||||
} else
|
||||
put_ptr(proc, "vaddr_ret", (vir_bytes)mapreq->vaddr);
|
||||
put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg);
|
||||
put_value(proc, "val", "%08x", pci_cfgreg->val);
|
||||
return IF_ALL;
|
||||
|
||||
case TIOCUNMAPMEM:
|
||||
if ((mapreq = (struct mapreqvm *)ptr) == NULL)
|
||||
case PCI_IOC_CFGWRITE:
|
||||
if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL)
|
||||
return IF_OUT;
|
||||
|
||||
put_ptr(proc, "vaddr", (vir_bytes)mapreq->vaddr);
|
||||
put_value(proc, "size", "%zu", mapreq->size);
|
||||
put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg);
|
||||
put_value(proc, "val", "%08x", pci_cfgreg->val);
|
||||
return IF_ALL;
|
||||
|
||||
case PCI_IOC_BDF_CFGREAD:
|
||||
if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL)
|
||||
return IF_IN;
|
||||
|
||||
put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus);
|
||||
put_value(proc, "device", "%u", pci_bdf_cfgreg->device);
|
||||
put_value(proc, "function", "%u", pci_bdf_cfgreg->function);
|
||||
put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg);
|
||||
put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val);
|
||||
return IF_ALL;
|
||||
|
||||
case PCI_IOC_BDF_CFGWRITE:
|
||||
if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL)
|
||||
return IF_OUT;
|
||||
|
||||
put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus);
|
||||
put_value(proc, "device", "%u", pci_bdf_cfgreg->device);
|
||||
put_value(proc, "function", "%u", pci_bdf_cfgreg->function);
|
||||
put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg);
|
||||
put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val);
|
||||
return IF_ALL;
|
||||
|
||||
case PCI_IOC_BUSINFO:
|
||||
if ((pci_businfo = (struct pciio_businfo *)ptr) == NULL)
|
||||
return IF_IN;
|
||||
|
||||
put_value(proc, "busno", "%u", pci_businfo->busno);
|
||||
put_value(proc, "maxdevs", "%u", pci_businfo->maxdevs);
|
||||
return IF_ALL;
|
||||
|
||||
case PCI_IOC_MAP:
|
||||
if ((pci_iomap = (struct pciio_map *)ptr) == NULL)
|
||||
return IF_OUT|IF_IN;
|
||||
|
||||
put_value(proc, "flags", "%x", pci_iomap->flags);
|
||||
put_value(proc, "phys_offset", "%08x", pci_iomap->phys_offset);
|
||||
put_value(proc, "size", "%zu", pci_iomap->size);
|
||||
put_value(proc, "readonly", "%x", pci_iomap->readonly);
|
||||
|
||||
if (IF_IN == dir)
|
||||
put_ptr(proc, "vaddr_ret", (vir_bytes)pci_iomap->vaddr_ret);
|
||||
|
||||
return IF_ALL;
|
||||
|
||||
case PCI_IOC_UNMAP:
|
||||
if ((pci_iomap = (struct pciio_map *)ptr) == NULL)
|
||||
return IF_OUT;
|
||||
|
||||
put_ptr(proc, "vaddr", (vir_bytes)pci_iomap->vaddr);
|
||||
|
||||
return IF_ALL;
|
||||
|
||||
case PCI_IOC_RESERVE:
|
||||
if ((pci_acl = (struct pciio_acl *)ptr) == NULL)
|
||||
return IF_OUT;
|
||||
|
||||
put_value(proc, "domain", "%u", pci_acl->domain);
|
||||
put_value(proc, "bus", "%u", pci_acl->bus);
|
||||
put_value(proc, "device", "%u", pci_acl->device);
|
||||
put_value(proc, "function", "%u", pci_acl->function);
|
||||
|
||||
return IF_ALL;
|
||||
case PCI_IOC_RELEASE:
|
||||
if ((pci_acl = (struct pciio_acl *)ptr) == NULL)
|
||||
return IF_OUT;
|
||||
|
||||
put_value(proc, "domain", "%u", pci_acl->domain);
|
||||
put_value(proc, "bus", "%u", pci_acl->bus);
|
||||
put_value(proc, "device", "%u", pci_acl->device);
|
||||
put_value(proc, "function", "%u", pci_acl->function);
|
||||
|
||||
return IF_ALL;
|
||||
|
||||
default:
|
||||
|
|
|
@ -93,4 +93,28 @@ struct pciio_businfo {
|
|||
|
||||
#define PCI_IOC_BUSINFO _IOR('P', 4, struct pciio_businfo)
|
||||
|
||||
#if defined(__minix)
|
||||
struct pciio_map {
|
||||
int flags; /* reserved, must be 0 */
|
||||
u_int phys_offset;
|
||||
size_t size;
|
||||
int readonly;
|
||||
char reserved[36]; /* reserved, must be 0 */
|
||||
void *vaddr;
|
||||
void *vaddr_ret;
|
||||
};
|
||||
|
||||
#define PCI_IOC_MAP _IOWR('P', 100, struct pciio_map)
|
||||
#define PCI_IOC_UNMAP _IOW('P', 101, struct pciio_map)
|
||||
|
||||
struct pciio_acl {
|
||||
u_int domain;
|
||||
u_int bus;
|
||||
u_int device;
|
||||
u_int function;
|
||||
};
|
||||
|
||||
#define PCI_IOC_RESERVE _IOW('P', 102, struct pciio_acl)
|
||||
#define PCI_IOC_RELEASE _IOW('P', 103, struct pciio_acl)
|
||||
#endif /* defined(__minix) */
|
||||
#endif /* _DEV_PCI_PCIIO_H_ */
|
||||
|
|
|
@ -174,9 +174,6 @@ typedef char linedn_t[TTLINEDNAMELEN];
|
|||
#define KIOCSLEDS _IOW('k', 2, struct kio_leds)
|
||||
#define KIOCSMAP _IOW('k', 3, keymap_t)
|
||||
|
||||
/* /dev/video ioctls. */
|
||||
#define TIOCMAPMEM _IOWR('v', 1, struct mapreqvm)
|
||||
#define TIOCUNMAPMEM _IOWR('v', 2, struct mapreqvm)
|
||||
#endif /* defined(__minix) */
|
||||
|
||||
#endif /* !_SYS_TTYCOM_H_ */
|
||||
|
|
Loading…
Reference in a new issue