diff --git a/minix/drivers/bus/pci/Makefile b/minix/drivers/bus/pci/Makefile index 50af8a580..d1e4cf882 100644 --- a/minix/drivers/bus/pci/Makefile +++ b/minix/drivers/bus/pci/Makefile @@ -5,4 +5,6 @@ SRCS= main.c pci.c pci_table.c DPADD+= ${LIBSYS} ${LIBTIMERS} LDADD+= -lsys -ltimers +WARNS?= 3 + .include diff --git a/minix/drivers/bus/pci/main.c b/minix/drivers/bus/pci/main.c index 1e76f02ce..780029021 100644 --- a/minix/drivers/bus/pci/main.c +++ b/minix/drivers/bus/pci/main.c @@ -1,96 +1,13 @@ -/* -main.c -*/ +#include +#include #include "pci.h" +int debug = 0; struct pci_acl pci_acl[NR_DRIVERS]; -static void do_init(message *mp); -static void do_first_dev(message *mp); -static void do_next_dev(message *mp); -static void do_find_dev(message *mp); -static void do_ids(message *mp); -static void do_dev_name_s(message *mp); -static void do_slot_name_s(message *mp); -static void do_set_acl(message *mp); -static void do_del_acl(message *mp); -static void do_reserve(message *mp); -static void do_attr_r8(message *mp); -static void do_attr_r16(message *mp); -static void do_attr_r32(message *mp); -static void do_attr_w8(message *mp); -static void do_attr_w16(message *mp); -static void do_attr_w32(message *mp); -static void do_get_bar(message *mp); -static void do_rescan_bus(message *mp); -static void reply(message *mp, int result); -static struct rs_pci *find_acl(int endpoint); - -extern int debug; - -/* SEF functions and variables. */ -static void sef_local_startup(void); - -int main(void) -{ - int r; - message m; - int ipc_status; - - /* SEF local startup. */ - 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_s(&m); break; - case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&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; -} - -/*===========================================================================* - * sef_local_startup * - *===========================================================================*/ -static void sef_local_startup() +static void +sef_local_startup() { /* Register init callbacks. */ sef_setcb_init_fresh(sef_cb_init_fresh); @@ -105,8 +22,37 @@ static void sef_local_startup() sef_startup(); } -static void do_init(mp) -message *mp; +static struct rs_pci * +find_acl(int endpoint) +{ + int i; + + /* Find ACL entry for caller */ + for (i= 0; im_source, &m); + if (r != 0) + printf("reply: unable to send to %d: %d\n", mp->m_source, r); +} + + +static void +do_init(message *mp) { int r; @@ -121,7 +67,8 @@ message *mp; mp->m_source, r); } -static void do_first_dev(message *mp) +static void +do_first_dev(message *mp) { int r, devind; u16_t vid, did; @@ -133,7 +80,7 @@ static void do_first_dev(message *mp) printf("PCI: do_first_dev: no acl for caller %d\n", mp->m_source); - r= pci_first_dev_a(aclp, &devind, &vid, &did); + r= _pci_first_dev(aclp, &devind, &vid, &did); if (r == 1) { mp->m1_i1= devind; @@ -149,7 +96,8 @@ static void do_first_dev(message *mp) } } -static void do_next_dev(message *mp) +static void +do_next_dev(message *mp) { int r, devind; u16_t vid, did; @@ -158,7 +106,7 @@ static void do_next_dev(message *mp) devind= mp->m1_i1; aclp= find_acl(mp->m_source); - r= pci_next_dev_a(aclp, &devind, &vid, &did); + r= _pci_next_dev(aclp, &devind, &vid, &did); if (r == 1) { mp->m1_i1= devind; @@ -174,8 +122,8 @@ static void do_next_dev(message *mp) } } -static void do_find_dev(mp) -message *mp; +static void +do_find_dev(message *mp) { int r, devind; u8_t bus, dev, func; @@ -184,7 +132,7 @@ message *mp; dev= mp->m1_i2; func= mp->m1_i3; - r= pci_find_dev(bus, dev, func, &devind); + r= _pci_find_dev(bus, dev, func, &devind); if (r == 1) mp->m1_i1= devind; mp->m_type= r; @@ -196,15 +144,15 @@ message *mp; } } -static void do_ids(mp) -message *mp; +static void +do_ids(message *mp) { int r, devind; u16_t vid, did; devind= mp->m1_i1; - r= pci_ids_s(devind, &vid, &did); + r= _pci_ids(devind, &vid, &did); if (r != OK) { printf("pci:do_ids: failed for devind %d: %d\n", @@ -222,20 +170,20 @@ message *mp; } } -static void do_dev_name_s(mp) -message *mp; +static void +do_dev_name(message *mp) { int r, name_len, len; u16_t vid, did; cp_grant_id_t name_gid; - char *name; + const char *name; vid= mp->m7_i1; did= mp->m7_i2; name_len= mp->m7_i3; name_gid= mp->m7_i4; - name= pci_dev_name(vid, did); + name= _pci_dev_name(vid, did); if (name == NULL) { /* No name */ @@ -259,8 +207,8 @@ message *mp; } } -static void do_slot_name_s(mp) -message *mp; +static void +do_slot_name(message *mp) { int r, devind, name_len, len; cp_grant_id_t gid; @@ -270,7 +218,7 @@ message *mp; name_len= mp->m1_i2; gid= mp->m1_i3; - r= pci_slot_name_s(devind, &name); + r= _pci_slot_name(devind, &name); if (r != OK) { printf("pci:do_slot_name_s: failed for devind %d: %d\n", @@ -295,8 +243,8 @@ message *mp; } } -static void do_set_acl(mp) -message *mp; +static void +do_set_acl(message *mp) { int i, r, gid; @@ -338,7 +286,8 @@ message *mp; reply(mp, OK); } -static void do_del_acl(message *mp) +static void +do_del_acl(message *mp) { int i, proc_nr; @@ -373,12 +322,13 @@ static void do_del_acl(message *mp) #endif /* Also release all devices held by this process */ - pci_release(proc_nr); + _pci_release(proc_nr); reply(mp, OK); } -static void do_reserve(message *mp) +static void +do_reserve(message *mp) { struct rs_pci *aclp; int r, devind; @@ -387,7 +337,7 @@ static void do_reserve(message *mp) aclp= find_acl(mp->m_source); - mp->m_type= pci_reserve_a(devind, mp->m_source, aclp); + mp->m_type= _pci_reserve(devind, mp->m_source, aclp); r= ipc_send(mp->m_source, mp); if (r != 0) { @@ -396,8 +346,8 @@ static void do_reserve(message *mp) } } -static void do_attr_r8(mp) -message *mp; +static void +do_attr_r8(message *mp) { int r, devind, port; u8_t v; @@ -405,11 +355,11 @@ message *mp; devind= mp->m2_i1; port= mp->m2_i2; - r= pci_attr_r8_s(devind, port, &v); + r= _pci_attr_r8(devind, port, &v); if (r != OK) { printf( - "pci:do_attr_r8: pci_attr_r8_s(%d, %d, ...) failed: %d\n", + "pci:do_attr_r8: pci_attr_r8(%d, %d, ...) failed: %d\n", devind, port, r); } mp->m2_l1= v; @@ -422,16 +372,22 @@ message *mp; } } -static void do_attr_r16(mp) -message *mp; +static void +do_attr_r16(message *mp) { int r, devind, port; - u32_t v; + u16_t v; devind= mp->m2_i1; port= mp->m2_i2; - v= pci_attr_r16(devind, port); + r= _pci_attr_r16(devind, port, &v); + if (r != OK) + { + printf( + "pci:do_attr_r16: pci_attr_r16(%d, %d, ...) failed: %d\n", + devind, port, r); + } mp->m2_l1= v; mp->m_type= OK; r= ipc_send(mp->m_source, mp); @@ -442,8 +398,8 @@ message *mp; } } -static void do_attr_r32(mp) -message *mp; +static void +do_attr_r32(message *mp) { int r, devind, port; u32_t v; @@ -451,11 +407,11 @@ message *mp; devind= mp->m2_i1; port= mp->m2_i2; - r= pci_attr_r32_s(devind, port, &v); + r= _pci_attr_r32(devind, port, &v); if (r != OK) { printf( - "pci:do_attr_r32: pci_attr_r32_s(%d, %d, ...) failed: %d\n", + "pci:do_attr_r32: pci_attr_r32(%d, %d, ...) failed: %d\n", devind, port, r); } mp->m2_l1= v; @@ -468,8 +424,8 @@ message *mp; } } -static void do_attr_w8(mp) -message *mp; +static void +do_attr_w8(message *mp) { int r, devind, port; u8_t v; @@ -478,7 +434,7 @@ message *mp; port= mp->m2_i2; v= mp->m2_l1; - pci_attr_w8(devind, port, v); + _pci_attr_w8(devind, port, v); mp->m_type= OK; r= ipc_send(mp->m_source, mp); if (r != 0) @@ -488,8 +444,8 @@ message *mp; } } -static void do_attr_w16(mp) -message *mp; +static void +do_attr_w16(message *mp) { int r, devind, port; u16_t v; @@ -498,7 +454,7 @@ message *mp; port= mp->m2_i2; v= mp->m2_l1; - pci_attr_w16(devind, port, v); + _pci_attr_w16(devind, port, v); mp->m_type= OK; r= ipc_send(mp->m_source, mp); if (r != 0) @@ -508,8 +464,8 @@ message *mp; } } -static void do_attr_w32(mp) -message *mp; +static void +do_attr_w32(message *mp) { int r, devind, port; u32_t v; @@ -518,7 +474,7 @@ message *mp; port= mp->m2_i2; v= mp->m2_l1; - pci_attr_w32(devind, port, v); + _pci_attr_w32(devind, port, v); mp->m_type= OK; r= ipc_send(mp->m_source, mp); if (r != 0) @@ -528,8 +484,8 @@ message *mp; } } -static void do_get_bar(mp) -message *mp; +static void +do_get_bar(message *mp) { int r, devind, port, ioflag; u32_t base, size; @@ -537,7 +493,7 @@ message *mp; devind= mp->m_lsys_pci_busc_get_bar.devind; port= mp->m_lsys_pci_busc_get_bar.port; - mp->m_type= pci_get_bar_s(devind, port, &base, &size, &ioflag); + mp->m_type= _pci_get_bar(devind, port, &base, &size, &ioflag); if (mp->m_type == OK) { @@ -554,14 +510,14 @@ message *mp; } } -static void do_rescan_bus(mp) -message *mp; +static void +do_rescan_bus(message *mp) { int r, busnr; busnr= mp->m2_i1; - pci_rescan_bus(busnr); + _pci_rescan_bus(busnr); mp->m_type= OK; r= ipc_send(mp->m_source, mp); if (r != 0) @@ -571,33 +527,58 @@ message *mp; } } - -static void reply(mp, result) -message *mp; -int result; +int +main(void) { int r; message m; + int ipc_status; - m.m_type= result; - r= ipc_send(mp->m_source, &m); - if (r != 0) - printf("reply: unable to send to %d: %d\n", mp->m_source, r); -} + /* SEF local startup. */ + sef_local_startup(); - -static struct rs_pci *find_acl(endpoint) -int endpoint; -{ - int i; - - /* Find ACL entry for caller */ - for (i= 0; i */ -#include -#include -#include -#include -#include -#include -#include -#include +#include -#include "pci.h" +#include +#include +#include +#include + +#include #include #include #include #include -#if __minix_vmd -#include "config.h" -#endif - -#if !__minix_vmd -#define irq_mode_pci(irq) ((void)0) -#endif +#include #include #include -#include -#include + +#include "pci.h" + +#define irq_mode_pci(irq) ((void)0) #define PBT_INTEL_HOST 1 #define PBT_PCIBRIDGE 2 @@ -39,7 +33,7 @@ Created: Jan 2000 by Philip Homburg #define BAM_NR 6 /* Number of base-address registers */ -int debug= 0; +struct pci_acl pci_acl[NR_DRIVERS]; static struct pcibus { @@ -88,503 +82,235 @@ static struct pcidev int pd_bar_nr; } pcidev[NR_PCIDEV]; -EXTERN struct pci_acl pci_acl[NR_DRIVERS]; - /* pb_flags */ #define PBF_IO 1 /* I/O else memory */ #define PBF_INCOMPLETE 2 /* not allocated */ static int nr_pcidev= 0; -static void pci_intel_init(void); -static void probe_bus(int busind); -static int is_duplicate(u8_t busnr, u8_t dev, u8_t func); -static void record_irq(int devind); -static void record_bars_normal(int devind); -static void record_bars_bridge(int devind); -static void record_bars_cardbus(int devind); -static void record_bars(int devind, int last_reg); -static int record_bar(int devind, int bar_nr, int last); -static void complete_bridges(void); -static void complete_bars(void); -static void update_bridge4dev_io(int devind, u32_t io_base, u32_t - io_size); -static int get_freebus(void); -static int do_isabridge(int busind); -static void do_pcibridge(int busind); -static int get_busind(int busnr); -static int do_piix(int devind); -static int do_amd_isabr(int devind); -static int do_sis_isabr(int devind); -static int do_via_isabr(int devind); -#if 0 -static void report_vga(int devind); -#endif -static char *pci_vid_name(u16_t vid); -static char *pci_baseclass_name(u8_t baseclass); -static char *pci_subclass_name(u8_t baseclass, u8_t subclass, u8_t - infclass); -static void ntostr(unsigned n, char **str, const char *end); - -static u8_t pci_attr_r8_u(int devind, int port); -static u32_t pci_attr_r32_u(int devind, int port); - -static u16_t pci_attr_rsts(int devind); -static void pci_attr_wsts(int devind, u16_t value); -static u16_t pcibr_std_rsts(int busind); -static void pcibr_std_wsts(int busind, u16_t value); -static u16_t pcibr_cb_rsts(int busind); -static void pcibr_cb_wsts(int busind, u16_t value); -static u16_t pcibr_via_rsts(int busind); -static void pcibr_via_wsts(int busind, u16_t value); -static u8_t pcii_rreg8(int busind, int devind, int port); -static u16_t pcii_rreg16(int busind, int devind, int port); -static u32_t pcii_rreg32(int busind, int devind, int port); -static void pcii_wreg8(int busind, int devind, int port, u8_t value); -static void pcii_wreg16(int busind, int devind, int port, u16_t value); -static void pcii_wreg32(int busind, int devind, int port, u32_t value); -static u16_t pcii_rsts(int busind); -static void pcii_wsts(int busind, u16_t value); -static void print_capabilities(int devind); -static int visible(struct rs_pci *aclp, int devind); -static void print_hyper_cap(int devind, u8_t capptr); - static struct machine machine; static endpoint_t acpi_ep; -/*===========================================================================* - * sef_cb_init_fresh * - *===========================================================================*/ -int sef_cb_init_fresh(int type, sef_init_info_t *info) -{ -/* Initialize the pci driver. */ - long v; - int i, r; - struct rprocpub rprocpub[NR_BOOT_PROCS]; - - v= 0; - env_parse("pci_debug", "d", 0, &v, 0, 1); - debug= v; - - if (sys_getmachine(&machine)) { - printf("PCI: no machine\n"); - return ENODEV; - } - if (machine.apic_enabled && - ds_retrieve_label_endpt("acpi", &acpi_ep) != OK) { - panic("PCI: Cannot use APIC mode without ACPI!\n"); - } - - /* Only Intel (compatible) PCI controllers are supported at the - * moment. - */ - pci_intel_init(); - - /* Map all the services in the boot image. */ - if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, - (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) { - panic("sys_safecopyfrom failed: %d", r); - } - for(i=0;i < NR_BOOT_PROCS;i++) { - if(rprocpub[i].in_use) { - if((r = map_service(&rprocpub[i])) != OK) { - panic("unable to map service: %d", r); - } - } - } - - return(OK); -} - -/*===========================================================================* - * map_service * - *===========================================================================*/ -int map_service(rpub) -struct rprocpub *rpub; -{ -/* Map a new service by registering a new acl entry if required. */ - int i; - - /* Stop right now if no pci device or class is found. */ - if(rpub->pci_acl.rsp_nr_device == 0 - && rpub->pci_acl.rsp_nr_class == 0) { - return(OK); - } - - /* Find a free acl slot. */ - for (i= 0; i= NR_DRIVERS) - { - printf("PCI: map_service: table is full\n"); - return ENOMEM; - } - - /* Initialize acl slot. */ - pci_acl[i].inuse = 1; - pci_acl[i].acl = rpub->pci_acl; - - return(OK); -} - /*===========================================================================* * helper functions for I/O * *===========================================================================*/ -unsigned pci_inb(u16_t port) { +static unsigned +pci_inb(u16_t port) { u32_t value; int s; if ((s=sys_inb(port, &value)) !=OK) printf("PCI: warning, sys_inb failed: %d\n", s); return value; } -unsigned pci_inw(u16_t port) { + +static unsigned +pci_inw(u16_t port) { u32_t value; int s; if ((s=sys_inw(port, &value)) !=OK) printf("PCI: warning, sys_inw failed: %d\n", s); return value; } -unsigned pci_inl(u16_t port) { + +static unsigned +pci_inl(u16_t port) { u32_t value; int s; if ((s=sys_inl(port, &value)) !=OK) printf("PCI: warning, sys_inl failed: %d\n", s); return value; } -void pci_outb(u16_t port, u8_t value) { + +static void +pci_outb(u16_t port, u8_t value) { int s; if ((s=sys_outb(port, value)) !=OK) printf("PCI: warning, sys_outb failed: %d\n", s); } -void pci_outw(u16_t port, u16_t value) { + +static void +pci_outw(u16_t port, u16_t value) { int s; if ((s=sys_outw(port, value)) !=OK) printf("PCI: warning, sys_outw failed: %d\n", s); } -void pci_outl(u16_t port, u32_t value) { + +static void +pci_outl(u16_t port, u32_t value) { int s; if ((s=sys_outl(port, value)) !=OK) printf("PCI: warning, sys_outl failed: %d\n", s); } -/*===========================================================================* - * pci_find_dev * - *===========================================================================*/ -int pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp) +static u8_t +pcii_rreg8(int busind, int devind, int port) { - int devind; + u8_t v; + int s; - for (devind= 0; devind < nr_pcidev; devind++) + v= PCII_RREG8_(pcibus[busind].pb_busnr, + pcidev[devind].pd_dev, pcidev[devind].pd_func, + port); + if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) + printf("PCI: warning, sys_outl failed: %d\n", s); +#if 0 + printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n", + busind, devind, port, + pcibus[busind].pb_bus, pcidev[devind].pd_dev, + pcidev[devind].pd_func, v); +#endif + return v; +} + +static u16_t +pcii_rreg16(int busind, int devind, int port) +{ + u16_t v; + int s; + + v= PCII_RREG16_(pcibus[busind].pb_busnr, + pcidev[devind].pd_dev, pcidev[devind].pd_func, + port); + if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) + printf("PCI: warning, sys_outl failed: %d\n", s); +#if 0 + printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n", + busind, devind, port, + pcibus[busind].pb_bus, pcidev[devind].pd_dev, + pcidev[devind].pd_func, v); +#endif + return v; +} + +static u32_t +pcii_rreg32(int busind, int devind, int port) +{ + u32_t v; + int s; + + v= PCII_RREG32_(pcibus[busind].pb_busnr, + pcidev[devind].pd_dev, pcidev[devind].pd_func, + port); + if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) + printf("PCI: warning, sys_outl failed: %d\n", s); +#if 0 + printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n", + busind, devind, port, + pcibus[busind].pb_bus, pcidev[devind].pd_dev, + pcidev[devind].pd_func, v); +#endif + return v; +} + +static void +pcii_wreg8(int busind, int devind, int port, u8_t value) +{ + int s; +#if 0 + printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n", + busind, devind, port, value, + pcibus[busind].pb_bus, pcidev[devind].pd_dev, + pcidev[devind].pd_func); +#endif + PCII_WREG8_(pcibus[busind].pb_busnr, + pcidev[devind].pd_dev, pcidev[devind].pd_func, + port, value); + if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) + printf("PCI: warning, sys_outl failed: %d\n", s); +} + +static void +pcii_wreg16(int busind, int devind, int port, u16_t value) +{ + int s; +#if 0 + printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n", + busind, devind, port, value, + pcibus[busind].pb_bus, pcidev[devind].pd_dev, + pcidev[devind].pd_func); +#endif + PCII_WREG16_(pcibus[busind].pb_busnr, + pcidev[devind].pd_dev, pcidev[devind].pd_func, + port, value); + if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) + printf("PCI: warning, sys_outl failed: %d\n", s); +} + +static void +pcii_wreg32(int busind, int devind, int port, u32_t value) +{ + int s; +#if 0 + printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n", + busind, devind, port, value, + pcibus[busind].pb_busnr, pcidev[devind].pd_dev, + pcidev[devind].pd_func); +#endif + PCII_WREG32_(pcibus[busind].pb_busnr, + pcidev[devind].pd_dev, pcidev[devind].pd_func, + port, value); + if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) + printf("PCI: warning, sys_outl failed: %d\n",s); +} + +/*===========================================================================* + * ntostr * + *===========================================================================*/ +static void +ntostr(unsigned int n, char **str, const char *end) +{ + char tmpstr[20]; + int i; + + if (n == 0) { - if (pcidev[devind].pd_busnr == bus && - pcidev[devind].pd_dev == dev && - pcidev[devind].pd_func == func) + tmpstr[0]= '0'; + i= 1; + } + else + { + for (i= 0; n; i++) + { + tmpstr[i]= '0' + (n%10); + n /= 10; + } + } + for (; i>0; i--) + { + if (*str == end) { break; } + **str= tmpstr[i-1]; + (*str)++; } - if (devind >= nr_pcidev) - return 0; -#if 0 - if (pcidev[devind].pd_inuse) - return 0; -#endif - *devindp= devind; - return 1; + if (*str == end) + (*str)[-1]= '\0'; + else + **str= '\0'; } /*===========================================================================* - * pci_first_dev_a * + * get_busind * *===========================================================================*/ -int pci_first_dev_a( - struct rs_pci *aclp, - int *devindp, - u16_t *vidp, - u16_t *didp -) -{ - int devind; - - for (devind= 0; devind < nr_pcidev; devind++) - { -#if 0 - if (pcidev[devind].pd_inuse) - continue; -#endif - if (!visible(aclp, devind)) - continue; - break; - } - if (devind >= nr_pcidev) - return 0; - *devindp= devind; - *vidp= pcidev[devind].pd_vid; - *didp= pcidev[devind].pd_did; - return 1; -} - -/*===========================================================================* - * pci_next_dev * - *===========================================================================*/ -int pci_next_dev_a( - struct rs_pci *aclp, - int *devindp, - u16_t *vidp, - u16_t *didp -) -{ - int devind; - - for (devind= *devindp+1; devind < nr_pcidev; devind++) - { -#if 0 - if (pcidev[devind].pd_inuse) - continue; -#endif - if (!visible(aclp, devind)) - continue; - break; - } - if (devind >= nr_pcidev) - return 0; - *devindp= devind; - *vidp= pcidev[devind].pd_vid; - *didp= pcidev[devind].pd_did; - return 1; -} - -/*===========================================================================* - * pci_reserve_a * - *===========================================================================*/ -int pci_reserve_a(devind, proc, aclp) -int devind; -endpoint_t proc; -struct rs_pci *aclp; -{ - int i, r; - int ilr; - 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= nr_pcidev) - return EINVAL; - - *vidp= pcidev[devind].pd_vid; - *didp= pcidev[devind].pd_did; - return OK; -} - -/*===========================================================================* - * pci_rescan_bus * - *===========================================================================*/ -void pci_rescan_bus(u8_t busnr) -{ - int busind; - - busind= get_busind(busnr); - probe_bus(busind); - - /* Allocate bus numbers for uninitialized bridges */ - complete_bridges(); - - /* Allocate I/O and memory resources for uninitialized devices */ - complete_bars(); -} - -/*===========================================================================* - * pci_slot_name_s * - *===========================================================================*/ -int pci_slot_name_s(devind, cpp) -int devind; -char **cpp; -{ - static char label[]= "ddd.ddd.ddd"; - char *end; - char *p; - - if (devind < 0 || devind >= nr_pcidev) - return EINVAL; - - p= label; - end= label+sizeof(label); - - ntostr(pcidev[devind].pd_busnr, &p, end); - *p++= '.'; - - ntostr(pcidev[devind].pd_dev, &p, end); - *p++= '.'; - - ntostr(pcidev[devind].pd_func, &p, end); - - *cpp= label; - return OK; -} - -/*===========================================================================* - * pci_dev_name * - *===========================================================================*/ -char *pci_dev_name(u16_t vid, u16_t did) -{ - int i; - - for (i= 0; pci_device_table[i].name; i++) - { - if (pci_device_table[i].vid == vid && - pci_device_table[i].did == did) - { - return pci_device_table[i].name; - } - } - return NULL; -} - -/*===========================================================================* - * pci_get_bar_s * - *===========================================================================*/ -int pci_get_bar_s(int devind, int port, u32_t *base, u32_t *size, - int *ioflag) -{ - int i, reg; - - if (devind < 0 || devind >= nr_pcidev) - return EINVAL; - - for (i= 0; i < pcidev[devind].pd_bar_nr; i++) - { - reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr; - - if (reg == port) - { - if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE) - return EINVAL; - - *base= pcidev[devind].pd_bar[i].pb_base; - *size= pcidev[devind].pd_bar[i].pb_size; - *ioflag= - !!(pcidev[devind].pd_bar[i].pb_flags & PBF_IO); - return OK; - } - } - return EINVAL; -} - -/*===========================================================================* - * pci_attr_r8_s * - *===========================================================================*/ -int pci_attr_r8_s(int devind, int port, u8_t *vp) -{ - if (devind < 0 || devind >= nr_pcidev) - return EINVAL; - if (port < 0 || port > 255) - return EINVAL; - - *vp= pci_attr_r8_u(devind, port); - return OK; -} - -/*===========================================================================* - * pci_attr_r8_u * - *===========================================================================*/ -static u8_t pci_attr_r8_u(devind, port) -int devind; -int port; +static u8_t +__pci_attr_r8(int devind, int port) { int busnr, busind; @@ -593,12 +319,8 @@ int port; return pcibus[busind].pb_rreg8(busind, devind, port); } -/*===========================================================================* - * pci_attr_r16 * - *===========================================================================*/ -u16_t pci_attr_r16(devind, port) -int devind; -int port; +static u16_t +__pci_attr_r16(int devind, int port) { int busnr, busind; @@ -607,26 +329,8 @@ int port; return pcibus[busind].pb_rreg16(busind, devind, port); } -/*===========================================================================* - * pci_attr_r32_s * - *===========================================================================*/ -int pci_attr_r32_s(int devind, int port, u32_t *vp) -{ - if (devind < 0 || devind >= nr_pcidev) - return EINVAL; - if (port < 0 || port > 256-4) - return EINVAL; - - *vp= pci_attr_r32_u(devind, port); - return OK; -} - -/*===========================================================================* - * pci_attr_r32_u * - *===========================================================================*/ -static u32_t pci_attr_r32_u(devind, port) -int devind; -int port; +static u32_t +__pci_attr_r32(int devind, int port) { int busnr, busind; @@ -635,10 +339,8 @@ int port; return pcibus[busind].pb_rreg32(busind, devind, port); } -/*===========================================================================* - * pci_attr_w8 * - *===========================================================================*/ -void pci_attr_w8(int devind, int port, u8_t value) +static void +__pci_attr_w8(int devind, int port, u8_t value) { int busnr, busind; @@ -647,10 +349,8 @@ void pci_attr_w8(int devind, int port, u8_t value) pcibus[busind].pb_wreg8(busind, devind, port, value); } -/*===========================================================================* - * pci_attr_w16 * - *===========================================================================*/ -void pci_attr_w16(int devind, int port, u16_t value) +static void +__pci_attr_w16(int devind, int port, u16_t value) { int busnr, busind; @@ -659,10 +359,8 @@ void pci_attr_w16(int devind, int port, u16_t value) pcibus[busind].pb_wreg16(busind, devind, port, value); } -/*===========================================================================* - * pci_attr_w32 * - *===========================================================================*/ -void pci_attr_w32(int devind, int port, u32_t value) +static void +__pci_attr_w32(int devind, int port, u32_t value) { int busnr, busind; @@ -672,270 +370,51 @@ void pci_attr_w32(int devind, int port, u32_t value) } /*===========================================================================* - * pci_intel_init * + * helpers * *===========================================================================*/ -static void pci_intel_init() +static u16_t +pci_attr_rsts(int devind) { - /* Try to detect a know PCI controller. Read the Vendor ID and - * the Device ID for function 0 of device 0. - * Two times the value 0xffff suggests a system without a (compatible) - * PCI controller. - */ - u32_t bus, dev, func; - u16_t vid, did; - int s, i, r, busind, busnr; - char *dstr; + int busnr, busind; - bus= 0; - dev= 0; - func= 0; + busnr= pcidev[devind].pd_busnr; + busind= get_busind(busnr); + return pcibus[busind].pb_rsts(busind); +} - vid= PCII_RREG16_(bus, dev, func, PCI_VID); - did= PCII_RREG16_(bus, dev, func, PCI_DID); +static void +pci_attr_wsts(int devind, u16_t value) +{ + int busnr, busind; + + busnr= pcidev[devind].pd_busnr; + busind= get_busind(busnr); + pcibus[busind].pb_wsts(busind, value); +} + +static u16_t +pcii_rsts(int busind) +{ + u16_t v; + int s; + + v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR); if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) printf("PCI: warning, sys_outl failed: %d\n", s); - -#if 0 - if (vid == 0xffff && did == 0xffff) - return; /* Nothing here */ - - for (i= 0; pci_intel_ctrl[i].vid; i++) - { - if (pci_intel_ctrl[i].vid == vid && - pci_intel_ctrl[i].did == did) - { - break; - } - } - - if (!pci_intel_ctrl[i].vid) - { - printf("pci_intel_init (warning): unknown PCI-controller:\n" - "\tvendor %04X (%s), device %04X\n", - vid, pci_vid_name(vid), did); - } -#endif - - if (nr_pcibus >= NR_PCIBUS) - panic("too many PCI busses: %d", nr_pcibus); - busind= nr_pcibus; - nr_pcibus++; - pcibus[busind].pb_type= PBT_INTEL_HOST; - pcibus[busind].pb_needinit= 0; - pcibus[busind].pb_isabridge_dev= -1; - pcibus[busind].pb_isabridge_type= 0; - pcibus[busind].pb_devind= -1; - pcibus[busind].pb_busnr= 0; - pcibus[busind].pb_rreg8= pcii_rreg8; - pcibus[busind].pb_rreg16= pcii_rreg16; - pcibus[busind].pb_rreg32= pcii_rreg32; - pcibus[busind].pb_wreg8= pcii_wreg8; - pcibus[busind].pb_wreg16= pcii_wreg16; - pcibus[busind].pb_wreg32= pcii_wreg32; - pcibus[busind].pb_rsts= pcii_rsts; - pcibus[busind].pb_wsts= pcii_wsts; - - dstr= pci_dev_name(vid, did); - if (!dstr) - dstr= "unknown device"; - if (debug) - { - printf("pci_intel_init: %s (%04X:%04X)\n", - dstr, vid, did); - } - - probe_bus(busind); - - r= do_isabridge(busind); - if (r != OK) - { - busnr= pcibus[busind].pb_busnr; - - /* Disable all devices for this bus */ - for (i= 0; i= NR_PCIDEV) - panic("too many PCI devices: %d", nr_pcidev); - devind= nr_pcidev; - - busnr= pcibus[busind].pb_busnr; - for (dev= 0; dev<32; dev++) - { - - for (func= 0; func < 8; func++) - { - pcidev[devind].pd_busnr= busnr; - pcidev[devind].pd_dev= dev; - pcidev[devind].pd_func= func; - - pci_attr_wsts(devind, - PSR_SSE|PSR_RMAS|PSR_RTAS); - vid= pci_attr_r16(devind, PCI_VID); - did= pci_attr_r16(devind, PCI_DID); - headt= pci_attr_r8_u(devind, PCI_HEADT); - sts= pci_attr_rsts(devind); - -#if 0 - printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n", - vid, did, headt, sts); -#endif - - if (vid == NO_VID && did == NO_VID) - { - if (func == 0) - break; /* Nothing here */ - - /* Scan all functions of a multifunction - * device. - */ - continue; - } - - if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS)) - { - static int warned = 0; - - if(!warned) { - printf( - "PCI: ignoring bad value 0x%x in sts for QEMU\n", - sts & (PSR_SSE|PSR_RMAS|PSR_RTAS)); - warned = 1; - } - } - - sub_vid= pci_attr_r16(devind, PCI_SUBVID); - sub_did= pci_attr_r16(devind, PCI_SUBDID); - - dstr= pci_dev_name(vid, did); - if (debug) - { - if (dstr) - { - printf("%d.%lu.%lu: %s (%04X:%04X)\n", - busnr, (unsigned long)dev, - (unsigned long)func, dstr, - vid, did); - } - else - { - printf( - "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n", - busnr, (unsigned long)dev, - (unsigned long)func, vid, - pci_vid_name(vid), did); - } - printf("Device index: %d\n", devind); - printf("Subsystem: Vid 0x%x, did 0x%x\n", - sub_vid, sub_did); - } - - baseclass= pci_attr_r8_u(devind, PCI_BCR); - subclass= pci_attr_r8_u(devind, PCI_SCR); - infclass= pci_attr_r8_u(devind, PCI_PIFR); - s= pci_subclass_name(baseclass, subclass, infclass); - if (!s) - s= pci_baseclass_name(baseclass); - { - if (!s) - s= "(unknown class)"; - } - if (debug) - { - printf("\tclass %s (%X/%X/%X)\n", s, - baseclass, subclass, infclass); - } - - if (is_duplicate(busnr, dev, func)) - { - printf("\tduplicate!\n"); - if (func == 0 && !(headt & PHT_MULTIFUNC)) - break; - continue; - } - - devind= nr_pcidev; - nr_pcidev++; - pcidev[devind].pd_baseclass= baseclass; - pcidev[devind].pd_subclass= subclass; - pcidev[devind].pd_infclass= infclass; - pcidev[devind].pd_vid= vid; - pcidev[devind].pd_did= did; - pcidev[devind].pd_sub_vid= sub_vid; - pcidev[devind].pd_sub_did= sub_did; - pcidev[devind].pd_inuse= 0; - pcidev[devind].pd_bar_nr= 0; - record_irq(devind); - switch(headt & PHT_MASK) - { - case PHT_NORMAL: - record_bars_normal(devind); - break; - case PHT_BRIDGE: - record_bars_bridge(devind); - break; - case PHT_CARDBUS: - record_bars_cardbus(devind); - break; - default: - printf("\t%d.%d.%d: unknown header type %d\n", - busind, dev, func, - headt & PHT_MASK); - break; - } - if (debug) - print_capabilities(devind); - - t3= ((baseclass << 16) | (subclass << 8) | infclass); -#if 0 - if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD) - report_vga(devind); -#endif - - if (nr_pcidev >= NR_PCIDEV) - panic("too many PCI devices: %d", nr_pcidev); - devind= nr_pcidev; - - if (func == 0 && !(headt & PHT_MULTIFUNC)) - break; - } - } + int s; + PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value); + if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) + printf("PCI: warning, sys_outl failed: %d\n", s); } -/*===========================================================================* - * is_duplicate * - *===========================================================================*/ -static int is_duplicate(u8_t busnr, u8_t dev, u8_t func) +static int +is_duplicate(u8_t busnr, u8_t dev, u8_t func) { int i; @@ -951,7 +430,504 @@ static int is_duplicate(u8_t busnr, u8_t dev, u8_t func) return 0; } -static int acpi_get_irq(unsigned bus, unsigned dev, unsigned pin) +static int +get_freebus(void) +{ + int i, freebus; + + freebus= 1; + for (i= 0; i> 16) & 0xffff; +#if 0 + if (v & 0x10000) + { + printf(" WarmReset"); + v &= ~0x10000; + } + if (v & 0x20000) + { + printf(" DblEnded"); + v &= ~0x20000; + } + printf(" DevNum %d", (v & 0x7C0000) >> 18); + v &= ~0x7C0000; +#endif + type0= (cmd & 0xE000) >> 13; + type1= (cmd & 0xF800) >> 11; + if (type0 == 0 || type0 == 1) + { + printf("Capability Type: %s\n", + type0 == 0 ? "Slave or Primary Interface" : + "Host or Secondary Interface"); + cmd &= ~0xE000; + } + else + { + printf(" Capability Type 0x%x", type1); + cmd &= ~0xF800; + } + if (cmd) + printf(" undecoded 0x%x\n", cmd); + +#if 0 + printf("print_hyper_cap: off 4 (ctl): 0x%x\n", + __pci_attr_r32(devind, capptr+4)); + printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n", + __pci_attr_r32(devind, capptr+8)); + printf("print_hyper_cap: off 12 (cap): 0x%x\n", + __pci_attr_r32(devind, capptr+12)); + printf("print_hyper_cap: off 16 (buf count): 0x%x\n", + __pci_attr_r32(devind, capptr+16)); + v= __pci_attr_r32(devind, capptr+20); + printf("print_hyper_cap: @0x%x, off 20 (bus nr): ", + capptr+20); + printf("prim %d", v & 0xff); + printf(", sec %d", (v >> 8) & 0xff); + printf(", sub %d", (v >> 16) & 0xff); + if (v >> 24) + printf(", reserved %d", (v >> 24) & 0xff); + printf("\n"); + printf("print_hyper_cap: off 24 (type): 0x%x\n", + __pci_attr_r32(devind, capptr+24)); +#endif +} + +static void +print_capabilities(int devind) +{ + u8_t status, capptr, type, next, subtype; + const char *str; + + /* Check capabilities bit in the device status register */ + status= __pci_attr_r16(devind, PCI_SR); + if (!(status & PSR_CAPPTR)) + return; + + capptr= (__pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK); + while (capptr != 0) + { + type = __pci_attr_r8(devind, capptr+CAP_TYPE); + next= (__pci_attr_r8(devind, capptr+CAP_NEXT) & PCI_CP_MASK); + switch(type) + { + case 1: str= "PCI Power Management"; break; + case 2: str= "AGP"; break; + case 3: str= "Vital Product Data"; break; + case 4: str= "Slot Identification"; break; + case 5: str= "Message Signaled Interrupts"; break; + case 6: str= "CompactPCI Hot Swap"; break; + case 8: str= "AMD HyperTransport"; break; + case 0xf: str= "Secure Device"; break; + default: str= "(unknown type)"; break; + } + + printf(" @0x%x (0x%08x): capability type 0x%x: %s", + capptr, __pci_attr_r32(devind, capptr), type, str); + if (type == 0x08) + print_hyper_cap(devind, capptr); + else if (type == 0x0f) + { + subtype= (__pci_attr_r8(devind, capptr+2) & 0x07); + switch(subtype) + { + case 0: str= "Device Exclusion Vector"; break; + case 3: str= "IOMMU"; break; + default: str= "(unknown type)"; break; + } + printf(", sub type 0%o: %s", subtype, str); + } + printf("\n"); + capptr= next; + } +} + +/*===========================================================================* + * ISA Bridge Helpers * + *===========================================================================*/ +static void +update_bridge4dev_io(int devind, u32_t io_base, u32_t io_size) +{ + int busnr, busind, type, br_devind; + u16_t v16; + + busnr= pcidev[devind].pd_busnr; + busind= get_busind(busnr); + type= pcibus[busind].pb_type; + if (type == PBT_INTEL_HOST) + return; /* Nothing to do for host controller */ + if (type == PBT_PCIBRIDGE) + { + printf( + "update_bridge4dev_io: not implemented for PCI bridges\n"); + return; + } + if (type != PBT_CARDBUS) + panic("update_bridge4dev_io: strange bus type: %d", type); + + if (debug) + { + printf("update_bridge4dev_io: adding 0x%x at 0x%x\n", + io_size, io_base); + } + br_devind= pcibus[busind].pb_devind; + __pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1); + __pci_attr_w32(br_devind, CBB_IOBASE_0, io_base); + + /* Enable I/O access. Enable busmaster access as well. */ + v16= __pci_attr_r16(devind, PCI_CR); + __pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN); +} + +static int +do_piix(int devind) +{ + int i, s, irqrc, irq; + u32_t elcr1, elcr2, elcr; + +#if DEBUG + printf("in piix\n"); +#endif + if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1))) + printf("Warning, sys_inb failed: %d\n", s); + if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2))) + printf("Warning, sys_inb failed: %d\n", s); + elcr= elcr1 | (elcr2 << 8); + for (i= 0; i<4; i++) + { + irqrc= __pci_attr_r8(devind, PIIX_PIRQRCA+i); + if (irqrc & PIIX_IRQ_DI) + { + if (debug) + printf("INT%c: disabled\n", 'A'+i); + } + else + { + irq= irqrc & PIIX_IRQ_MASK; + if (debug) + printf("INT%c: %d\n", 'A'+i, irq); + if (!(elcr & (1 << irq))) + { + if (debug) + { + printf( + "(warning) IRQ %d is not level triggered\n", + irq); + } + } + irq_mode_pci(irq); + } + } + return 0; +} + +static int +do_amd_isabr(int devind) +{ + int i, busnr, dev, func, xdevind, irq, edge; + u8_t levmask; + u16_t pciirq; + + /* Find required function */ + func= AMD_ISABR_FUNC; + busnr= pcidev[devind].pd_busnr; + dev= pcidev[devind].pd_dev; + + /* Fake a device with the required function */ + if (nr_pcidev >= NR_PCIDEV) + panic("too many PCI devices: %d", nr_pcidev); + xdevind= nr_pcidev; + pcidev[xdevind].pd_busnr= busnr; + pcidev[xdevind].pd_dev= dev; + pcidev[xdevind].pd_func= func; + pcidev[xdevind].pd_inuse= 1; + nr_pcidev++; + + levmask= __pci_attr_r8(xdevind, AMD_ISABR_PCIIRQ_LEV); + pciirq= __pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE); + for (i= 0; i<4; i++) + { + edge= (levmask >> i) & 1; + irq= (pciirq >> (4*i)) & 0xf; + if (!irq) + { + if (debug) + printf("INT%c: disabled\n", 'A'+i); + } + else + { + if (debug) + printf("INT%c: %d\n", 'A'+i, irq); + if (edge && debug) + { + printf( + "(warning) IRQ %d is not level triggered\n", + irq); + } + irq_mode_pci(irq); + } + } + nr_pcidev--; + return 0; +} + +static int +do_sis_isabr(int devind) +{ + int i, irq; + + irq= 0; /* lint */ + for (i= 0; i<4; i++) + { + irq= __pci_attr_r8(devind, SIS_ISABR_IRQ_A+i); + if (irq & SIS_IRQ_DISABLED) + { + if (debug) + printf("INT%c: disabled\n", 'A'+i); + } + else + { + irq &= SIS_IRQ_MASK; + if (debug) + printf("INT%c: %d\n", 'A'+i, irq); + irq_mode_pci(irq); + } + } + return 0; +} + +static int +do_via_isabr(int devind) +{ + int i, irq, edge; + u8_t levmask; + + levmask= __pci_attr_r8(devind, VIA_ISABR_EL); + irq= 0; /* lint */ + edge= 0; /* lint */ + for (i= 0; i<4; i++) + { + switch(i) + { + case 0: + edge= (levmask & VIA_ISABR_EL_INTA); + irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R2) >> 4; + break; + case 1: + edge= (levmask & VIA_ISABR_EL_INTB); + irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R2); + break; + case 2: + edge= (levmask & VIA_ISABR_EL_INTC); + irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R3) >> 4; + break; + case 3: + edge= (levmask & VIA_ISABR_EL_INTD); + irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R1) >> 4; + break; + default: + panic("PCI: VIA ISA Bridge IRQ Detection Failed"); + } + irq &= 0xf; + if (!irq) + { + if (debug) + printf("INT%c: disabled\n", 'A'+i); + } + else + { + if (debug) + printf("INT%c: %d\n", 'A'+i, irq); + if (edge && debug) + { + printf( + "(warning) IRQ %d is not level triggered\n", + irq); + } + irq_mode_pci(irq); + } + } + return 0; +} + +static int +do_isabridge(int busind) +{ + int i, j, r, type, busnr, unknown_bridge, bridge_dev; + u16_t vid, did; + u32_t t3; + const char *dstr; + + unknown_bridge= -1; + bridge_dev= -1; + j= 0; /* lint */ + vid= did= 0; /* lint */ + busnr= pcibus[busind].pb_busnr; + for (i= 0; i< nr_pcidev; i++) + { + if (pcidev[i].pd_busnr != busnr) + continue; + t3= ((pcidev[i].pd_baseclass << 16) | + (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass); + if (t3 == PCI_T3_ISA) + { + /* ISA bridge. Report if no supported bridge is + * found. + */ + unknown_bridge= i; + } + + vid= pcidev[i].pd_vid; + did= pcidev[i].pd_did; + for (j= 0; pci_isabridge[j].vid != 0; j++) + { + if (pci_isabridge[j].vid != vid) + continue; + if (pci_isabridge[j].did != did) + continue; + if (pci_isabridge[j].checkclass && + unknown_bridge != i) + { + /* This part of multifunction device is + * not the bridge. + */ + continue; + } + break; + } + if (pci_isabridge[j].vid) + { + bridge_dev= i; + break; + } + } + + if (bridge_dev != -1) + { + dstr= _pci_dev_name(vid, did); + if (!dstr) + dstr= "unknown device"; + if (debug) + { + printf("found ISA bridge (%04X:%04X) %s\n", + vid, did, dstr); + } + pcibus[busind].pb_isabridge_dev= bridge_dev; + type= pci_isabridge[j].type; + pcibus[busind].pb_isabridge_type= type; + switch(type) + { + case PCI_IB_PIIX: + r= do_piix(bridge_dev); + break; + case PCI_IB_VIA: + r= do_via_isabr(bridge_dev); + break; + case PCI_IB_AMD: + r= do_amd_isabr(bridge_dev); + break; + case PCI_IB_SIS: + r= do_sis_isabr(bridge_dev); + break; + default: + panic("unknown ISA bridge type: %d", type); + } + return r; + } + + if (unknown_bridge == -1) + { + if (debug) + { + printf("(warning) no ISA bridge found on bus %d\n", + busind); + } + return 0; + } + if (debug) + { + printf( + "(warning) unsupported ISA bridge %04X:%04X for bus %d\n", + pcidev[unknown_bridge].pd_vid, + pcidev[unknown_bridge].pd_did, busind); + } + return 0; +} + +/*===========================================================================* + * IRQ handling * + *===========================================================================*/ +static int +acpi_get_irq(unsigned bus, unsigned dev, unsigned pin) { int err; message m; @@ -967,11 +943,12 @@ static int acpi_get_irq(unsigned bus, unsigned dev, unsigned pin) return ((struct acpi_get_irq_resp *)&m)->irq; } -static int derive_irq(struct pcidev * dev, int pin) +static int +derive_irq(struct pcidev * dev, int pin) { struct pcidev * parent_bridge; int slot; - + parent_bridge = &pcidev[pcibus[get_busind(dev->pd_busnr)].pb_devind]; /* @@ -984,16 +961,13 @@ static int derive_irq(struct pcidev * dev, int pin) parent_bridge->pd_dev, (pin + slot) % 4); } -/*===========================================================================* - * record_irq * - *===========================================================================*/ -static void record_irq(devind) -int devind; +static void +record_irq(int devind) { int ilr, ipr, busnr, busind, cb_devind; - ilr= pci_attr_r8_u(devind, PCI_ILR); - ipr= pci_attr_r8_u(devind, PCI_IPR); + ilr= __pci_attr_r8(devind, PCI_ILR); + ipr= __pci_attr_r8(devind, PCI_IPR); if (ipr && machine.apic_enabled) { int irq; @@ -1006,7 +980,7 @@ int devind; if (irq >= 0) { ilr = irq; - pci_attr_w8(devind, PCI_ILR, ilr); + __pci_attr_w8(devind, PCI_ILR, ilr); if (debug) printf("PCI: ACPI IRQ %d for " "device %d.%d.%d INT%c\n", @@ -1069,7 +1043,7 @@ int devind; "assigning IRQ %d to Cardbus device\n", ilr); } - pci_attr_w8(devind, PCI_ILR, ilr); + __pci_attr_w8(devind, PCI_ILR, ilr); pcidev[devind].pd_ilr= ilr; return; } @@ -1084,10 +1058,162 @@ int devind; } /*===========================================================================* - * record_bars_normal * + * BAR helpers * *===========================================================================*/ -static void record_bars_normal(devind) -int devind; +static int +record_bar(int devind, int bar_nr, int last) +{ + int reg, prefetch, type, dev_bar_nr, width; + u32_t bar, bar2; + u16_t cmd; + + /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */ + width = 1; + + reg= PCI_BAR+4*bar_nr; + + bar= __pci_attr_r32(devind, reg); + if (bar & PCI_BAR_IO) + { + /* Disable I/O access before probing for BAR's size */ + cmd = __pci_attr_r16(devind, PCI_CR); + __pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_IO_EN); + + /* Probe BAR's size */ + __pci_attr_w32(devind, reg, 0xffffffff); + bar2= __pci_attr_r32(devind, reg); + + /* Restore original state */ + __pci_attr_w32(devind, reg, bar); + __pci_attr_w16(devind, PCI_CR, cmd); + + bar &= PCI_BAR_IO_MASK; /* Clear non-address bits */ + bar2 &= PCI_BAR_IO_MASK; + bar2= (~bar2 & 0xffff)+1; + if (debug) + { + printf("\tbar_%d: %d bytes at 0x%x I/O\n", + bar_nr, bar2, bar); + } + + dev_bar_nr= pcidev[devind].pd_bar_nr++; + pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO; + pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar; + pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2; + pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr; + if (bar == 0) + { + pcidev[devind].pd_bar[dev_bar_nr].pb_flags |= + PBF_INCOMPLETE; + } + } + else + { + type= (bar & PCI_BAR_TYPE); + + switch(type) { + case PCI_TYPE_32: + case PCI_TYPE_32_1M: + break; + + case PCI_TYPE_64: + /* A 64-bit BAR takes up two consecutive DWORDs. */ + if (last) + { + printf("PCI: device %d.%d.%d BAR %d extends" + " beyond designated area\n", + pcidev[devind].pd_busnr, + pcidev[devind].pd_dev, + pcidev[devind].pd_func, bar_nr); + + return width; + } + width++; + + bar2= __pci_attr_r32(devind, reg+4); + + /* If the upper 32 bits of the BAR are not zero, the + * memory is inaccessible to us; ignore the BAR. + */ + if (bar2 != 0) + { + if (debug) + { + printf("\tbar_%d: (64-bit BAR with" + " high bits set)\n", bar_nr); + } + + return width; + } + + break; + + default: + /* Ignore the BAR. */ + if (debug) + { + printf("\tbar_%d: (unknown type %x)\n", + bar_nr, type); + } + + return width; + } + + /* Disable mem access before probing for BAR's size */ + cmd = __pci_attr_r16(devind, PCI_CR); + __pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN); + + /* Probe BAR's size */ + __pci_attr_w32(devind, reg, 0xffffffff); + bar2= __pci_attr_r32(devind, reg); + + /* Restore original values */ + __pci_attr_w32(devind, reg, bar); + __pci_attr_w16(devind, PCI_CR, cmd); + + if (bar2 == 0) + return width; /* Reg. is not implemented */ + + prefetch= !!(bar & PCI_BAR_PREFETCH); + bar &= PCI_BAR_MEM_MASK; /* Clear non-address bits */ + bar2 &= PCI_BAR_MEM_MASK; + bar2= (~bar2)+1; + if (debug) + { + printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n", + bar_nr, bar2, bar, + prefetch ? " prefetchable" : "", + type == PCI_TYPE_64 ? ", 64-bit" : ""); + } + + dev_bar_nr= pcidev[devind].pd_bar_nr++; + pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0; + pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar; + pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2; + pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr; + if (bar == 0) + { + pcidev[devind].pd_bar[dev_bar_nr].pb_flags |= + PBF_INCOMPLETE; + } + } + + return width; +} + +static void +record_bars(int devind, int last_reg) +{ + int i, reg, width; + + for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width) + { + width = record_bar(devind, i, reg == last_reg); + } +} + +static void +record_bars_normal(int devind) { int i, j, clear_01, clear_23, pb_nr; @@ -1147,11 +1273,8 @@ int devind; } } -/*===========================================================================* - * record_bars_bridge * - *===========================================================================*/ -static void record_bars_bridge(devind) -int devind; +static void +record_bars_bridge(int devind) { u32_t base, limit, size; @@ -1160,12 +1283,12 @@ int devind; */ record_bars(devind, PCI_BAR_2); - base= ((pci_attr_r8_u(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) | - (pci_attr_r16(devind, PPB_IOBASEU16) << 16); + base= ((__pci_attr_r8(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) | + (__pci_attr_r16(devind, PPB_IOBASEU16) << 16); limit= 0xff | - ((pci_attr_r8_u(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) | + ((__pci_attr_r8(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) | ((~PPB_IOL_MASK & 0xff) << 8) | - (pci_attr_r16(devind, PPB_IOLIMITU16) << 16); + (__pci_attr_r16(devind, PPB_IOLIMITU16) << 16); size= limit-base + 1; if (debug) { @@ -1173,9 +1296,9 @@ int devind; base, limit, size); } - base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16); + base= ((__pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16); limit= 0xffff | - ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) | + ((__pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) | ((~PPB_MEML_MASK & 0xffff) << 16); size= limit-base + 1; if (debug) @@ -1185,9 +1308,9 @@ int devind; } /* Ignore the upper 32 bits */ - base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16); + base= ((__pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16); limit= 0xffff | - ((pci_attr_r16(devind, PPB_PFMEMLIMIT) & + ((__pci_attr_r16(devind, PPB_PFMEMLIMIT) & PPB_PFMEML_MASK) << 16) | ((~PPB_PFMEML_MASK & 0xffff) << 16); size= limit-base + 1; @@ -1199,19 +1322,16 @@ int devind; } } -/*===========================================================================* - * record_bars_cardbus * - *===========================================================================*/ -static void record_bars_cardbus(devind) -int devind; +static void +record_bars_cardbus(int devind) { u32_t base, limit, size; /* The generic BAR area of CardBus devices is one DWORD in size. */ record_bars(devind, PCI_BAR); - base= pci_attr_r32_u(devind, CBB_MEMBASE_0); - limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_0) | + base= __pci_attr_r32(devind, CBB_MEMBASE_0); + limit= __pci_attr_r32(devind, CBB_MEMLIMIT_0) | (~CBB_MEML_MASK & 0xffffffff); size= limit-base + 1; if (debug) @@ -1220,8 +1340,8 @@ int devind; base, limit, size); } - base= pci_attr_r32_u(devind, CBB_MEMBASE_1); - limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_1) | + base= __pci_attr_r32(devind, CBB_MEMBASE_1); + limit= __pci_attr_r32(devind, CBB_MEMLIMIT_1) | (~CBB_MEML_MASK & 0xffffffff); size= limit-base + 1; if (debug) @@ -1230,8 +1350,8 @@ int devind; base, limit, size); } - base= pci_attr_r32_u(devind, CBB_IOBASE_0); - limit= pci_attr_r32_u(devind, CBB_IOLIMIT_0) | + base= __pci_attr_r32(devind, CBB_IOBASE_0); + limit= __pci_attr_r32(devind, CBB_IOLIMIT_0) | (~CBB_IOL_MASK & 0xffffffff); size= limit-base + 1; if (debug) @@ -1240,8 +1360,8 @@ int devind; base, limit, size); } - base= pci_attr_r32_u(devind, CBB_IOBASE_1); - limit= pci_attr_r32_u(devind, CBB_IOLIMIT_1) | + base= __pci_attr_r32(devind, CBB_IOBASE_1); + limit= __pci_attr_r32(devind, CBB_IOLIMIT_1) | (~CBB_IOL_MASK & 0xffffffff); size= limit-base + 1; if (debug) @@ -1251,210 +1371,8 @@ int devind; } } -/*===========================================================================* - * record_bars * - *===========================================================================*/ -static void record_bars(int devind, int last_reg) -{ - int i, reg, width; - - for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width) - { - width = record_bar(devind, i, reg == last_reg); - } -} - -/*===========================================================================* - * record_bar * - *===========================================================================*/ -static int record_bar(devind, bar_nr, last) -int devind; -int bar_nr; -int last; -{ - int reg, prefetch, type, dev_bar_nr, width; - u32_t bar, bar2; - u16_t cmd; - - /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */ - width = 1; - - reg= PCI_BAR+4*bar_nr; - - bar= pci_attr_r32_u(devind, reg); - if (bar & PCI_BAR_IO) - { - /* Disable I/O access before probing for BAR's size */ - cmd = pci_attr_r16(devind, PCI_CR); - pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_IO_EN); - - /* Probe BAR's size */ - pci_attr_w32(devind, reg, 0xffffffff); - bar2= pci_attr_r32_u(devind, reg); - - /* Restore original state */ - pci_attr_w32(devind, reg, bar); - pci_attr_w16(devind, PCI_CR, cmd); - - bar &= PCI_BAR_IO_MASK; /* Clear non-address bits */ - bar2 &= PCI_BAR_IO_MASK; - bar2= (~bar2 & 0xffff)+1; - if (debug) - { - printf("\tbar_%d: %d bytes at 0x%x I/O\n", - bar_nr, bar2, bar); - } - - dev_bar_nr= pcidev[devind].pd_bar_nr++; - pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO; - pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar; - pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2; - pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr; - if (bar == 0) - { - pcidev[devind].pd_bar[dev_bar_nr].pb_flags |= - PBF_INCOMPLETE; - } - } - else - { - type= (bar & PCI_BAR_TYPE); - - switch(type) { - case PCI_TYPE_32: - case PCI_TYPE_32_1M: - break; - - case PCI_TYPE_64: - /* A 64-bit BAR takes up two consecutive DWORDs. */ - if (last) - { - printf("PCI: device %d.%d.%d BAR %d extends" - " beyond designated area\n", - pcidev[devind].pd_busnr, - pcidev[devind].pd_dev, - pcidev[devind].pd_func, bar_nr); - - return width; - } - width++; - - bar2= pci_attr_r32_u(devind, reg+4); - - /* If the upper 32 bits of the BAR are not zero, the - * memory is inaccessible to us; ignore the BAR. - */ - if (bar2 != 0) - { - if (debug) - { - printf("\tbar_%d: (64-bit BAR with" - " high bits set)\n", bar_nr); - } - - return width; - } - - break; - - default: - /* Ignore the BAR. */ - if (debug) - { - printf("\tbar_%d: (unknown type %x)\n", - bar_nr, type); - } - - return width; - } - - /* Disable mem access before probing for BAR's size */ - cmd = pci_attr_r16(devind, PCI_CR); - pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN); - - /* Probe BAR's size */ - pci_attr_w32(devind, reg, 0xffffffff); - bar2= pci_attr_r32_u(devind, reg); - - /* Restore original values */ - pci_attr_w32(devind, reg, bar); - pci_attr_w16(devind, PCI_CR, cmd); - - if (bar2 == 0) - return width; /* Reg. is not implemented */ - - prefetch= !!(bar & PCI_BAR_PREFETCH); - bar &= PCI_BAR_MEM_MASK; /* Clear non-address bits */ - bar2 &= PCI_BAR_MEM_MASK; - bar2= (~bar2)+1; - if (debug) - { - printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n", - bar_nr, bar2, bar, - prefetch ? " prefetchable" : "", - type == PCI_TYPE_64 ? ", 64-bit" : ""); - } - - dev_bar_nr= pcidev[devind].pd_bar_nr++; - pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0; - pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar; - pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2; - pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr; - if (bar == 0) - { - pcidev[devind].pd_bar[dev_bar_nr].pb_flags |= - PBF_INCOMPLETE; - } - } - - return width; -} - -/*===========================================================================* - * complete_bridges * - *===========================================================================*/ -static void complete_bridges() -{ - int i, freebus, devind, prim_busnr; - - for (i= 0; i= NR_PCIDEV) + panic("too many PCI devices: %d", nr_pcidev); + devind= nr_pcidev; - /* Enable I/O access. Enable busmaster access as well. */ - v16= pci_attr_r16(devind, PCI_CR); - pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN); -} - -/*===========================================================================* - * get_freebus * - *===========================================================================*/ -static int get_freebus() -{ - int i, freebus; - - freebus= 1; - for (i= 0; i= NR_PCIDEV) + panic("too many PCI devices: %d", nr_pcidev); + devind= nr_pcidev; + + if (func == 0 && !(headt & PHT_MULTIFUNC)) + break; } - return 0; - } - if (debug) - { - printf( - "(warning) unsupported ISA bridge %04X:%04X for bus %d\n", - pcidev[unknown_bridge].pd_vid, - pcidev[unknown_bridge].pd_did, busind); } +} + + +static u16_t +pcibr_std_rsts(int busind) +{ + int devind; + + devind= pcibus[busind].pb_devind; + return __pci_attr_r16(devind, PPB_SSTS); +} + +static void +pcibr_std_wsts(int busind, u16_t value) +{ + int devind; + devind= pcibus[busind].pb_devind; + +#if 0 + printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n", + busind, value, devind); +#endif + __pci_attr_w16(devind, PPB_SSTS, value); +} + +static u16_t +pcibr_cb_rsts(int busind) +{ + int devind; + devind= pcibus[busind].pb_devind; + + return __pci_attr_r16(devind, CBB_SSTS); +} + +static void +pcibr_cb_wsts(int busind, u16_t value) +{ + int devind; + devind= pcibus[busind].pb_devind; + +#if 0 + printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n", + busind, value, devind); +#endif + __pci_attr_w16(devind, CBB_SSTS, value); +} + +static u16_t +pcibr_via_rsts(int busind) +{ return 0; } +static void +pcibr_via_wsts(int busind, u16_t value) +{ + int devind; + devind= pcibus[busind].pb_devind; + +#if 0 + printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n", + busind, value, devind); +#endif +} + +static void +complete_bridges(void) +{ + int i, freebus, devind, prim_busnr; + + for (i= 0; i= NR_PCIBUS) panic("too many PCI busses: %d", nr_pcibus); @@ -1967,7 +1979,7 @@ int busind; pcibus[ind].pb_wsts= pcibr_via_wsts; break; default: - panic("unknown PCI-PCI bridge type: %d", type); + panic("unknown PCI-PCI bridge type: %d", type); } if (machine.apic_enabled) @@ -1978,7 +1990,7 @@ int busind; { printf( "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n", - ind, sbusn, pci_attr_r8_u(devind, PPB_SUBORDBN)); + ind, sbusn, __pci_attr_r8(devind, PPB_SUBORDBN)); } if (sbusn == 0) { @@ -1995,207 +2007,112 @@ int busind; } /*===========================================================================* - * get_busind * + * pci_intel_init * *===========================================================================*/ -static int get_busind(busnr) -int busnr; +static void +pci_intel_init() { - int i; + /* Try to detect a know PCI controller. Read the Vendor ID and + * the Device ID for function 0 of device 0. + * Two times the value 0xffff suggests a system without a (compatible) + * PCI controller. + */ + u32_t bus, dev, func; + u16_t vid, did; + int s, i, r, busind, busnr; + const char *dstr; - for (i= 0; i= NR_PCIBUS) + panic("too many PCI busses: %d", nr_pcibus); + busind= nr_pcibus; + nr_pcibus++; + pcibus[busind].pb_type= PBT_INTEL_HOST; + pcibus[busind].pb_needinit= 0; + pcibus[busind].pb_isabridge_dev= -1; + pcibus[busind].pb_isabridge_type= 0; + pcibus[busind].pb_devind= -1; + pcibus[busind].pb_busnr= 0; + pcibus[busind].pb_rreg8= pcii_rreg8; + pcibus[busind].pb_rreg16= pcii_rreg16; + pcibus[busind].pb_rreg32= pcii_rreg32; + pcibus[busind].pb_wreg8= pcii_wreg8; + pcibus[busind].pb_wreg16= pcii_wreg16; + pcibus[busind].pb_wreg32= pcii_wreg32; + pcibus[busind].pb_rsts= pcii_rsts; + pcibus[busind].pb_wsts= pcii_wsts; + + dstr= _pci_dev_name(vid, did); + if (!dstr) + dstr= "unknown device"; + if (debug) { - irqrc= pci_attr_r8_u(devind, PIIX_PIRQRCA+i); - if (irqrc & PIIX_IRQ_DI) - { - if (debug) - printf("INT%c: disabled\n", 'A'+i); - } - else - { - irq= irqrc & PIIX_IRQ_MASK; - if (debug) - printf("INT%c: %d\n", 'A'+i, irq); - if (!(elcr & (1 << irq))) - { - if (debug) - { - printf( - "(warning) IRQ %d is not level triggered\n", - irq); - } - } - irq_mode_pci(irq); - } + printf("pci_intel_init: %s (%04X:%04X)\n", + dstr, vid, did); } - return 0; -} -/*===========================================================================* - * do_amd_isabr * - *===========================================================================*/ -static int do_amd_isabr(int devind) -{ - int i, busnr, dev, func, xdevind, irq, edge; - u8_t levmask; - u16_t pciirq; + probe_bus(busind); - /* Find required function */ - func= AMD_ISABR_FUNC; - busnr= pcidev[devind].pd_busnr; - dev= pcidev[devind].pd_dev; - - /* Fake a device with the required function */ - if (nr_pcidev >= NR_PCIDEV) - panic("too many PCI devices: %d", nr_pcidev); - xdevind= nr_pcidev; - pcidev[xdevind].pd_busnr= busnr; - pcidev[xdevind].pd_dev= dev; - pcidev[xdevind].pd_func= func; - pcidev[xdevind].pd_inuse= 1; - nr_pcidev++; - - levmask= pci_attr_r8_u(xdevind, AMD_ISABR_PCIIRQ_LEV); - pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE); - for (i= 0; i<4; i++) + r= do_isabridge(busind); + if (r != OK) { - edge= (levmask >> i) & 1; - irq= (pciirq >> (4*i)) & 0xf; - if (!irq) + busnr= pcibus[busind].pb_busnr; + + /* Disable all devices for this bus */ + for (i= 0; i> 4; - break; - case 1: - edge= (levmask & VIA_ISABR_EL_INTB); - irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2); - break; - case 2: - edge= (levmask & VIA_ISABR_EL_INTC); - irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R3) >> 4; - break; - case 3: - edge= (levmask & VIA_ISABR_EL_INTD); - irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R1) >> 4; - break; - default: - assert(0); - } - irq &= 0xf; - if (!irq) - { - if (debug) - printf("INT%c: disabled\n", 'A'+i); - } - else - { - if (debug) - printf("INT%c: %d\n", 'A'+i, irq); - if (edge && debug) - { - printf( - "(warning) IRQ %d is not level triggered\n", - irq); - } - irq_mode_pci(irq); - } - } - return 0; -} - - #if 0 /*===========================================================================* * report_vga * *===========================================================================*/ -static void report_vga(devind) -int devind; +static void +report_vga(int devind) { /* Report the amount of video memory. This is needed by the X11R6 * postinstall script to chmem the X server. Hopefully this can be @@ -2226,426 +2143,11 @@ int devind; #endif -/*===========================================================================* - * pci_vid_name * - *===========================================================================*/ -static char *pci_vid_name(u16_t vid) -{ - int i; - - for (i= 0; pci_vendor_table[i].name; i++) - { - if (pci_vendor_table[i].vid == vid) - return pci_vendor_table[i].name; - } - return "unknown"; -} - -/*===========================================================================* - * pci_baseclass_name * - *===========================================================================*/ -static char *pci_baseclass_name(u8_t baseclass) -{ - int i; - - for (i= 0; pci_baseclass_table[i].name; i++) - { - if (pci_baseclass_table[i].baseclass == baseclass) - return pci_baseclass_table[i].name; - } - return NULL; -} - -/*===========================================================================* - * pci_subclass_name * - *===========================================================================*/ -static char *pci_subclass_name(u8_t baseclass, u8_t subclass, u8_t infclass) -{ - int i; - - for (i= 0; pci_subclass_table[i].name; i++) - { - if (pci_subclass_table[i].baseclass != baseclass) - continue; - if (pci_subclass_table[i].subclass != subclass) - continue; - if (pci_subclass_table[i].infclass != infclass && - pci_subclass_table[i].infclass != (u16_t)-1) - { - continue; - } - return pci_subclass_table[i].name; - } - return NULL; -} - -/*===========================================================================* - * ntostr * - *===========================================================================*/ -static void ntostr(n, str, end) -unsigned n; -char **str; -const char *end; -{ - char tmpstr[20]; - int i; - - if (n == 0) - { - tmpstr[0]= '0'; - i= 1; - } - else - { - for (i= 0; n; i++) - { - tmpstr[i]= '0' + (n%10); - n /= 10; - } - } - for (; i>0; i--) - { - if (*str == end) - { - break; - } - **str= tmpstr[i-1]; - (*str)++; - } - if (*str == end) - (*str)[-1]= '\0'; - else - **str= '\0'; -} - -/*===========================================================================* - * pci_attr_rsts * - *===========================================================================*/ -static u16_t pci_attr_rsts(devind) -int devind; -{ - int busnr, busind; - - busnr= pcidev[devind].pd_busnr; - busind= get_busind(busnr); - return pcibus[busind].pb_rsts(busind); -} - - -/*===========================================================================* - * pcibr_std_rsts * - *===========================================================================*/ -static u16_t pcibr_std_rsts(busind) -int busind; -{ - int devind; - - devind= pcibus[busind].pb_devind; - return pci_attr_r16(devind, PPB_SSTS); -} - -/*===========================================================================* - * pcibr_std_wsts * - *===========================================================================*/ -static void pcibr_std_wsts(int busind, u16_t value) -{ - int devind; - devind= pcibus[busind].pb_devind; - -#if 0 - printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n", - busind, value, devind); -#endif - pci_attr_w16(devind, PPB_SSTS, value); -} - -/*===========================================================================* - * pcibr_cb_rsts * - *===========================================================================*/ -static u16_t pcibr_cb_rsts(busind) -int busind; -{ - int devind; - devind= pcibus[busind].pb_devind; - - return pci_attr_r16(devind, CBB_SSTS); -} - -/*===========================================================================* - * pcibr_cb_wsts * - *===========================================================================*/ -static void pcibr_cb_wsts(int busind, u16_t value) -{ - int devind; - devind= pcibus[busind].pb_devind; - -#if 0 - printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n", - busind, value, devind); -#endif - pci_attr_w16(devind, CBB_SSTS, value); -} - -/*===========================================================================* - * pcibr_via_rsts * - *===========================================================================*/ -static u16_t pcibr_via_rsts(int busind) -{ - return 0; -} - -/*===========================================================================* - * pcibr_via_wsts * - *===========================================================================*/ -static void pcibr_via_wsts(int busind, u16_t value) -{ - int devind; - devind= pcibus[busind].pb_devind; - -#if 0 - printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n", - busind, value, devind); -#endif -} - -/*===========================================================================* - * pci_attr_wsts * - *===========================================================================*/ -static void pci_attr_wsts(int devind, u16_t value) -{ - int busnr, busind; - - busnr= pcidev[devind].pd_busnr; - busind= get_busind(busnr); - pcibus[busind].pb_wsts(busind, value); -} - - -/*===========================================================================* - * pcii_rreg8 * - *===========================================================================*/ -static u8_t pcii_rreg8(busind, devind, port) -int busind; -int devind; -int port; -{ - u8_t v; - int s; - - v= PCII_RREG8_(pcibus[busind].pb_busnr, - pcidev[devind].pd_dev, pcidev[devind].pd_func, - port); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n", s); -#if 0 - printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n", - busind, devind, port, - pcibus[busind].pb_bus, pcidev[devind].pd_dev, - pcidev[devind].pd_func, v); -#endif - return v; -} - -/*===========================================================================* - * pcii_rreg16 * - *===========================================================================*/ -static u16_t pcii_rreg16(int busind, int devind, int port) -{ - u16_t v; - int s; - - v= PCII_RREG16_(pcibus[busind].pb_busnr, - pcidev[devind].pd_dev, pcidev[devind].pd_func, - port); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n", s); -#if 0 - printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n", - busind, devind, port, - pcibus[busind].pb_bus, pcidev[devind].pd_dev, - pcidev[devind].pd_func, v); -#endif - return v; -} - -/*===========================================================================* - * pcii_rreg32 * - *===========================================================================*/ -static u32_t pcii_rreg32(int busind, int devind, int port) -{ - u32_t v; - int s; - - v= PCII_RREG32_(pcibus[busind].pb_busnr, - pcidev[devind].pd_dev, pcidev[devind].pd_func, - port); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n", s); -#if 0 - printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n", - busind, devind, port, - pcibus[busind].pb_bus, pcidev[devind].pd_dev, - pcidev[devind].pd_func, v); -#endif - return v; -} - -/*===========================================================================* - * pcii_wreg8 * - *===========================================================================*/ -static void pcii_wreg8( - int busind, - int devind, - int port, - u8_t value -) -{ - int s; -#if 0 - printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n", - busind, devind, port, value, - pcibus[busind].pb_bus, pcidev[devind].pd_dev, - pcidev[devind].pd_func); -#endif - PCII_WREG8_(pcibus[busind].pb_busnr, - pcidev[devind].pd_dev, pcidev[devind].pd_func, - port, value); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n", s); -} - -/*===========================================================================* - * pcii_wreg16 * - *===========================================================================*/ -static void pcii_wreg16( - int busind, - int devind, - int port, - u16_t value -) -{ - int s; -#if 0 - printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n", - busind, devind, port, value, - pcibus[busind].pb_bus, pcidev[devind].pd_dev, - pcidev[devind].pd_func); -#endif - PCII_WREG16_(pcibus[busind].pb_busnr, - pcidev[devind].pd_dev, pcidev[devind].pd_func, - port, value); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n", s); -} - -/*===========================================================================* - * pcii_wreg32 * - *===========================================================================*/ -static void pcii_wreg32( - int busind, - int devind, - int port, - u32_t value -) -{ - int s; -#if 0 - printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n", - busind, devind, port, value, - pcibus[busind].pb_busnr, pcidev[devind].pd_dev, - pcidev[devind].pd_func); -#endif - PCII_WREG32_(pcibus[busind].pb_busnr, - pcidev[devind].pd_dev, pcidev[devind].pd_func, - port, value); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n",s); -} - -/*===========================================================================* - * pcii_rsts * - *===========================================================================*/ -static u16_t pcii_rsts(int busind) -{ - u16_t v; - int s; - - v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n", s); - return v; -} - -/*===========================================================================* - * pcii_wsts * - *===========================================================================*/ -static void pcii_wsts(int busind, u16_t value) -{ - int s; - PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value); - if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL))) - printf("PCI: warning, sys_outl failed: %d\n", s); -} - - -/*===========================================================================* - * print_capabilities * - *===========================================================================*/ -static void print_capabilities(int devind) -{ - u8_t status, capptr, type, next, subtype; - char *str; - - /* Check capabilities bit in the device status register */ - status= pci_attr_r16(devind, PCI_SR); - if (!(status & PSR_CAPPTR)) - return; - - capptr= (pci_attr_r8_u(devind, PCI_CAPPTR) & PCI_CP_MASK); - while (capptr != 0) - { - type = pci_attr_r8_u(devind, capptr+CAP_TYPE); - next= (pci_attr_r8_u(devind, capptr+CAP_NEXT) & PCI_CP_MASK); - switch(type) - { - case 1: str= "PCI Power Management"; break; - case 2: str= "AGP"; break; - case 3: str= "Vital Product Data"; break; - case 4: str= "Slot Identification"; break; - case 5: str= "Message Signaled Interrupts"; break; - case 6: str= "CompactPCI Hot Swap"; break; - case 8: str= "AMD HyperTransport"; break; - case 0xf: str= "Secure Device"; break; - default: str= "(unknown type)"; break; - } - - printf(" @0x%x (0x%08x): capability type 0x%x: %s", - capptr, pci_attr_r32_u(devind, capptr), type, str); - if (type == 0x08) - print_hyper_cap(devind, capptr); - else if (type == 0x0f) - { - subtype= (pci_attr_r8_u(devind, capptr+2) & 0x07); - switch(subtype) - { - case 0: str= "Device Exclusion Vector"; break; - case 3: str= "IOMMU"; break; - default: str= "(unknown type)"; break; - } - printf(", sub type 0%o: %s", subtype, str); - } - printf("\n"); - capptr= next; - } -} - - /*===========================================================================* * visible * *===========================================================================*/ -static int visible(aclp, devind) -struct rs_pci *aclp; -int devind; +static int +visible(struct rs_pci *aclp, int devind) { u16_t acl_sub_vid, acl_sub_did; int i; @@ -2690,72 +2192,465 @@ int devind; } /*===========================================================================* - * print_hyper_cap * + * sef_cb_init_fresh * *===========================================================================*/ -static void print_hyper_cap(int devind, u8_t capptr) -{ - u32_t v; - u16_t cmd; - int type0, type1; +int +sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the pci driver. */ + long v; + int i, r; + struct rprocpub rprocpub[NR_BOOT_PROCS]; - printf("\n"); - v= pci_attr_r32_u(devind, capptr); - printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr); - cmd= (v >> 16) & 0xffff; -#if 0 - if (v & 0x10000) - { - printf(" WarmReset"); - v &= ~0x10000; - } - if (v & 0x20000) - { - printf(" DblEnded"); - v &= ~0x20000; - } - printf(" DevNum %d", (v & 0x7C0000) >> 18); - v &= ~0x7C0000; -#endif - type0= (cmd & 0xE000) >> 13; - type1= (cmd & 0xF800) >> 11; - if (type0 == 0 || type0 == 1) - { - printf("Capability Type: %s\n", - type0 == 0 ? "Slave or Primary Interface" : - "Host or Secondary Interface"); - cmd &= ~0xE000; - } - else - { - printf(" Capability Type 0x%x", type1); - cmd &= ~0xF800; - } - if (cmd) - printf(" undecoded 0x%x\n", cmd); + v= 0; + env_parse("pci_debug", "d", 0, &v, 0, 1); + debug= v; -#if 0 - printf("print_hyper_cap: off 4 (ctl): 0x%x\n", - pci_attr_r32_u(devind, capptr+4)); - printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n", - pci_attr_r32_u(devind, capptr+8)); - printf("print_hyper_cap: off 12 (cap): 0x%x\n", - pci_attr_r32_u(devind, capptr+12)); - printf("print_hyper_cap: off 16 (buf count): 0x%x\n", - pci_attr_r32_u(devind, capptr+16)); - v= pci_attr_r32_u(devind, capptr+20); - printf("print_hyper_cap: @0x%x, off 20 (bus nr): ", - capptr+20); - printf("prim %d", v & 0xff); - printf(", sec %d", (v >> 8) & 0xff); - printf(", sub %d", (v >> 16) & 0xff); - if (v >> 24) - printf(", reserved %d", (v >> 24) & 0xff); - printf("\n"); - printf("print_hyper_cap: off 24 (type): 0x%x\n", - pci_attr_r32_u(devind, capptr+24)); -#endif + if (sys_getmachine(&machine)) { + printf("PCI: no machine\n"); + return ENODEV; + } + if (machine.apic_enabled && + ds_retrieve_label_endpt("acpi", &acpi_ep) != OK) { + panic("PCI: Cannot use APIC mode without ACPI!\n"); + } + + /* Only Intel (compatible) PCI controllers are supported at the + * moment. + */ + pci_intel_init(); + + /* Map all the services in the boot image. */ + if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, + (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) { + panic("sys_safecopyfrom failed: %d", r); + } + for(i=0;i < NR_BOOT_PROCS;i++) { + if(rprocpub[i].in_use) { + if((r = map_service(&rprocpub[i])) != OK) { + panic("unable to map service: %d", r); + } + } + } + + return(OK); } -/* - * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $ - */ +/*===========================================================================* + * map_service * + *===========================================================================*/ +int +map_service(struct rprocpub *rpub) +{ +/* Map a new service by registering a new acl entry if required. */ + int i; + + /* Stop right now if no pci device or class is found. */ + if(rpub->pci_acl.rsp_nr_device == 0 + && rpub->pci_acl.rsp_nr_class == 0) { + return(OK); + } + + /* Find a free acl slot. */ + for (i= 0; i= NR_DRIVERS) + { + printf("PCI: map_service: table is full\n"); + return ENOMEM; + } + + /* Initialize acl slot. */ + pci_acl[i].inuse = 1; + pci_acl[i].acl = rpub->pci_acl; + + return(OK); +} + +/*===========================================================================* + * _pci_find_dev * + *===========================================================================*/ +int +_pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp) +{ + int devind; + + for (devind= 0; devind < nr_pcidev; devind++) + { + if (pcidev[devind].pd_busnr == bus && + pcidev[devind].pd_dev == dev && + pcidev[devind].pd_func == func) + { + break; + } + } + if (devind >= nr_pcidev) + return 0; +#if 0 + if (pcidev[devind].pd_inuse) + return 0; +#endif + *devindp= devind; + return 1; +} + +/*===========================================================================* + * _pci_first_dev * + *===========================================================================*/ +int +_pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, + u16_t *didp) +{ + int devind; + + for (devind= 0; devind < nr_pcidev; devind++) + { +#if 0 + if (pcidev[devind].pd_inuse) + continue; +#endif + if (!visible(aclp, devind)) + continue; + break; + } + if (devind >= nr_pcidev) + return 0; + *devindp= devind; + *vidp= pcidev[devind].pd_vid; + *didp= pcidev[devind].pd_did; + return 1; +} + +/*===========================================================================* + * _pci_next_dev * + *===========================================================================*/ +int +_pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp) +{ + int devind; + + for (devind= *devindp+1; devind < nr_pcidev; devind++) + { +#if 0 + if (pcidev[devind].pd_inuse) + continue; +#endif + if (!visible(aclp, devind)) + continue; + break; + } + if (devind >= nr_pcidev) + return 0; + *devindp= devind; + *vidp= pcidev[devind].pd_vid; + *didp= pcidev[devind].pd_did; + return 1; +} + +/*===========================================================================* + * _pci_reserve * + *===========================================================================*/ +int +_pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp) +{ + int i, r; + int ilr; + 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= nr_pcidev) + return EINVAL; + + *vidp= pcidev[devind].pd_vid; + *didp= pcidev[devind].pd_did; + return OK; +} + +/*===========================================================================* + * _pci_rescan_bus * + *===========================================================================*/ +void +_pci_rescan_bus(u8_t busnr) +{ + int busind; + + busind= get_busind(busnr); + probe_bus(busind); + + /* Allocate bus numbers for uninitialized bridges */ + complete_bridges(); + + /* Allocate I/O and memory resources for uninitialized devices */ + complete_bars(); +} + +/*===========================================================================* + * _pci_slot_name * + *===========================================================================*/ +int +_pci_slot_name(int devind, char **cpp) +{ + static char label[]= "ddd.ddd.ddd.ddd"; + char *end; + char *p; + + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + + p= label; + end= label+sizeof(label); + + /* FIXME: domain nb is always 0 on 32bit system, but we should + * retrieve it properly, somehow. */ + ntostr(0, &p, end); + *p++= '.'; + + ntostr(pcidev[devind].pd_busnr, &p, end); + *p++= '.'; + + ntostr(pcidev[devind].pd_dev, &p, end); + *p++= '.'; + + ntostr(pcidev[devind].pd_func, &p, end); + + *cpp= label; + return OK; +} + +/*===========================================================================* + * _pci_dev_name * + *===========================================================================*/ +const char * +_pci_dev_name(u16_t vid, u16_t did) +{ + int i; + + for (i= 0; pci_device_table[i].name; i++) + { + if (pci_device_table[i].vid == vid && + pci_device_table[i].did == did) + { + return pci_device_table[i].name; + } + } + return NULL; +} + +/*===========================================================================* + * _pci_get_bar * + *===========================================================================*/ +int +_pci_get_bar(int devind, int port, u32_t *base, u32_t *size, + int *ioflag) +{ + int i, reg; + + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + + for (i= 0; i < pcidev[devind].pd_bar_nr; i++) + { + reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr; + + if (reg == port) + { + if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE) + return EINVAL; + + *base= pcidev[devind].pd_bar[i].pb_base; + *size= pcidev[devind].pd_bar[i].pb_size; + *ioflag= + !!(pcidev[devind].pd_bar[i].pb_flags & PBF_IO); + return OK; + } + } + return EINVAL; +} + +/*===========================================================================* + * _pci_attr_r8 * + *===========================================================================*/ +int +_pci_attr_r8(int devind, int port, u8_t *vp) +{ + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + if (port < 0 || port > 256-1) + return EINVAL; + + *vp= __pci_attr_r8(devind, port); + return OK; +} + +/*===========================================================================* + * _pci_attr_r16 * + *===========================================================================*/ +int +_pci_attr_r16(int devind, int port, u16_t *vp) +{ + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + if (port < 0 || port > 256-2) + return EINVAL; + + *vp= __pci_attr_r16(devind, port); + return OK; +} + +/*===========================================================================* + * _pci_attr_r32 * + *===========================================================================*/ +int +_pci_attr_r32(int devind, int port, u32_t *vp) +{ + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + if (port < 0 || port > 256-4) + return EINVAL; + + *vp= __pci_attr_r32(devind, port); + return OK; +} + +/*===========================================================================* + * _pci_attr_w8 * + *===========================================================================*/ +int +_pci_attr_w8(int devind, int port, u8_t value) +{ + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + if (port < 0 || port > 256-1) + return EINVAL; + + __pci_attr_w8(devind, port, value); + return OK; +} + +/*===========================================================================* + * _pci_attr_w16 * + *===========================================================================*/ +int +_pci_attr_w16(int devind, int port, u16_t value) +{ + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + if (port < 0 || port > 256-2) + return EINVAL; + + __pci_attr_w16(devind, port, value); + return OK; +} + +/*===========================================================================* + * _pci_attr_w32 * + *===========================================================================*/ +int +_pci_attr_w32(int devind, int port, u32_t value) +{ + if (devind < 0 || devind >= nr_pcidev) + return EINVAL; + if (port < 0 || port > 256-4) + return EINVAL; + + __pci_attr_w32(devind, port, value); + return OK; +} diff --git a/minix/drivers/bus/pci/pci.h b/minix/drivers/bus/pci/pci.h index 1aac8d373..e3c6fd383 100644 --- a/minix/drivers/bus/pci/pci.h +++ b/minix/drivers/bus/pci/pci.h @@ -4,36 +4,23 @@ pci.h Created: Jan 2000 by Philip Homburg */ -#include -#include -#include - -/* tempory functions: to be replaced later (see pci_intel.h) */ -unsigned pci_inb(u16_t port); -unsigned pci_inw(u16_t port); -unsigned pci_inl(u16_t port); - -void pci_outb(u16_t port, u8_t value); -void pci_outw(u16_t port, u16_t value); -void pci_outl(u16_t port, u32_t value); - struct pci_vendor { u16_t vid; - char *name; + const char *name; }; struct pci_device { u16_t vid; u16_t did; - char *name; + const char *name; }; struct pci_baseclass { u8_t baseclass; - char *name; + const char *name; }; struct pci_subclass @@ -41,7 +28,7 @@ struct pci_subclass u8_t baseclass; u8_t subclass; u16_t infclass; - char *name; + const char *name; }; struct pci_intel_ctrl @@ -83,6 +70,8 @@ struct pci_acl /* Still needed? */ #define PCI_AGPB_VIA 3 /* VIA compatible AGP bridge */ +extern int debug; + extern struct pci_vendor pci_vendor_table[]; extern struct pci_device pci_device_table[]; extern struct pci_baseclass pci_baseclass_table[]; @@ -92,24 +81,36 @@ extern struct pci_intel_ctrl pci_intel_ctrl[]; #endif extern struct pci_isabridge pci_isabridge[]; extern struct pci_pcibridge pci_pcibridge[]; +extern struct pci_acl pci_acl[NR_DRIVERS]; /* Function prototypes. */ int sef_cb_init_fresh(int type, sef_init_info_t *info); int map_service(struct rprocpub *rpub); -int pci_reserve_a(int devind, endpoint_t proc, struct rs_pci *aclp); -void pci_release(endpoint_t proc); -int pci_first_dev_a(struct rs_pci *aclp, int *devindp, u16_t *vidp, + +int _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp); +void _pci_release(endpoint_t proc); + +int _pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp); -int pci_next_dev_a(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t +int _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp); +int _pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp); -int pci_attr_r8_s(int devind, int port, u8_t *vp); -int pci_attr_r32_s(int devind, int port, u32_t *vp); -int pci_get_bar_s(int devind, int port, u32_t *base, u32_t *size, int +void _pci_rescan_bus(u8_t busnr); +const char *_pci_dev_name(u16_t vid, u16_t did); + + +int _pci_get_bar(int devind, int port, u32_t *base, u32_t *size, int *ioflag); -int pci_slot_name_s(int devind, char **cpp); -int pci_ids_s(int devind, u16_t *vidp, u16_t *didp); +int _pci_slot_name(int devind, char **cpp); +int _pci_ids(int devind, u16_t *vidp, u16_t *didp); -/* - * $PchId: pci.h,v 1.4 2001/12/06 20:21:22 philip Exp $ - */ +/* PCI Config Read functions */ +int _pci_attr_r8(int devind, int port, u8_t *vp); +int _pci_attr_r16(int devind, int port, u16_t *vp); +int _pci_attr_r32(int devind, int port, u32_t *vp); + +/* PCI Config Write functions */ +int _pci_attr_w8(int devind, int port, u8_t value); +int _pci_attr_w16(int devind, int port, u16_t value); +int _pci_attr_w32(int devind, int port, u32_t value); diff --git a/minix/drivers/bus/pci/pci_table.c b/minix/drivers/bus/pci/pci_table.c index e468f2948..3182282ee 100644 --- a/minix/drivers/bus/pci/pci_table.c +++ b/minix/drivers/bus/pci/pci_table.c @@ -14,10 +14,9 @@ See the Linux PCI ID Repository . */ #include +#include + #include "pci.h" -#if __minix_vmd -#include "config.h" -#endif struct pci_vendor pci_vendor_table[]= {