Index: head/sys/amd64/amd64/genassym.c =================================================================== --- head/sys/amd64/amd64/genassym.c (revision 84614) +++ head/sys/amd64/amd64/genassym.c (revision 84615) @@ -1,217 +1,224 @@ /*- * Copyright (c) 1982, 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 * $FreeBSD$ */ #include "opt_kstack_pages.h" #include #include #include #include #include #include #include #include #include #include #include #include /* XXX */ #ifdef KTR_PERCPU #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef SMP #include #endif #include #include #include #include ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap)); ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); ASSYM(P_SFLAG, offsetof(struct proc, p_sflag)); ASSYM(P_STAT, offsetof(struct proc, p_stat)); ASSYM(P_UAREA, offsetof(struct proc, p_uarea)); /*ASSYM(TD_STAT, offsetof(struct thread, td__stat));*/ ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_WCHAN, offsetof(struct thread, td_wchan)); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_KSE, offsetof(struct thread, td_kse)); ASSYM(TD_PROC, offsetof(struct thread, td_proc)); ASSYM(TD_INTR_NESTING_LEVEL, offsetof(struct thread, td_intr_nesting_level)); ASSYM(KE_FLAGS, offsetof(struct kse, ke_flags)); ASSYM(KEF_ASTPENDING, KEF_ASTPENDING); ASSYM(KEF_NEEDRESCHED, KEF_NEEDRESCHED); ASSYM(SSLEEP, SSLEEP); ASSYM(SRUN, SRUN); ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap)); ASSYM(V_SYSCALL, offsetof(struct vmmeter, v_syscall)); ASSYM(V_INTR, offsetof(struct vmmeter, v_intr)); /* ASSYM(UPAGES, UPAGES);*/ ASSYM(UAREA_PAGES, UAREA_PAGES); ASSYM(KSTACK_PAGES, KSTACK_PAGES); ASSYM(PAGE_SIZE, PAGE_SIZE); ASSYM(NPTEPG, NPTEPG); ASSYM(NPDEPG, NPDEPG); ASSYM(PDESIZE, PDESIZE); ASSYM(PTESIZE, PTESIZE); ASSYM(PAGE_SHIFT, PAGE_SHIFT); ASSYM(PAGE_MASK, PAGE_MASK); ASSYM(PDRSHIFT, PDRSHIFT); ASSYM(USRSTACK, USRSTACK); ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); ASSYM(KERNBASE, KERNBASE); ASSYM(MCLBYTES, MCLBYTES); ASSYM(PCB_CR3, offsetof(struct pcb, pcb_cr3)); ASSYM(PCB_EDI, offsetof(struct pcb, pcb_edi)); ASSYM(PCB_ESI, offsetof(struct pcb, pcb_esi)); ASSYM(PCB_EBP, offsetof(struct pcb, pcb_ebp)); ASSYM(PCB_ESP, offsetof(struct pcb, pcb_esp)); ASSYM(PCB_EBX, offsetof(struct pcb, pcb_ebx)); ASSYM(PCB_EIP, offsetof(struct pcb, pcb_eip)); ASSYM(TSS_ESP0, offsetof(struct i386tss, tss_esp0)); ASSYM(PCB_USERLDT, offsetof(struct pcb, pcb_ldt)); ASSYM(PCB_GS, offsetof(struct pcb, pcb_gs)); ASSYM(PCB_DR0, offsetof(struct pcb, pcb_dr0)); ASSYM(PCB_DR1, offsetof(struct pcb, pcb_dr1)); ASSYM(PCB_DR2, offsetof(struct pcb, pcb_dr2)); ASSYM(PCB_DR3, offsetof(struct pcb, pcb_dr3)); ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6)); ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7)); ASSYM(PCB_DBREGS, PCB_DBREGS); ASSYM(PCB_EXT, offsetof(struct pcb, pcb_ext)); ASSYM(PCB_SPARE, offsetof(struct pcb, __pcb_spare)); ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save)); ASSYM(PCB_SAVEFPU_SIZE, sizeof(union savefpu)); ASSYM(PCB_SAVE87_SIZE, sizeof(struct save87)); ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); ASSYM(PCB_SIZE, sizeof(struct pcb)); ASSYM(TF_TRAPNO, offsetof(struct trapframe, tf_trapno)); ASSYM(TF_ERR, offsetof(struct trapframe, tf_err)); ASSYM(TF_CS, offsetof(struct trapframe, tf_cs)); ASSYM(TF_EFLAGS, offsetof(struct trapframe, tf_eflags)); ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler)); ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc)); ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); ASSYM(SC_PS, offsetof(struct osigcontext, sc_ps)); ASSYM(SC_FS, offsetof(struct osigcontext, sc_fs)); ASSYM(SC_GS, offsetof(struct osigcontext, sc_gs)); ASSYM(SC_TRAPNO, offsetof(struct osigcontext, sc_trapno)); ASSYM(UC_EFLAGS, offsetof(ucontext_t, uc_mcontext.mc_eflags)); ASSYM(UC_GS, offsetof(ucontext_t, uc_mcontext.mc_gs)); ASSYM(ENOENT, ENOENT); ASSYM(EFAULT, EFAULT); ASSYM(ENAMETOOLONG, ENAMETOOLONG); ASSYM(MAXPATHLEN, MAXPATHLEN); ASSYM(BOOTINFO_SIZE, sizeof(struct bootinfo)); ASSYM(BI_VERSION, offsetof(struct bootinfo, bi_version)); ASSYM(BI_KERNELNAME, offsetof(struct bootinfo, bi_kernelname)); ASSYM(BI_NFS_DISKLESS, offsetof(struct bootinfo, bi_nfs_diskless)); ASSYM(BI_ENDCOMMON, offsetof(struct bootinfo, bi_endcommon)); ASSYM(NFSDISKLESS_SIZE, sizeof(struct nfs_diskless)); ASSYM(BI_SIZE, offsetof(struct bootinfo, bi_size)); ASSYM(BI_SYMTAB, offsetof(struct bootinfo, bi_symtab)); ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab)); ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend)); ASSYM(GD_SIZEOF, sizeof(struct globaldata)); ASSYM(GD_PRVSPACE, offsetof(struct globaldata, gd_prvspace)); ASSYM(GD_CURTHREAD, offsetof(struct globaldata, gd_curthread)); ASSYM(GD_NPXTHREAD, offsetof(struct globaldata, gd_npxthread)); ASSYM(GD_IDLETHREAD, offsetof(struct globaldata, gd_idlethread)); ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); ASSYM(GD_COMMON_TSS, offsetof(struct globaldata, gd_common_tss)); ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime)); ASSYM(GD_SWITCHTICKS, offsetof(struct globaldata, gd_switchticks)); ASSYM(GD_COMMON_TSSD, offsetof(struct globaldata, gd_common_tssd)); ASSYM(GD_TSS_GDT, offsetof(struct globaldata, gd_tss_gdt)); ASSYM(GD_CURRENTLDT, offsetof(struct globaldata, gd_currentldt)); /* XXX */ #ifdef KTR_PERCPU ASSYM(GD_KTR_IDX, offsetof(struct globaldata, gd_ktr_idx)); ASSYM(GD_KTR_BUF, offsetof(struct globaldata, gd_ktr_buf)); ASSYM(GD_KTR_BUF_DATA, offsetof(struct globaldata, gd_ktr_buf_data)); #endif ASSYM(GD_CPUID, offsetof(struct globaldata, gd_cpuid)); #ifdef SMP ASSYM(LA_VER, offsetof(struct LAPIC, version)); ASSYM(LA_TPR, offsetof(struct LAPIC, tpr)); ASSYM(LA_EOI, offsetof(struct LAPIC, eoi)); ASSYM(LA_SVR, offsetof(struct LAPIC, svr)); ASSYM(LA_ICR_LO, offsetof(struct LAPIC, icr_lo)); ASSYM(LA_ICR_HI, offsetof(struct LAPIC, icr_hi)); #endif ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL)); ASSYM(KDSEL, GSEL(GDATA_SEL, SEL_KPL)); ASSYM(KPSEL, GSEL(GPRIV_SEL, SEL_KPL)); ASSYM(BC32SEL, GSEL(GBIOSCODE32_SEL, SEL_KPL)); ASSYM(GPROC0_SEL, GPROC0_SEL); ASSYM(VM86_FRAMESIZE, sizeof(struct vm86frame)); ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock)); ASSYM(MTX_RECURSECNT, offsetof(struct mtx, mtx_recurse)); ASSYM(MTX_SAVECRIT, offsetof(struct mtx, mtx_savecrit)); + +#ifdef PC98 +#include + +ASSYM(BUS_SPACE_HANDLE_BASE, offsetof(struct bus_space_handle, bsh_base)); +ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat)); +#endif Index: head/sys/amd64/amd64/legacy.c =================================================================== --- head/sys/amd64/amd64/legacy.c (revision 84614) +++ head/sys/amd64/amd64/legacy.c (revision 84615) @@ -1,679 +1,685 @@ /* * Copyright 1998 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * This code implements a `root nexus' for Intel Architecture * machines. The function of the root nexus is to serve as an * attachment point for both processors and buses, and to manage * resources which are common to all of them. In particular, * this code implements the core resource managers for interrupt * requests, DMA requests (which rightfully should be a part of the * ISA code but it's easier to do it here for now), I/O port addresses, * and I/O memory address space. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef APIC_IO #include #include #endif #include #ifdef PC98 #include #else #include #endif #include #include #include #ifdef PC98 static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle"); #endif static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); struct nexus_device { struct resource_list nx_resources; int nx_pcibus; }; #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static int nexus_attach(device_t); static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format); static int nexus_print_all_resources(device_t dev); static int nexus_print_child(device_t, device_t); static device_t nexus_add_child(device_t bus, int order, const char *name, int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); static int nexus_write_ivar(device_t, device_t, int, uintptr_t); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, struct resource *); static int nexus_release_resource(device_t, device_t, int, int, struct resource *); static int nexus_setup_intr(device_t, device_t, struct resource *, int flags, void (*)(void *), void *, void **); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); static void nexus_delete_resource(device_t, device_t, int, int); static device_method_t nexus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nexus_probe), DEVMETHOD(device_attach, nexus_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, nexus_read_ivar), DEVMETHOD(bus_write_ivar, nexus_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), DEVMETHOD(bus_delete_resource, nexus_delete_resource), { 0, 0 } }; static driver_t nexus_driver = { "nexus", nexus_methods, 1, /* no softc */ }; static devclass_t nexus_devclass; DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); static int nexus_probe(device_t dev) { device_quiet(dev); /* suppress attach message for neatness */ /* * XXX working notes: * * - IRQ resource creation should be moved to the PIC/APIC driver. * - DRQ resource creation should be moved to the DMAC driver. * - The above should be sorted to probe earlier than any child busses. * * - Leave I/O and memory creation here, as child probes may need them. * (especially eg. ACPI) */ /* * IRQ's are on the mainboard on old systems, but on the ISA part * of PCI->ISA bridges. There would be multiple sets of IRQs on * multi-ISA-bus systems. PCI interrupts are routed to the ISA * component, so in a way, PCI can be a partial child of an ISA bus(!). * APIC interrupts are global though. * * XXX We depend on the AT PIC driver correctly claiming IRQ 2 * to prevent its reuse elsewhere in the !APIC_IO case. */ irq_rman.rm_start = 0; irq_rman.rm_type = RMAN_ARRAY; irq_rman.rm_descr = "Interrupt request lines"; #ifdef APIC_IO irq_rman.rm_end = APIC_INTMAPSIZE - 1; #else irq_rman.rm_end = 15; #endif if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, irq_rman.rm_start, irq_rman.rm_end)) panic("nexus_probe irq_rman"); /* * ISA DMA on PCI systems is implemented in the ISA part of each * PCI->ISA bridge and the channels can be duplicated if there are * multiple bridges. (eg: laptops with docking stations) */ drq_rman.rm_start = 0; #ifdef PC98 drq_rman.rm_end = 3; #else drq_rman.rm_end = 7; #endif drq_rman.rm_type = RMAN_ARRAY; drq_rman.rm_descr = "DMA request lines"; /* XXX drq 0 not available on some machines */ if (rman_init(&drq_rman) || rman_manage_region(&drq_rman, drq_rman.rm_start, drq_rman.rm_end)) panic("nexus_probe drq_rman"); /* * However, IO ports and Memory truely are global at this level, * as are APIC interrupts (however many IO APICS there turn out * to be on large systems..) */ port_rman.rm_start = 0; port_rman.rm_end = 0xffff; port_rman.rm_type = RMAN_ARRAY; port_rman.rm_descr = "I/O ports"; if (rman_init(&port_rman) || rman_manage_region(&port_rman, 0, 0xffff)) panic("nexus_probe port_rman"); mem_rman.rm_start = 0; mem_rman.rm_end = ~0u; mem_rman.rm_type = RMAN_ARRAY; mem_rman.rm_descr = "I/O memory addresses"; if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0)) panic("nexus_probe mem_rman"); return bus_generic_probe(dev); } static int nexus_attach(device_t dev) { device_t child; /* * First, deal with the children we know about already */ bus_generic_attach(dev); /* * And if we didn't see EISA or ISA on a pci bridge, create some * connection points now so they show up "on motherboard". */ if (!devclass_get_device(devclass_find("eisa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "eisa", 0); if (child == NULL) panic("nexus_attach eisa"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("mca"), 0)) { child = BUS_ADD_CHILD(dev, 0, "mca", 0); if (child == 0) panic("nexus_probe mca"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("isa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "isa", 0); if (child == NULL) panic("nexus_attach isa"); device_probe_and_attach(child); } return 0; } static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format) { struct resource_list_entry *rle; int printed, retval; printed = 0; retval = 0; /* Yes, this is kinda cheating */ SLIST_FOREACH(rle, rl, link) { if (rle->type == type) { if (printed == 0) retval += printf(" %s ", name); else if (printed > 0) retval += printf(","); printed++; retval += printf(format, rle->start); if (rle->count > 1) { retval += printf("-"); retval += printf(format, rle->start + rle->count - 1); } } } return retval; } static int nexus_print_all_resources(device_t dev) { struct nexus_device *ndev = DEVTONX(dev); struct resource_list *rl = &ndev->nx_resources; int retval = 0; if (SLIST_FIRST(rl) || ndev->nx_pcibus != -1) retval += printf(" at"); retval += nexus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); retval += nexus_print_resources(rl, "iomem", SYS_RES_MEMORY, "%#lx"); retval += nexus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); return retval; } static int nexus_print_child(device_t bus, device_t child) { struct nexus_device *ndev = DEVTONX(child); int retval = 0; retval += bus_print_child_header(bus, child); retval += nexus_print_all_resources(child); if (ndev->nx_pcibus != -1) retval += printf(" pcibus %d", ndev->nx_pcibus); retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */ return (retval); } static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { device_t child; struct nexus_device *ndev; ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); if (!ndev) return(0); resource_list_init(&ndev->nx_resources); ndev->nx_pcibus = -1; child = device_add_child_ordered(bus, order, name, unit); /* should we free this in nexus_child_detached? */ device_set_ivars(child, ndev); return(child); } static int nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: *result = ndev->nx_pcibus; break; default: return ENOENT; } return 0; } static int nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: ndev->nx_pcibus = value; break; default: return ENOENT; } return 0; } /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. * (Exceptions include npx.) */ static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct nexus_device *ndev = DEVTONX(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int needactivate = flags & RF_ACTIVE; /* * If this is an allocation of the "default" range for a given RID, and * we know what the resources for this device are (ie. they aren't maintained * by a child bus), then work out the start/end values. */ if ((start == 0UL) && (end == ~0UL) && (count == 1)) { if (ndev == NULL) return(NULL); rle = resource_list_find(&ndev->nx_resources, type, *rid); if (rle == NULL) return(NULL); start = rle->start; end = rle->end; count = rle->count; } flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_IRQ: rm = &irq_rman; break; case SYS_RES_DRQ: rm = &drq_rman; break; case SYS_RES_IOPORT: rm = &port_rman; break; case SYS_RES_MEMORY: rm = &mem_rman; break; default: return 0; } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) return 0; #ifdef PC98 /* Allocate bushandle. */ rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE, M_NOWAIT | M_ZERO); if (rv->r_bushandle == 0) { rman_release_resource(rv); return 0; } #endif if (type == SYS_RES_MEMORY) { rman_set_bustag(rv, I386_BUS_SPACE_MEM); } else if (type == SYS_RES_IOPORT) { rman_set_bustag(rv, I386_BUS_SPACE_IO); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ rv->r_bushandle->bsh_base = rv->r_start; - rv->r_bushandle->bsh_iat = NULL; + rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; rv->r_bushandle->bsh_iatsz = 0; rv->r_bushandle->bsh_res = NULL; rv->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(rv, rv->r_start); #endif } if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { #ifdef PC98 free(rv->r_bushandle, M_BUSSPACEHANDLE); #endif rman_release_resource(rv); return 0; } } return rv; } static int nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, map it into the kernel. */ if (rman_get_bustag(r) == I386_BUS_SPACE_MEM) { caddr_t vaddr = 0; if (rman_get_end(r) < 1024 * 1024) { /* * The first 1Mb is mapped at KERNBASE. */ vaddr = (caddr_t)(uintptr_t)(KERNBASE + rman_get_start(r)); } else { u_int32_t paddr; u_int32_t psize; u_int32_t poffs; paddr = rman_get_start(r); psize = rman_get_size(r); poffs = paddr - trunc_page(paddr); vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; } rman_set_virtual(r, vaddr); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ r->r_bushandle->bsh_base = (bus_addr_t) vaddr; - r->r_bushandle->bsh_iat = NULL; + r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; r->r_bushandle->bsh_iatsz = 0; r->r_bushandle->bsh_res = NULL; r->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + r->r_bushandle->bsh_bam = r->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(r, (bus_space_handle_t) vaddr); #endif } return (rman_activate_resource(r)); } static int nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, unmap it. */ if ((rman_get_bustag(r) == I386_BUS_SPACE_MEM) && (rman_get_end(r) >= 1024 * 1024)) { u_int32_t psize; psize = rman_get_size(r); pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize); } return (rman_deactivate_resource(r)); } static int nexus_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { if (rman_get_flags(r) & RF_ACTIVE) { int error = bus_deactivate_resource(child, type, rid, r); if (error) return error; } #ifdef PC98 free(r->r_bushandle, M_BUSSPACEHANDLE); #endif return (rman_release_resource(r)); } /* * Currently this uses the really grody interface from kern/kern_intr.c * (which really doesn't belong in kern/anything.c). Eventually, all of * the code in kern_intr.c and machdep_intr.c should get moved here, since * this is going to be the official interface. */ static int nexus_setup_intr(device_t bus, device_t child, struct resource *irq, int flags, void (*ihand)(void *), void *arg, void **cookiep) { driver_t *driver; int error; /* somebody tried to setup an irq that failed to allocate! */ if (irq == NULL) panic("nexus_setup_intr: NULL irq resource!"); *cookiep = 0; if ((irq->r_flags & RF_SHAREABLE) == 0) flags |= INTR_EXCL; driver = device_get_driver(child); /* * We depend here on rman_activate_resource() being idempotent. */ error = rman_activate_resource(irq); if (error) return (error); error = inthand_add(device_get_nameunit(child), irq->r_start, ihand, arg, flags, cookiep); return (error); } static int nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) { return (inthand_remove(ih)); } static int nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; /* XXX this should return a success/failure indicator */ resource_list_add(rl, type, rid, start, start + count - 1, count); return(0); } static int nexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; struct resource_list_entry *rle; rle = resource_list_find(rl, type, rid); device_printf(child, "type %d rid %d startp %p countp %p - got %p\n", type, rid, startp, countp, rle); if (!rle) return(ENOENT); if (startp) *startp = rle->start; if (countp) *countp = rle->count; return(0); } static void nexus_delete_resource(device_t dev, device_t child, int type, int rid) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; resource_list_delete(rl, type, rid); } /* * Placeholder which claims PnP 'devices' which describe system * resources. */ static struct isa_pnp_id sysresource_ids[] = { { 0x010cd041 /* PNP0c01 */, "System Memory" }, { 0x020cd041 /* PNP0c02 */, "System Resource" }, { 0 } }; static int sysresource_probe(device_t dev) { int result; if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) { device_quiet(dev); } return(result); } static int sysresource_attach(device_t dev) { return(0); } static device_method_t sysresource_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sysresource_probe), DEVMETHOD(device_attach, sysresource_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), { 0, 0 } }; static driver_t sysresource_driver = { "sysresource", sysresource_methods, 1, /* no softc */ }; static devclass_t sysresource_devclass; DRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0); Index: head/sys/amd64/amd64/nexus.c =================================================================== --- head/sys/amd64/amd64/nexus.c (revision 84614) +++ head/sys/amd64/amd64/nexus.c (revision 84615) @@ -1,679 +1,685 @@ /* * Copyright 1998 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * This code implements a `root nexus' for Intel Architecture * machines. The function of the root nexus is to serve as an * attachment point for both processors and buses, and to manage * resources which are common to all of them. In particular, * this code implements the core resource managers for interrupt * requests, DMA requests (which rightfully should be a part of the * ISA code but it's easier to do it here for now), I/O port addresses, * and I/O memory address space. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef APIC_IO #include #include #endif #include #ifdef PC98 #include #else #include #endif #include #include #include #ifdef PC98 static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle"); #endif static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); struct nexus_device { struct resource_list nx_resources; int nx_pcibus; }; #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static int nexus_attach(device_t); static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format); static int nexus_print_all_resources(device_t dev); static int nexus_print_child(device_t, device_t); static device_t nexus_add_child(device_t bus, int order, const char *name, int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); static int nexus_write_ivar(device_t, device_t, int, uintptr_t); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, struct resource *); static int nexus_release_resource(device_t, device_t, int, int, struct resource *); static int nexus_setup_intr(device_t, device_t, struct resource *, int flags, void (*)(void *), void *, void **); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); static void nexus_delete_resource(device_t, device_t, int, int); static device_method_t nexus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nexus_probe), DEVMETHOD(device_attach, nexus_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, nexus_read_ivar), DEVMETHOD(bus_write_ivar, nexus_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), DEVMETHOD(bus_delete_resource, nexus_delete_resource), { 0, 0 } }; static driver_t nexus_driver = { "nexus", nexus_methods, 1, /* no softc */ }; static devclass_t nexus_devclass; DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); static int nexus_probe(device_t dev) { device_quiet(dev); /* suppress attach message for neatness */ /* * XXX working notes: * * - IRQ resource creation should be moved to the PIC/APIC driver. * - DRQ resource creation should be moved to the DMAC driver. * - The above should be sorted to probe earlier than any child busses. * * - Leave I/O and memory creation here, as child probes may need them. * (especially eg. ACPI) */ /* * IRQ's are on the mainboard on old systems, but on the ISA part * of PCI->ISA bridges. There would be multiple sets of IRQs on * multi-ISA-bus systems. PCI interrupts are routed to the ISA * component, so in a way, PCI can be a partial child of an ISA bus(!). * APIC interrupts are global though. * * XXX We depend on the AT PIC driver correctly claiming IRQ 2 * to prevent its reuse elsewhere in the !APIC_IO case. */ irq_rman.rm_start = 0; irq_rman.rm_type = RMAN_ARRAY; irq_rman.rm_descr = "Interrupt request lines"; #ifdef APIC_IO irq_rman.rm_end = APIC_INTMAPSIZE - 1; #else irq_rman.rm_end = 15; #endif if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, irq_rman.rm_start, irq_rman.rm_end)) panic("nexus_probe irq_rman"); /* * ISA DMA on PCI systems is implemented in the ISA part of each * PCI->ISA bridge and the channels can be duplicated if there are * multiple bridges. (eg: laptops with docking stations) */ drq_rman.rm_start = 0; #ifdef PC98 drq_rman.rm_end = 3; #else drq_rman.rm_end = 7; #endif drq_rman.rm_type = RMAN_ARRAY; drq_rman.rm_descr = "DMA request lines"; /* XXX drq 0 not available on some machines */ if (rman_init(&drq_rman) || rman_manage_region(&drq_rman, drq_rman.rm_start, drq_rman.rm_end)) panic("nexus_probe drq_rman"); /* * However, IO ports and Memory truely are global at this level, * as are APIC interrupts (however many IO APICS there turn out * to be on large systems..) */ port_rman.rm_start = 0; port_rman.rm_end = 0xffff; port_rman.rm_type = RMAN_ARRAY; port_rman.rm_descr = "I/O ports"; if (rman_init(&port_rman) || rman_manage_region(&port_rman, 0, 0xffff)) panic("nexus_probe port_rman"); mem_rman.rm_start = 0; mem_rman.rm_end = ~0u; mem_rman.rm_type = RMAN_ARRAY; mem_rman.rm_descr = "I/O memory addresses"; if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0)) panic("nexus_probe mem_rman"); return bus_generic_probe(dev); } static int nexus_attach(device_t dev) { device_t child; /* * First, deal with the children we know about already */ bus_generic_attach(dev); /* * And if we didn't see EISA or ISA on a pci bridge, create some * connection points now so they show up "on motherboard". */ if (!devclass_get_device(devclass_find("eisa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "eisa", 0); if (child == NULL) panic("nexus_attach eisa"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("mca"), 0)) { child = BUS_ADD_CHILD(dev, 0, "mca", 0); if (child == 0) panic("nexus_probe mca"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("isa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "isa", 0); if (child == NULL) panic("nexus_attach isa"); device_probe_and_attach(child); } return 0; } static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format) { struct resource_list_entry *rle; int printed, retval; printed = 0; retval = 0; /* Yes, this is kinda cheating */ SLIST_FOREACH(rle, rl, link) { if (rle->type == type) { if (printed == 0) retval += printf(" %s ", name); else if (printed > 0) retval += printf(","); printed++; retval += printf(format, rle->start); if (rle->count > 1) { retval += printf("-"); retval += printf(format, rle->start + rle->count - 1); } } } return retval; } static int nexus_print_all_resources(device_t dev) { struct nexus_device *ndev = DEVTONX(dev); struct resource_list *rl = &ndev->nx_resources; int retval = 0; if (SLIST_FIRST(rl) || ndev->nx_pcibus != -1) retval += printf(" at"); retval += nexus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); retval += nexus_print_resources(rl, "iomem", SYS_RES_MEMORY, "%#lx"); retval += nexus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); return retval; } static int nexus_print_child(device_t bus, device_t child) { struct nexus_device *ndev = DEVTONX(child); int retval = 0; retval += bus_print_child_header(bus, child); retval += nexus_print_all_resources(child); if (ndev->nx_pcibus != -1) retval += printf(" pcibus %d", ndev->nx_pcibus); retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */ return (retval); } static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { device_t child; struct nexus_device *ndev; ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); if (!ndev) return(0); resource_list_init(&ndev->nx_resources); ndev->nx_pcibus = -1; child = device_add_child_ordered(bus, order, name, unit); /* should we free this in nexus_child_detached? */ device_set_ivars(child, ndev); return(child); } static int nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: *result = ndev->nx_pcibus; break; default: return ENOENT; } return 0; } static int nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: ndev->nx_pcibus = value; break; default: return ENOENT; } return 0; } /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. * (Exceptions include npx.) */ static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct nexus_device *ndev = DEVTONX(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int needactivate = flags & RF_ACTIVE; /* * If this is an allocation of the "default" range for a given RID, and * we know what the resources for this device are (ie. they aren't maintained * by a child bus), then work out the start/end values. */ if ((start == 0UL) && (end == ~0UL) && (count == 1)) { if (ndev == NULL) return(NULL); rle = resource_list_find(&ndev->nx_resources, type, *rid); if (rle == NULL) return(NULL); start = rle->start; end = rle->end; count = rle->count; } flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_IRQ: rm = &irq_rman; break; case SYS_RES_DRQ: rm = &drq_rman; break; case SYS_RES_IOPORT: rm = &port_rman; break; case SYS_RES_MEMORY: rm = &mem_rman; break; default: return 0; } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) return 0; #ifdef PC98 /* Allocate bushandle. */ rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE, M_NOWAIT | M_ZERO); if (rv->r_bushandle == 0) { rman_release_resource(rv); return 0; } #endif if (type == SYS_RES_MEMORY) { rman_set_bustag(rv, I386_BUS_SPACE_MEM); } else if (type == SYS_RES_IOPORT) { rman_set_bustag(rv, I386_BUS_SPACE_IO); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ rv->r_bushandle->bsh_base = rv->r_start; - rv->r_bushandle->bsh_iat = NULL; + rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; rv->r_bushandle->bsh_iatsz = 0; rv->r_bushandle->bsh_res = NULL; rv->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(rv, rv->r_start); #endif } if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { #ifdef PC98 free(rv->r_bushandle, M_BUSSPACEHANDLE); #endif rman_release_resource(rv); return 0; } } return rv; } static int nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, map it into the kernel. */ if (rman_get_bustag(r) == I386_BUS_SPACE_MEM) { caddr_t vaddr = 0; if (rman_get_end(r) < 1024 * 1024) { /* * The first 1Mb is mapped at KERNBASE. */ vaddr = (caddr_t)(uintptr_t)(KERNBASE + rman_get_start(r)); } else { u_int32_t paddr; u_int32_t psize; u_int32_t poffs; paddr = rman_get_start(r); psize = rman_get_size(r); poffs = paddr - trunc_page(paddr); vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; } rman_set_virtual(r, vaddr); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ r->r_bushandle->bsh_base = (bus_addr_t) vaddr; - r->r_bushandle->bsh_iat = NULL; + r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; r->r_bushandle->bsh_iatsz = 0; r->r_bushandle->bsh_res = NULL; r->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + r->r_bushandle->bsh_bam = r->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(r, (bus_space_handle_t) vaddr); #endif } return (rman_activate_resource(r)); } static int nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, unmap it. */ if ((rman_get_bustag(r) == I386_BUS_SPACE_MEM) && (rman_get_end(r) >= 1024 * 1024)) { u_int32_t psize; psize = rman_get_size(r); pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize); } return (rman_deactivate_resource(r)); } static int nexus_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { if (rman_get_flags(r) & RF_ACTIVE) { int error = bus_deactivate_resource(child, type, rid, r); if (error) return error; } #ifdef PC98 free(r->r_bushandle, M_BUSSPACEHANDLE); #endif return (rman_release_resource(r)); } /* * Currently this uses the really grody interface from kern/kern_intr.c * (which really doesn't belong in kern/anything.c). Eventually, all of * the code in kern_intr.c and machdep_intr.c should get moved here, since * this is going to be the official interface. */ static int nexus_setup_intr(device_t bus, device_t child, struct resource *irq, int flags, void (*ihand)(void *), void *arg, void **cookiep) { driver_t *driver; int error; /* somebody tried to setup an irq that failed to allocate! */ if (irq == NULL) panic("nexus_setup_intr: NULL irq resource!"); *cookiep = 0; if ((irq->r_flags & RF_SHAREABLE) == 0) flags |= INTR_EXCL; driver = device_get_driver(child); /* * We depend here on rman_activate_resource() being idempotent. */ error = rman_activate_resource(irq); if (error) return (error); error = inthand_add(device_get_nameunit(child), irq->r_start, ihand, arg, flags, cookiep); return (error); } static int nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) { return (inthand_remove(ih)); } static int nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; /* XXX this should return a success/failure indicator */ resource_list_add(rl, type, rid, start, start + count - 1, count); return(0); } static int nexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; struct resource_list_entry *rle; rle = resource_list_find(rl, type, rid); device_printf(child, "type %d rid %d startp %p countp %p - got %p\n", type, rid, startp, countp, rle); if (!rle) return(ENOENT); if (startp) *startp = rle->start; if (countp) *countp = rle->count; return(0); } static void nexus_delete_resource(device_t dev, device_t child, int type, int rid) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; resource_list_delete(rl, type, rid); } /* * Placeholder which claims PnP 'devices' which describe system * resources. */ static struct isa_pnp_id sysresource_ids[] = { { 0x010cd041 /* PNP0c01 */, "System Memory" }, { 0x020cd041 /* PNP0c02 */, "System Resource" }, { 0 } }; static int sysresource_probe(device_t dev) { int result; if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) { device_quiet(dev); } return(result); } static int sysresource_attach(device_t dev) { return(0); } static device_method_t sysresource_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sysresource_probe), DEVMETHOD(device_attach, sysresource_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), { 0, 0 } }; static driver_t sysresource_driver = { "sysresource", sysresource_methods, 1, /* no softc */ }; static devclass_t sysresource_devclass; DRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0); Index: head/sys/amd64/isa/isa.c =================================================================== --- head/sys/amd64/isa/isa.c (revision 84614) +++ head/sys/amd64/isa/isa.c (revision 84615) @@ -1,261 +1,264 @@ /*- * Copyright (c) 1998 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Modifications for Intel architecture by Garrett A. Wollman. * Copyright 1998 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include void isa_init(void) { } /* * This implementation simply passes the request up to the parent * bus, which in our case is the special i386 nexus, substituting any * configured values if the caller defaulted. We can get away with * this because there is no special mapping for ISA resources on an Intel * platform. When porting this code to another architecture, it may be * necessary to interpose a mapping layer here. */ struct resource * isa_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { /* * Consider adding a resource definition. We allow rid 0-1 for * irq and drq, 0-3 for memory and 0-7 for ports which is * sufficient for isapnp. */ int passthrough = (device_get_parent(child) != bus); int isdefault = (start == 0UL && end == ~0UL); struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; struct resource_list_entry *rle; if (!passthrough && !isdefault) { rle = resource_list_find(rl, type, *rid); if (!rle) { if (*rid < 0) return 0; switch (type) { case SYS_RES_IRQ: if (*rid >= ISA_NIRQ) return 0; break; case SYS_RES_DRQ: if (*rid >= ISA_NDRQ) return 0; break; case SYS_RES_MEMORY: if (*rid >= ISA_NMEM) return 0; break; case SYS_RES_IOPORT: if (*rid >= ISA_NPORT) return 0; break; default: return 0; } resource_list_add(rl, type, *rid, start, end, count); } } return resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags); } #ifdef PC98 /* * Indirection support. The type of bus_space_handle_t is * defined in sys/i386/include/bus_pc98.h. */ struct resource * isa_alloc_resourcev(device_t child, int type, int *rid, bus_addr_t *res, bus_size_t count, u_int flags) { struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; device_t bus = device_get_parent(child); bus_addr_t start; struct resource *re; struct resource **bsre; int i, j, k, linear_cnt, ressz, bsrid; start = bus_get_resource_start(child, type, *rid); linear_cnt = count; ressz = 1; for (i = 1; i < count; ++i) { if (res[i] != res[i - 1] + 1) { if (i < linear_cnt) linear_cnt = i; ++ressz; } } re = isa_alloc_resource(bus, child, type, rid, start + res[0], start + res[linear_cnt - 1], linear_cnt, flags); if (re == NULL) return NULL; bsre = malloc(sizeof (struct resource *) * ressz, M_DEVBUF, M_NOWAIT); if (bsre == NULL) { resource_list_release(rl, bus, child, type, *rid, re); return NULL; } bsre[0] = re; for (i = linear_cnt, k = 1; i < count; i = j, k++) { for (j = i + 1; j < count; j++) { if (res[j] != res[j - 1] + 1) break; } bsrid = *rid + k; bsre[k] = isa_alloc_resource(bus, child, type, &bsrid, start + res[i], start + res[j - 1], j - i, flags); if (bsre[k] == NULL) { for (k--; k >= 0; k--) resource_list_release(rl, bus, child, type, *rid + k, bsre[k]); free(bsre, M_DEVBUF); return NULL; } } re->r_bushandle->bsh_res = bsre; re->r_bushandle->bsh_ressz = ressz; return re; } int isa_load_resourcev(struct resource *re, bus_addr_t *res, bus_size_t count) { - bus_addr_t *addr; + bus_addr_t start; int i; - addr = malloc(sizeof (bus_addr_t) * count, M_DEVBUF, M_NOWAIT); - if (addr == NULL) - return 1; + if (count > re->r_bushandle->bsh_maxiatsz) { + printf("isa_load_resourcev: map size too large\n"); + return EINVAL; + } - for (i = 0; i < count; i++) - addr[i] = rman_get_start(re) + res[i]; + start = rman_get_start(re); + for (i = 0; i < re->r_bushandle->bsh_maxiatsz; i++) { + if (i < count) + re->r_bushandle->bsh_iat[i] = start + res[i]; + else + re->r_bushandle->bsh_iat[i] = start; + } - rman_set_bustag(re, I386_BUS_SPACE_IO_IND); - re->r_bushandle->bsh_iat = addr; re->r_bushandle->bsh_iatsz = count; + re->r_bushandle->bsh_bam = re->r_bustag->bs_ra; /* relocate access */ return 0; } #endif /* PC98 */ int isa_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; #ifdef PC98 /* * Indirection support. The type of bus_space_handle_t is * defined in sys/i386/include/bus_pc98.h. */ int i; for (i = 1; i < r->r_bushandle->bsh_ressz; i++) resource_list_release(rl, bus, child, type, rid + i, r->r_bushandle->bsh_res[i]); if (r->r_bushandle->bsh_res != NULL) free(r->r_bushandle->bsh_res, M_DEVBUF); - if (r->r_bushandle->bsh_iat != NULL) - free(r->r_bushandle->bsh_iat, M_DEVBUF); #endif return resource_list_release(rl, bus, child, type, rid, r); } /* * We can't use the bus_generic_* versions of these methods because those * methods always pass the bus param as the requesting device, and we need * to pass the child (the i386 nexus knows about this and is prepared to * deal). */ int isa_setup_intr(device_t bus, device_t child, struct resource *r, int flags, void (*ihand)(void *), void *arg, void **cookiep) { return (BUS_SETUP_INTR(device_get_parent(bus), child, r, flags, ihand, arg, cookiep)); } int isa_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie) { return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie)); } Index: head/sys/conf/files.pc98 =================================================================== --- head/sys/conf/files.pc98 (revision 84614) +++ head/sys/conf/files.pc98 (revision 84615) @@ -1,409 +1,411 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # # modified for PC-9801 # # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # linux_genassym.o optional compat_linux \ dependency "$S/i386/linux/linux_genassym.c" \ compile-with "${CC} ${CFLAGS} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "linux_genassym.o" # linux_assym.h optional compat_linux \ dependency "$S/kern/genassym.sh linux_genassym.o" \ compile-with "sh $S/kern/genassym.sh linux_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # svr4_genassym.o optional compat_svr4 \ dependency "$S/i386/svr4/svr4_genassym.c" \ compile-with "${CC} ${CFLAGS} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "svr4_genassym.o" # svr4_assym.h optional compat_svr4 \ dependency "$S/kern/genassym.sh svr4_genassym.o" \ compile-with "sh $S/kern/genassym.sh svr4_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "svr4_assym.h" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "/usr/sbin/kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "atkbdmap.h" # ukbdmap.h optional ukbd_dflt_keymap \ compile-with "/usr/sbin/kbdcontrol -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" # msysosak.o optional fla \ dependency "$S/contrib/dev/fla/i386/msysosak.o.uu" \ compile-with "uudecode < $S/contrib/dev/fla/i386/msysosak.o.uu" \ no-implicit-rule # trlld.o optional oltr \ dependency "$S/contrib/dev/oltr/i386${FMT}.trlld.o.uu" \ compile-with "uudecode < $S/contrib/dev/oltr/i386${FMT}.trlld.o.uu" \ no-implicit-rule # compat/linux/linux_file.c optional compat_linux compat/linux/linux_getcwd.c optional compat_linux compat/linux/linux_ioctl.c optional compat_linux compat/linux/linux_ipc.c optional compat_linux compat/linux/linux_mib.c optional compat_linux compat/linux/linux_misc.c optional compat_linux compat/linux/linux_signal.c optional compat_linux compat/linux/linux_socket.c optional compat_linux compat/linux/linux_stats.c optional compat_linux compat/linux/linux_sysctl.c optional compat_linux compat/linux/linux_uid16.c optional compat_linux compat/linux/linux_util.c optional compat_linux compat/pecoff/imgact_pecoff.c optional pecoff_support compat/svr4/imgact_svr4.c optional compat_svr4 compat/svr4/svr4_fcntl.c optional compat_svr4 compat/svr4/svr4_filio.c optional compat_svr4 compat/svr4/svr4_ioctl.c optional compat_svr4 compat/svr4/svr4_ipc.c optional compat_svr4 compat/svr4/svr4_misc.c optional compat_svr4 compat/svr4/svr4_resource.c optional compat_svr4 compat/svr4/svr4_signal.c optional compat_svr4 compat/svr4/svr4_socket.c optional compat_svr4 compat/svr4/svr4_sockio.c optional compat_svr4 compat/svr4/svr4_stat.c optional compat_svr4 compat/svr4/svr4_stream.c optional compat_svr4 compat/svr4/svr4_syscallnames.c optional compat_svr4 compat/svr4/svr4_sysent.c optional compat_svr4 compat/svr4/svr4_sysvec.c optional compat_svr4 compat/svr4/svr4_termios.c optional compat_svr4 compat/svr4/svr4_ttold.c optional compat_svr4 contrib/dev/fla/fla.c optional fla contrib/dev/oltr/if_oltr.c optional oltr contrib/dev/oltr/trlldbm.c optional oltr contrib/dev/oltr/trlldhm.c optional oltr contrib/dev/oltr/trlldmac.c optional oltr crypto/des/des_ecb.c optional netsmbcrypto crypto/des/des_setkey.c optional netsmbcrypto #dev/advansys/adv_isa.c optional adv isa dev/aic/aic_cbus.c optional aic isa dev/ar/if_ar_isa.c optional ar isa dev/ct/bshw_machdep.c optional ct dev/ct/ct.c optional ct dev/ct/ct_isa.c optional ct isa dev/ed/if_ed_cbus.c optional ed isa dev/eisa/eisaconf.c optional eisa dev/fb/fb.c optional fb dev/fb/fb.c optional gdc dev/fb/splash.c optional splash dev/fe/if_fe_cbus.c optional fe isa dev/kbd/kbd.c optional kbd dev/kbd/kbd.c optional sc dev/kbd/kbd.c optional ukbd dev/kbd/kbd.c count pckbd dev/lnc/if_lnc_cbus.c optional lnc isa dev/snc/dp83932.c optional snc dev/snc/dp83932subr.c optional snc dev/snc/if_snc.c optional snc dev/snc/if_snc_cbus.c optional snc isa dev/snc/if_snc_pccard.c optional snc card dev/sr/if_sr_isa.c optional sr isa dev/syscons/apm/apm_saver.c optional apm_saver apm dev/syscons/schistory.c count sc dev/syscons/scmouse.c optional sc dev/syscons/scterm.c optional sc dev/syscons/scterm-dumb.c optional sc dev/syscons/scvidctl.c optional sc dev/syscons/sysmouse.c optional sc fs/smbfs/smbfs_io.c optional smbfs fs/smbfs/smbfs_node.c optional smbfs fs/smbfs/smbfs_smb.c optional smbfs fs/smbfs/smbfs_subr.c optional smbfs fs/smbfs/smbfs_vfsops.c optional smbfs fs/smbfs/smbfs_vnops.c optional smbfs gnu/i386/fpemul/div_small.s optional gpl_math_emulate \ warning "kernel contains GPL contaminated math emulator" gnu/i386/fpemul/errors.c optional gpl_math_emulate gnu/i386/fpemul/fpu_arith.c optional gpl_math_emulate gnu/i386/fpemul/fpu_aux.c optional gpl_math_emulate gnu/i386/fpemul/fpu_entry.c optional gpl_math_emulate gnu/i386/fpemul/fpu_etc.c optional gpl_math_emulate gnu/i386/fpemul/fpu_trig.c optional gpl_math_emulate gnu/i386/fpemul/get_address.c optional gpl_math_emulate gnu/i386/fpemul/load_store.c optional gpl_math_emulate gnu/i386/fpemul/poly_2xm1.c optional gpl_math_emulate gnu/i386/fpemul/poly_atan.c optional gpl_math_emulate gnu/i386/fpemul/poly_div.s optional gpl_math_emulate gnu/i386/fpemul/poly_l2.c optional gpl_math_emulate gnu/i386/fpemul/poly_mul64.s optional gpl_math_emulate gnu/i386/fpemul/poly_sin.c optional gpl_math_emulate gnu/i386/fpemul/poly_tan.c optional gpl_math_emulate gnu/i386/fpemul/polynomial.s optional gpl_math_emulate gnu/i386/fpemul/reg_add_sub.c optional gpl_math_emulate gnu/i386/fpemul/reg_compare.c optional gpl_math_emulate gnu/i386/fpemul/reg_constant.c optional gpl_math_emulate gnu/i386/fpemul/reg_div.s optional gpl_math_emulate gnu/i386/fpemul/reg_ld_str.c optional gpl_math_emulate gnu/i386/fpemul/reg_mul.c optional gpl_math_emulate gnu/i386/fpemul/reg_norm.s optional gpl_math_emulate gnu/i386/fpemul/reg_round.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_add.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_div.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_mul.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate i386/acpica/OsdEnvironment.c optional acpica i386/acpica/acpi_wakeup.c optional acpica acpi_wakecode.h optional acpica \ dependency "$S/i386/acpica/acpi_wakecode.S" \ compile-with "${MAKE} -f $S/i386/acpica/Makefile MAKESRCPATH=$S/i386/acpica" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.h acpi_wakecode.o acpi_wakecode.bin" # i386/i386/atomic.c standard \ compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}" i386/i386/autoconf.c standard i386/i386/bios.c standard i386/i386/bioscall.s standard i386/i386/busdma_machdep.c standard i386/i386/db_disasm.c optional ddb i386/i386/db_interface.c optional ddb i386/i386/db_trace.c optional ddb i386/i386/elf_machdep.c standard i386/i386/exception.s standard i386/i386/i386-gdbstub.c optional ddb i386/i386/i686_mem.c standard i386/i386/identcpu.c standard i386/i386/in_cksum.c optional inet i386/i386/initcpu.c standard i386/i386/k6_mem.c standard # locore.s needs to be handled in Makefile to put it first. Otherwise it's # now normal. # i386/i386/locore.s standard i386/i386/math_emulate.c optional math_emulate i386/i386/mem.c standard i386/i386/mp_clock.c optional smp i386/i386/mp_machdep.c optional smp i386/i386/mpapic.c optional smp i386/i386/mpboot.s optional smp i386/i386/nexus.c standard i386/i386/perfmon.c optional perfmon i386/i386/perfmon.c optional perfmon profiling-routine i386/i386/pmap.c standard i386/i386/procfs_machdep.c standard i386/i386/support.s standard i386/i386/swtch.s standard i386/i386/sys_machdep.c standard i386/i386/trap.c standard i386/i386/vm86.c standard i386/i386/vm_machdep.c standard i386/ibcs2/ibcs2_errno.c optional ibcs2 i386/ibcs2/ibcs2_fcntl.c optional ibcs2 i386/ibcs2/ibcs2_ioctl.c optional ibcs2 i386/ibcs2/ibcs2_ipc.c optional ibcs2 i386/ibcs2/ibcs2_isc.c optional ibcs2 i386/ibcs2/ibcs2_isc_sysent.c optional ibcs2 i386/ibcs2/ibcs2_misc.c optional ibcs2 i386/ibcs2/ibcs2_msg.c optional ibcs2 i386/ibcs2/ibcs2_other.c optional ibcs2 i386/ibcs2/ibcs2_signal.c optional ibcs2 i386/ibcs2/ibcs2_socksys.c optional ibcs2 i386/ibcs2/ibcs2_stat.c optional ibcs2 i386/ibcs2/ibcs2_sysent.c optional ibcs2 i386/ibcs2/ibcs2_sysi86.c optional ibcs2 i386/ibcs2/ibcs2_sysvec.c optional ibcs2 i386/ibcs2/ibcs2_util.c optional ibcs2 i386/ibcs2/ibcs2_xenix.c optional ibcs2 i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2 i386/ibcs2/imgact_coff.c optional ibcs2 i386/isa/bs/bs.c optional bs i386/isa/bs/bsfunc.c optional bs i386/isa/bs/bshw.c optional bs i386/isa/bs/bsif.c count bs i386/isa/asc.c count asc i386/isa/cronyx.c optional cx i386/isa/ctx.c count ctx i386/isa/cx.c count cx i386/isa/cy.c count cy i386/isa/elink.c optional ep i386/isa/elink.c optional ie i386/isa/gpib.c optional gp i386/isa/gsc.c count gsc i386/isa/if_cx.c optional cx i386/isa/if_el.c count el i386/isa/if_le.c count le i386/isa/if_rdp.c count rdp i386/isa/intr_machdep.c standard i386/isa/ithread.c standard i386/isa/isa.c optional isa i386/isa/isa_compat.c optional isa compat_oldisa \ warning "Old ISA driver compatibility shims present." i386/isa/istallion.c optional stli i386/isa/loran.c optional loran i386/isa/matcd/matcd.c count matcd i386/isa/mca_machdep.c optional mca i386/isa/mcd.c count mcd i386/isa/pcf.c optional pcf i386/isa/pcvt/pcvt_drv.c optional vt i386/isa/pcvt/pcvt_ext.c optional vt i386/isa/pcvt/pcvt_kbd.c optional vt i386/isa/pcvt/pcvt_out.c optional vt i386/isa/pcvt/pcvt_sup.c optional vt i386/isa/pcvt/pcvt_vtf.c optional vt i386/isa/pmtimer.c optional pmtimer i386/isa/prof_machdep.c optional profiling-routine i386/isa/rc.c count rc #i386/isa/rp.c optional rp i386/isa/scd.c count scd i386/isa/spic.c optional spic i386/isa/spigot.c count spigot i386/isa/stallion.c optional stl i386/isa/tw.c count tw i386/isa/wt.c count wt i386/linux/imgact_linux.c optional compat_linux i386/linux/linux_dummy.c optional compat_linux i386/linux/linux_locore.s optional compat_linux \ dependency "linux_assym.h" i386/linux/linux_machdep.c optional compat_linux i386/linux/linux_sysent.c optional compat_linux i386/linux/linux_sysvec.c optional compat_linux i386/pci/pci_cfgreg.c optional pci i386/pci/pci_bus.c optional pci i386/svr4/svr4_locore.s optional compat_svr4 \ dependency "svr4_assym.h" \ warning "COMPAT_SVR4 is broken and usage is, until fixed, not recommended" i386/svr4/svr4_machdep.c optional compat_svr4 # # isdn4bsd, needed for isic | iwic | ifpi | ihfc | ifpnp | itjc # i4b/layer1/i4b_l1dmux.c optional isic i4b/layer1/i4b_l1lib.c optional isic i4b/layer1/i4b_l1dmux.c optional iwic i4b/layer1/i4b_l1lib.c optional iwic i4b/layer1/i4b_l1dmux.c optional ifpi i4b/layer1/i4b_l1lib.c optional ifpi i4b/layer1/i4b_l1dmux.c optional ihfc i4b/layer1/i4b_l1lib.c optional ihfc i4b/layer1/i4b_l1dmux.c optional ifpnp i4b/layer1/i4b_l1lib.c optional ifpnp i4b/layer1/i4b_l1dmux.c optional itjc i4b/layer1/i4b_l1lib.c optional itjc # # isdn4bsd, isic # i4b/layer1/isic/i4b_asuscom_ipac.c optional isic i4b/layer1/isic/i4b_avm_a1.c optional isic i4b/layer1/isic/i4b_bchan.c optional isic i4b/layer1/isic/i4b_ctx_s0P.c optional isic i4b/layer1/isic/i4b_drn_ngo.c optional isic i4b/layer1/isic/i4b_dynalink.c optional isic i4b/layer1/isic/i4b_elsa_qs1i.c optional isic i4b/layer1/isic/i4b_elsa_qs1p.c optional isic i4b/layer1/isic/i4b_elsa_pcc16.c optional isic i4b/layer1/isic/i4b_hscx.c optional isic i4b/layer1/isic/i4b_isac.c optional isic i4b/layer1/isic/i4b_isic.c count isic i4b/layer1/isic/i4b_isic_isa.c optional isic i4b/layer1/isic/i4b_isic_pnp.c optional isic i4b/layer1/isic/i4b_itk_ix1.c optional isic i4b/layer1/isic/i4b_l1.c optional isic i4b/layer1/isic/i4b_l1fsm.c optional isic i4b/layer1/isic/i4b_siemens_isurf.c optional isic i4b/layer1/isic/i4b_sws.c optional isic i4b/layer1/isic/i4b_tel_s016.c optional isic i4b/layer1/isic/i4b_tel_s0163.c optional isic i4b/layer1/isic/i4b_tel_s08.c optional isic i4b/layer1/isic/i4b_usr_sti.c optional isic i4b/layer1/isic/i4b_diva.c optional isic # # isdn4bsd, iwic # i4b/layer1/iwic/i4b_iwic_pci.c count iwic i4b/layer1/iwic/i4b_iwic_dchan.c optional iwic i4b/layer1/iwic/i4b_iwic_bchan.c optional iwic i4b/layer1/iwic/i4b_iwic_fsm.c optional iwic i4b/layer1/iwic/i4b_iwic_l1if.c optional iwic # # isdn4bsd, ifpi # i4b/layer1/ifpi/i4b_ifpi_pci.c count ifpi i4b/layer1/ifpi/i4b_ifpi_isac.c optional ifpi i4b/layer1/ifpi/i4b_ifpi_l1.c optional ifpi i4b/layer1/ifpi/i4b_ifpi_l1fsm.c optional ifpi # # isdn4bsd, ifpnp # i4b/layer1/ifpnp/i4b_ifpnp_avm.c count ifpnp i4b/layer1/ifpnp/i4b_ifpnp_isac.c optional ifpnp i4b/layer1/ifpnp/i4b_ifpnp_l1.c optional ifpnp i4b/layer1/ifpnp/i4b_ifpnp_l1fsm.c optional ifpnp # # isdn4bsd, ihfc # i4b/layer1/ihfc/i4b_ihfc_l1if.c count ihfc i4b/layer1/ihfc/i4b_ihfc_pnp.c optional ihfc i4b/layer1/ihfc/i4b_ihfc_drv.c optional ihfc # # isdn4bsd, itjc # i4b/layer1/itjc/i4b_itjc_pci.c count itjc i4b/layer1/itjc/i4b_itjc_isac.c optional itjc i4b/layer1/itjc/i4b_itjc_l1.c optional itjc i4b/layer1/itjc/i4b_itjc_l1fsm.c optional itjc # isa/psm.c optional psm kern/imgact_aout.c standard kern/imgact_gzip.c optional gzip kern/link_aout.c standard kern/md4c.c optional netsmb kern/subr_diskmbr.c count compat_atdisk libkern/divdi3.c standard libkern/moddi3.c standard libkern/qdivrem.c standard libkern/ucmpdi2.c standard libkern/udivdi3.c standard libkern/umoddi3.c standard netsmb/smb_conn.c optional netsmb netsmb/smb_crypt.c optional netsmb netsmb/smb_dev.c optional netsmb netsmb/smb_iod.c optional netsmb netsmb/smb_rq.c optional netsmb netsmb/smb_smb.c optional netsmb netsmb/smb_subr.c optional netsmb netsmb/smb_trantcp.c optional netsmb netsmb/smb_usr.c optional netsmb pc98/apm/apm.c optional apm pc98/apm/apm_bioscall.s optional apm +pc98/i386/busio.s standard +pc98/i386/busiosubr.c standard pc98/i386/machdep.c standard #pc98/i386/userconfig.c optional userconfig pc98/pc98/atapi.c optional wdc pc98/pc98/clock.c standard pc98/pc98/diskslice_machdep.c standard pc98/pc98/fd.c optional fdc pc98/pc98/isa_dma.c optional isa pc98/pc98/mse.c optional mse pc98/pc98/npx.c mandatory npx pc98/pc98/olpt.c optional olpt pc98/pc98/pc98gdc.c optional gdc pc98/pc98/pc98kbd.c optional pckbd pc98/pc98/pc98_machdep.c standard pc98/pc98/pcaudio.c optional pca pc98/pc98/ppc.c optional ppc pc98/pc98/scgdcrndr.c optional sc gdc pc98/pc98/scterm-sck.c optional sc pc98/pc98/scvtbpc98.c optional sc pc98/pc98/sio.c optional sio pc98/pc98/spkr.c optional speaker pc98/pc98/syscons.c optional sc pc98/pc98/syscons_pc98.c optional sc pc98/pc98/wd.c count wdc pc98/pc98/wd_cd.c count wcd wdc pc98/pc98/wfd.c count wfd wdc pc98/pc98/wst.c count wst wdc pccard/mecia.c optional mecia card Index: head/sys/conf/options.pc98 =================================================================== --- head/sys/conf/options.pc98 (revision 84614) +++ head/sys/conf/options.pc98 (revision 84615) @@ -1,221 +1,222 @@ # $FreeBSD$ # Options specific to the pc98 platform kernels DISABLE_PSE MATH_EMULATE opt_math_emulate.h GPL_MATH_EMULATE opt_math_emulate.h PMAP_SHPGPERPROC opt_pmap.h PPC_PROBE_CHIPSET opt_ppc.h PPC_DEBUG opt_ppc.h SHOW_BUSYBUFS PANIC_REBOOT_WAIT_TIME opt_panic.h MAXMEM PERFMON opt_perfmon.h POWERFAIL_NMI opt_trap.h AUTO_EOI_1 opt_auto_eoi.h AUTO_EOI_2 opt_auto_eoi.h CONSPEED opt_comconsole.h I586_PMC_GUPROF opt_i586_guprof.h WLCACHE opt_wavelan.h WLDEBUG opt_wavelan.h COMPAT_OLDISA BROKEN_KEYBOARD_RESET opt_reset.h KSTACK_PAGES # Options for emulators. These should only be used at config time, so # they are handled like options for static file systems # (see src/sys/conf/options), except for broken debugging options. IBCS2 opt_dontuse.h COMPAT_LINUX opt_dontuse.h DEBUG_LINUX opt_linux.h COMPAT_SVR4 opt_dontuse.h DEBUG_SVR4 opt_svr4.h PECOFF_SUPPORT opt_dontuse.h PECOFF_DEBUG opt_pecoff.h # i386 SMP options APIC_IO opt_global.h # Change KVM size. Changes things all over the kernel. KVA_PAGES opt_global.h CLK_CALIBRATION_LOOP opt_clock.h CLK_USE_I8254_CALIBRATION opt_clock.h CLK_USE_TSC_CALIBRATION opt_clock.h TIMER_FREQ opt_clock.h NO_F00F_HACK opt_cpu.h CPU_BLUELIGHTNING_FPU_OP_CACHE opt_cpu.h CPU_BLUELIGHTNING_3X opt_cpu.h CPU_BTB_EN opt_cpu.h CPU_CYRIX_NO_LOCK opt_cpu.h CPU_DIRECT_MAPPED_CACHE opt_cpu.h CPU_DISABLE_5X86_LSSER opt_cpu.h CPU_FASTER_5X86_FPU opt_cpu.h CPU_I486_ON_386 opt_cpu.h CPU_IORT opt_cpu.h CPU_L2_LATENCY opt_cpu.h CPU_LOOP_EN opt_cpu.h CPU_PPRO2CELERON opt_cpu.h CPU_RSTK_EN opt_cpu.h CPU_SUSP_HLT opt_cpu.h CPU_UPGRADE_HW_CACHE opt_cpu.h CPU_WT_ALLOC opt_cpu.h CYRIX_CACHE_WORKS opt_cpu.h CYRIX_CACHE_REALLY_WORKS opt_cpu.h NO_MEMORY_HOLE opt_cpu.h CPU_ENABLE_SSE opt_cpu.h # The CPU type affects the endian conversion functions all over the kernel. I386_CPU opt_global.h I486_CPU opt_global.h I586_CPU opt_global.h I686_CPU opt_global.h MAXCONS opt_syscons.h SC_ALT_MOUSE_IMAGE opt_syscons.h SC_DEBUG_LEVEL opt_syscons.h SC_DFLT_FONT opt_syscons.h SC_DISABLE_DDBKEY opt_syscons.h SC_DISABLE_REBOOT opt_syscons.h SC_HISTORY_SIZE opt_syscons.h SC_KERNEL_CONS_ATTR opt_syscons.h SC_KERNEL_CONS_REV_ATTR opt_syscons.h SC_MOUSE_CHAR opt_syscons.h SC_NO_CUTPASTE opt_syscons.h SC_NO_FONT_LOADING opt_syscons.h SC_NO_HISTORY opt_syscons.h SC_NO_SYSMOUSE opt_syscons.h SC_NORM_ATTR opt_syscons.h SC_NORM_REV_ATTR opt_syscons.h SC_PIXEL_MODE opt_syscons.h SC_RENDER_DEBUG opt_syscons.h SC_TWOBUTTON_MOUSE opt_syscons.h GDC opt_gdc.h PSM_HOOKRESUME opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h PSM_DEBUG opt_psm.h PCIC_RESUME_RESET opt_pcic.h KBD_DISABLE_KEYMAP_LOAD opt_kbd.h KBD_INSTALL_CDEV opt_kbd.h KBD_MAXRETRY opt_kbd.h KBD_MAXWAIT opt_kbd.h KBD_RESETDELAY opt_kbd.h KBDIO_DEBUG opt_kbd.h #USERCONFIG opt_userconfig.h #VISUAL_USERCONFIG opt_userconfig.h #INTRO_USERCONFIG opt_userconfig.h #DEV_EISA opt_userconfig.h EISA_SLOTS opt_eisa.h # pcvt(4) has a bunch of options FAT_CURSOR opt_pcvt.h XSERVER opt_pcvt.h PCVT_24LINESDEF opt_pcvt.h PCVT_CTRL_ALT_DEL opt_pcvt.h PCVT_META_ESC opt_pcvt.h PCVT_NSCREENS opt_pcvt.h PCVT_PRETTYSCRNS opt_pcvt.h PCVT_SCANSET opt_pcvt.h PCVT_SCREENSAVER opt_pcvt.h PCVT_USEKBDSEC opt_pcvt.h PCVT_VT220KEYB opt_pcvt.h PCVT_GREENSAVER opt_pcvt.h # voxware options GUS_DMA2 opt_sound.h GUS_DMA opt_sound.h GUS_IRQ opt_sound.h # Video spigot SPIGOT_UNSECURE opt_spigot.h # ------------------------------- # isdn4bsd: passive ISA cards # ------------------------------- TEL_S0_8 opt_i4b.h TEL_S0_16 opt_i4b.h TEL_S0_16_3 opt_i4b.h AVM_A1 opt_i4b.h USR_STI opt_i4b.h ITKIX1 opt_i4b.h ELSA_PCC16 opt_i4b.h # ------------------------------- # isdn4bsd: passive ISA PnP cards # ------------------------------- CRTX_S0_P opt_i4b.h DRN_NGO opt_i4b.h TEL_S0_16_3_P opt_i4b.h SEDLBAUER opt_i4b.h DYNALINK opt_i4b.h ASUSCOM_IPAC opt_i4b.h ELSA_QS1ISA opt_i4b.h SIEMENS_ISURF2 opt_i4b.h EICON_DIVA opt_i4b.h # ------------------------------- # isdn4bsd: passive PCI cards # ------------------------------- ELSA_QS1PCI opt_i4b.h AVM_A1_PCI opt_i4b.h # ------------------------------- # isdn4bsd: passive PCMCIA cards # ------------------------------- #AVM_A1_PCMCIA opt_i4b.h # ------------------------------- # isdn4bsd: misc options # ------------------------------- # temporary workaround for SMP machines I4B_SMP_WORKAROUND opt_i4b.h # enable VJ compression code for ipr i/f IPR_VJ opt_i4b.h IPR_LOG opt_i4b.h # ------------------------------- # oltr: build options # ------------------------------- # Exclude microcode options OLTR_NO_TMS_MAC opt_oltr.h OLTR_NO_HAWKEYE_MAC opt_oltr.h OLTR_NO_BULLSEYE_MAC opt_oltr.h # Total number of ports controlled by the dgb(4) driver. # Defaults to NDGB*16. NDGBPORTS opt_dgb.h # bs driver options SCSI_BOUNCE_SIZE opt_bs.h BS_TARG_SAFEMODE opt_bs.h # ct driver options CT_USE_RELOCATE_OFFSET opt_ct.h CT_BUS_WEIGHT opt_ct.h # npx options FPU_ERROR_BROKEN opt_npx.h # PC98 options PC98 opt_global.h EPSON_BOUNCEDMA opt_pc98.h EPSON_MEMWIN opt_pc98.h LINE30 opt_syscons.h # Device options DEV_NPX opt_npx.h DEV_APM opt_apm.h DEV_SPLASH opt_splash.h +DEV_MECIA opt_mecia.h # SMB/CIFS requester NETSMB opt_netsmb.h NETSMBCRYPTO opt_netsmb.h # SMB/CIFS filesystem SMBFS # ------------------------------- # EOF # ------------------------------- Index: head/sys/i386/i386/genassym.c =================================================================== --- head/sys/i386/i386/genassym.c (revision 84614) +++ head/sys/i386/i386/genassym.c (revision 84615) @@ -1,217 +1,224 @@ /*- * Copyright (c) 1982, 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 * $FreeBSD$ */ #include "opt_kstack_pages.h" #include #include #include #include #include #include #include #include #include #include #include #include /* XXX */ #ifdef KTR_PERCPU #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef SMP #include #endif #include #include #include #include ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap)); ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); ASSYM(P_SFLAG, offsetof(struct proc, p_sflag)); ASSYM(P_STAT, offsetof(struct proc, p_stat)); ASSYM(P_UAREA, offsetof(struct proc, p_uarea)); /*ASSYM(TD_STAT, offsetof(struct thread, td__stat));*/ ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_WCHAN, offsetof(struct thread, td_wchan)); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_KSE, offsetof(struct thread, td_kse)); ASSYM(TD_PROC, offsetof(struct thread, td_proc)); ASSYM(TD_INTR_NESTING_LEVEL, offsetof(struct thread, td_intr_nesting_level)); ASSYM(KE_FLAGS, offsetof(struct kse, ke_flags)); ASSYM(KEF_ASTPENDING, KEF_ASTPENDING); ASSYM(KEF_NEEDRESCHED, KEF_NEEDRESCHED); ASSYM(SSLEEP, SSLEEP); ASSYM(SRUN, SRUN); ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap)); ASSYM(V_SYSCALL, offsetof(struct vmmeter, v_syscall)); ASSYM(V_INTR, offsetof(struct vmmeter, v_intr)); /* ASSYM(UPAGES, UPAGES);*/ ASSYM(UAREA_PAGES, UAREA_PAGES); ASSYM(KSTACK_PAGES, KSTACK_PAGES); ASSYM(PAGE_SIZE, PAGE_SIZE); ASSYM(NPTEPG, NPTEPG); ASSYM(NPDEPG, NPDEPG); ASSYM(PDESIZE, PDESIZE); ASSYM(PTESIZE, PTESIZE); ASSYM(PAGE_SHIFT, PAGE_SHIFT); ASSYM(PAGE_MASK, PAGE_MASK); ASSYM(PDRSHIFT, PDRSHIFT); ASSYM(USRSTACK, USRSTACK); ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); ASSYM(KERNBASE, KERNBASE); ASSYM(MCLBYTES, MCLBYTES); ASSYM(PCB_CR3, offsetof(struct pcb, pcb_cr3)); ASSYM(PCB_EDI, offsetof(struct pcb, pcb_edi)); ASSYM(PCB_ESI, offsetof(struct pcb, pcb_esi)); ASSYM(PCB_EBP, offsetof(struct pcb, pcb_ebp)); ASSYM(PCB_ESP, offsetof(struct pcb, pcb_esp)); ASSYM(PCB_EBX, offsetof(struct pcb, pcb_ebx)); ASSYM(PCB_EIP, offsetof(struct pcb, pcb_eip)); ASSYM(TSS_ESP0, offsetof(struct i386tss, tss_esp0)); ASSYM(PCB_USERLDT, offsetof(struct pcb, pcb_ldt)); ASSYM(PCB_GS, offsetof(struct pcb, pcb_gs)); ASSYM(PCB_DR0, offsetof(struct pcb, pcb_dr0)); ASSYM(PCB_DR1, offsetof(struct pcb, pcb_dr1)); ASSYM(PCB_DR2, offsetof(struct pcb, pcb_dr2)); ASSYM(PCB_DR3, offsetof(struct pcb, pcb_dr3)); ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6)); ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7)); ASSYM(PCB_DBREGS, PCB_DBREGS); ASSYM(PCB_EXT, offsetof(struct pcb, pcb_ext)); ASSYM(PCB_SPARE, offsetof(struct pcb, __pcb_spare)); ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save)); ASSYM(PCB_SAVEFPU_SIZE, sizeof(union savefpu)); ASSYM(PCB_SAVE87_SIZE, sizeof(struct save87)); ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); ASSYM(PCB_SIZE, sizeof(struct pcb)); ASSYM(TF_TRAPNO, offsetof(struct trapframe, tf_trapno)); ASSYM(TF_ERR, offsetof(struct trapframe, tf_err)); ASSYM(TF_CS, offsetof(struct trapframe, tf_cs)); ASSYM(TF_EFLAGS, offsetof(struct trapframe, tf_eflags)); ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler)); ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc)); ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); ASSYM(SC_PS, offsetof(struct osigcontext, sc_ps)); ASSYM(SC_FS, offsetof(struct osigcontext, sc_fs)); ASSYM(SC_GS, offsetof(struct osigcontext, sc_gs)); ASSYM(SC_TRAPNO, offsetof(struct osigcontext, sc_trapno)); ASSYM(UC_EFLAGS, offsetof(ucontext_t, uc_mcontext.mc_eflags)); ASSYM(UC_GS, offsetof(ucontext_t, uc_mcontext.mc_gs)); ASSYM(ENOENT, ENOENT); ASSYM(EFAULT, EFAULT); ASSYM(ENAMETOOLONG, ENAMETOOLONG); ASSYM(MAXPATHLEN, MAXPATHLEN); ASSYM(BOOTINFO_SIZE, sizeof(struct bootinfo)); ASSYM(BI_VERSION, offsetof(struct bootinfo, bi_version)); ASSYM(BI_KERNELNAME, offsetof(struct bootinfo, bi_kernelname)); ASSYM(BI_NFS_DISKLESS, offsetof(struct bootinfo, bi_nfs_diskless)); ASSYM(BI_ENDCOMMON, offsetof(struct bootinfo, bi_endcommon)); ASSYM(NFSDISKLESS_SIZE, sizeof(struct nfs_diskless)); ASSYM(BI_SIZE, offsetof(struct bootinfo, bi_size)); ASSYM(BI_SYMTAB, offsetof(struct bootinfo, bi_symtab)); ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab)); ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend)); ASSYM(GD_SIZEOF, sizeof(struct globaldata)); ASSYM(GD_PRVSPACE, offsetof(struct globaldata, gd_prvspace)); ASSYM(GD_CURTHREAD, offsetof(struct globaldata, gd_curthread)); ASSYM(GD_NPXTHREAD, offsetof(struct globaldata, gd_npxthread)); ASSYM(GD_IDLETHREAD, offsetof(struct globaldata, gd_idlethread)); ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); ASSYM(GD_COMMON_TSS, offsetof(struct globaldata, gd_common_tss)); ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime)); ASSYM(GD_SWITCHTICKS, offsetof(struct globaldata, gd_switchticks)); ASSYM(GD_COMMON_TSSD, offsetof(struct globaldata, gd_common_tssd)); ASSYM(GD_TSS_GDT, offsetof(struct globaldata, gd_tss_gdt)); ASSYM(GD_CURRENTLDT, offsetof(struct globaldata, gd_currentldt)); /* XXX */ #ifdef KTR_PERCPU ASSYM(GD_KTR_IDX, offsetof(struct globaldata, gd_ktr_idx)); ASSYM(GD_KTR_BUF, offsetof(struct globaldata, gd_ktr_buf)); ASSYM(GD_KTR_BUF_DATA, offsetof(struct globaldata, gd_ktr_buf_data)); #endif ASSYM(GD_CPUID, offsetof(struct globaldata, gd_cpuid)); #ifdef SMP ASSYM(LA_VER, offsetof(struct LAPIC, version)); ASSYM(LA_TPR, offsetof(struct LAPIC, tpr)); ASSYM(LA_EOI, offsetof(struct LAPIC, eoi)); ASSYM(LA_SVR, offsetof(struct LAPIC, svr)); ASSYM(LA_ICR_LO, offsetof(struct LAPIC, icr_lo)); ASSYM(LA_ICR_HI, offsetof(struct LAPIC, icr_hi)); #endif ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL)); ASSYM(KDSEL, GSEL(GDATA_SEL, SEL_KPL)); ASSYM(KPSEL, GSEL(GPRIV_SEL, SEL_KPL)); ASSYM(BC32SEL, GSEL(GBIOSCODE32_SEL, SEL_KPL)); ASSYM(GPROC0_SEL, GPROC0_SEL); ASSYM(VM86_FRAMESIZE, sizeof(struct vm86frame)); ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock)); ASSYM(MTX_RECURSECNT, offsetof(struct mtx, mtx_recurse)); ASSYM(MTX_SAVECRIT, offsetof(struct mtx, mtx_savecrit)); + +#ifdef PC98 +#include + +ASSYM(BUS_SPACE_HANDLE_BASE, offsetof(struct bus_space_handle, bsh_base)); +ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat)); +#endif Index: head/sys/i386/i386/legacy.c =================================================================== --- head/sys/i386/i386/legacy.c (revision 84614) +++ head/sys/i386/i386/legacy.c (revision 84615) @@ -1,679 +1,685 @@ /* * Copyright 1998 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * This code implements a `root nexus' for Intel Architecture * machines. The function of the root nexus is to serve as an * attachment point for both processors and buses, and to manage * resources which are common to all of them. In particular, * this code implements the core resource managers for interrupt * requests, DMA requests (which rightfully should be a part of the * ISA code but it's easier to do it here for now), I/O port addresses, * and I/O memory address space. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef APIC_IO #include #include #endif #include #ifdef PC98 #include #else #include #endif #include #include #include #ifdef PC98 static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle"); #endif static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); struct nexus_device { struct resource_list nx_resources; int nx_pcibus; }; #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static int nexus_attach(device_t); static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format); static int nexus_print_all_resources(device_t dev); static int nexus_print_child(device_t, device_t); static device_t nexus_add_child(device_t bus, int order, const char *name, int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); static int nexus_write_ivar(device_t, device_t, int, uintptr_t); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, struct resource *); static int nexus_release_resource(device_t, device_t, int, int, struct resource *); static int nexus_setup_intr(device_t, device_t, struct resource *, int flags, void (*)(void *), void *, void **); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); static void nexus_delete_resource(device_t, device_t, int, int); static device_method_t nexus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nexus_probe), DEVMETHOD(device_attach, nexus_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, nexus_read_ivar), DEVMETHOD(bus_write_ivar, nexus_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), DEVMETHOD(bus_delete_resource, nexus_delete_resource), { 0, 0 } }; static driver_t nexus_driver = { "nexus", nexus_methods, 1, /* no softc */ }; static devclass_t nexus_devclass; DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); static int nexus_probe(device_t dev) { device_quiet(dev); /* suppress attach message for neatness */ /* * XXX working notes: * * - IRQ resource creation should be moved to the PIC/APIC driver. * - DRQ resource creation should be moved to the DMAC driver. * - The above should be sorted to probe earlier than any child busses. * * - Leave I/O and memory creation here, as child probes may need them. * (especially eg. ACPI) */ /* * IRQ's are on the mainboard on old systems, but on the ISA part * of PCI->ISA bridges. There would be multiple sets of IRQs on * multi-ISA-bus systems. PCI interrupts are routed to the ISA * component, so in a way, PCI can be a partial child of an ISA bus(!). * APIC interrupts are global though. * * XXX We depend on the AT PIC driver correctly claiming IRQ 2 * to prevent its reuse elsewhere in the !APIC_IO case. */ irq_rman.rm_start = 0; irq_rman.rm_type = RMAN_ARRAY; irq_rman.rm_descr = "Interrupt request lines"; #ifdef APIC_IO irq_rman.rm_end = APIC_INTMAPSIZE - 1; #else irq_rman.rm_end = 15; #endif if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, irq_rman.rm_start, irq_rman.rm_end)) panic("nexus_probe irq_rman"); /* * ISA DMA on PCI systems is implemented in the ISA part of each * PCI->ISA bridge and the channels can be duplicated if there are * multiple bridges. (eg: laptops with docking stations) */ drq_rman.rm_start = 0; #ifdef PC98 drq_rman.rm_end = 3; #else drq_rman.rm_end = 7; #endif drq_rman.rm_type = RMAN_ARRAY; drq_rman.rm_descr = "DMA request lines"; /* XXX drq 0 not available on some machines */ if (rman_init(&drq_rman) || rman_manage_region(&drq_rman, drq_rman.rm_start, drq_rman.rm_end)) panic("nexus_probe drq_rman"); /* * However, IO ports and Memory truely are global at this level, * as are APIC interrupts (however many IO APICS there turn out * to be on large systems..) */ port_rman.rm_start = 0; port_rman.rm_end = 0xffff; port_rman.rm_type = RMAN_ARRAY; port_rman.rm_descr = "I/O ports"; if (rman_init(&port_rman) || rman_manage_region(&port_rman, 0, 0xffff)) panic("nexus_probe port_rman"); mem_rman.rm_start = 0; mem_rman.rm_end = ~0u; mem_rman.rm_type = RMAN_ARRAY; mem_rman.rm_descr = "I/O memory addresses"; if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0)) panic("nexus_probe mem_rman"); return bus_generic_probe(dev); } static int nexus_attach(device_t dev) { device_t child; /* * First, deal with the children we know about already */ bus_generic_attach(dev); /* * And if we didn't see EISA or ISA on a pci bridge, create some * connection points now so they show up "on motherboard". */ if (!devclass_get_device(devclass_find("eisa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "eisa", 0); if (child == NULL) panic("nexus_attach eisa"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("mca"), 0)) { child = BUS_ADD_CHILD(dev, 0, "mca", 0); if (child == 0) panic("nexus_probe mca"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("isa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "isa", 0); if (child == NULL) panic("nexus_attach isa"); device_probe_and_attach(child); } return 0; } static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format) { struct resource_list_entry *rle; int printed, retval; printed = 0; retval = 0; /* Yes, this is kinda cheating */ SLIST_FOREACH(rle, rl, link) { if (rle->type == type) { if (printed == 0) retval += printf(" %s ", name); else if (printed > 0) retval += printf(","); printed++; retval += printf(format, rle->start); if (rle->count > 1) { retval += printf("-"); retval += printf(format, rle->start + rle->count - 1); } } } return retval; } static int nexus_print_all_resources(device_t dev) { struct nexus_device *ndev = DEVTONX(dev); struct resource_list *rl = &ndev->nx_resources; int retval = 0; if (SLIST_FIRST(rl) || ndev->nx_pcibus != -1) retval += printf(" at"); retval += nexus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); retval += nexus_print_resources(rl, "iomem", SYS_RES_MEMORY, "%#lx"); retval += nexus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); return retval; } static int nexus_print_child(device_t bus, device_t child) { struct nexus_device *ndev = DEVTONX(child); int retval = 0; retval += bus_print_child_header(bus, child); retval += nexus_print_all_resources(child); if (ndev->nx_pcibus != -1) retval += printf(" pcibus %d", ndev->nx_pcibus); retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */ return (retval); } static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { device_t child; struct nexus_device *ndev; ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); if (!ndev) return(0); resource_list_init(&ndev->nx_resources); ndev->nx_pcibus = -1; child = device_add_child_ordered(bus, order, name, unit); /* should we free this in nexus_child_detached? */ device_set_ivars(child, ndev); return(child); } static int nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: *result = ndev->nx_pcibus; break; default: return ENOENT; } return 0; } static int nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: ndev->nx_pcibus = value; break; default: return ENOENT; } return 0; } /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. * (Exceptions include npx.) */ static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct nexus_device *ndev = DEVTONX(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int needactivate = flags & RF_ACTIVE; /* * If this is an allocation of the "default" range for a given RID, and * we know what the resources for this device are (ie. they aren't maintained * by a child bus), then work out the start/end values. */ if ((start == 0UL) && (end == ~0UL) && (count == 1)) { if (ndev == NULL) return(NULL); rle = resource_list_find(&ndev->nx_resources, type, *rid); if (rle == NULL) return(NULL); start = rle->start; end = rle->end; count = rle->count; } flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_IRQ: rm = &irq_rman; break; case SYS_RES_DRQ: rm = &drq_rman; break; case SYS_RES_IOPORT: rm = &port_rman; break; case SYS_RES_MEMORY: rm = &mem_rman; break; default: return 0; } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) return 0; #ifdef PC98 /* Allocate bushandle. */ rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE, M_NOWAIT | M_ZERO); if (rv->r_bushandle == 0) { rman_release_resource(rv); return 0; } #endif if (type == SYS_RES_MEMORY) { rman_set_bustag(rv, I386_BUS_SPACE_MEM); } else if (type == SYS_RES_IOPORT) { rman_set_bustag(rv, I386_BUS_SPACE_IO); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ rv->r_bushandle->bsh_base = rv->r_start; - rv->r_bushandle->bsh_iat = NULL; + rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; rv->r_bushandle->bsh_iatsz = 0; rv->r_bushandle->bsh_res = NULL; rv->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(rv, rv->r_start); #endif } if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { #ifdef PC98 free(rv->r_bushandle, M_BUSSPACEHANDLE); #endif rman_release_resource(rv); return 0; } } return rv; } static int nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, map it into the kernel. */ if (rman_get_bustag(r) == I386_BUS_SPACE_MEM) { caddr_t vaddr = 0; if (rman_get_end(r) < 1024 * 1024) { /* * The first 1Mb is mapped at KERNBASE. */ vaddr = (caddr_t)(uintptr_t)(KERNBASE + rman_get_start(r)); } else { u_int32_t paddr; u_int32_t psize; u_int32_t poffs; paddr = rman_get_start(r); psize = rman_get_size(r); poffs = paddr - trunc_page(paddr); vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; } rman_set_virtual(r, vaddr); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ r->r_bushandle->bsh_base = (bus_addr_t) vaddr; - r->r_bushandle->bsh_iat = NULL; + r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; r->r_bushandle->bsh_iatsz = 0; r->r_bushandle->bsh_res = NULL; r->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + r->r_bushandle->bsh_bam = r->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(r, (bus_space_handle_t) vaddr); #endif } return (rman_activate_resource(r)); } static int nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, unmap it. */ if ((rman_get_bustag(r) == I386_BUS_SPACE_MEM) && (rman_get_end(r) >= 1024 * 1024)) { u_int32_t psize; psize = rman_get_size(r); pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize); } return (rman_deactivate_resource(r)); } static int nexus_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { if (rman_get_flags(r) & RF_ACTIVE) { int error = bus_deactivate_resource(child, type, rid, r); if (error) return error; } #ifdef PC98 free(r->r_bushandle, M_BUSSPACEHANDLE); #endif return (rman_release_resource(r)); } /* * Currently this uses the really grody interface from kern/kern_intr.c * (which really doesn't belong in kern/anything.c). Eventually, all of * the code in kern_intr.c and machdep_intr.c should get moved here, since * this is going to be the official interface. */ static int nexus_setup_intr(device_t bus, device_t child, struct resource *irq, int flags, void (*ihand)(void *), void *arg, void **cookiep) { driver_t *driver; int error; /* somebody tried to setup an irq that failed to allocate! */ if (irq == NULL) panic("nexus_setup_intr: NULL irq resource!"); *cookiep = 0; if ((irq->r_flags & RF_SHAREABLE) == 0) flags |= INTR_EXCL; driver = device_get_driver(child); /* * We depend here on rman_activate_resource() being idempotent. */ error = rman_activate_resource(irq); if (error) return (error); error = inthand_add(device_get_nameunit(child), irq->r_start, ihand, arg, flags, cookiep); return (error); } static int nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) { return (inthand_remove(ih)); } static int nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; /* XXX this should return a success/failure indicator */ resource_list_add(rl, type, rid, start, start + count - 1, count); return(0); } static int nexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; struct resource_list_entry *rle; rle = resource_list_find(rl, type, rid); device_printf(child, "type %d rid %d startp %p countp %p - got %p\n", type, rid, startp, countp, rle); if (!rle) return(ENOENT); if (startp) *startp = rle->start; if (countp) *countp = rle->count; return(0); } static void nexus_delete_resource(device_t dev, device_t child, int type, int rid) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; resource_list_delete(rl, type, rid); } /* * Placeholder which claims PnP 'devices' which describe system * resources. */ static struct isa_pnp_id sysresource_ids[] = { { 0x010cd041 /* PNP0c01 */, "System Memory" }, { 0x020cd041 /* PNP0c02 */, "System Resource" }, { 0 } }; static int sysresource_probe(device_t dev) { int result; if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) { device_quiet(dev); } return(result); } static int sysresource_attach(device_t dev) { return(0); } static device_method_t sysresource_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sysresource_probe), DEVMETHOD(device_attach, sysresource_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), { 0, 0 } }; static driver_t sysresource_driver = { "sysresource", sysresource_methods, 1, /* no softc */ }; static devclass_t sysresource_devclass; DRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0); Index: head/sys/i386/i386/nexus.c =================================================================== --- head/sys/i386/i386/nexus.c (revision 84614) +++ head/sys/i386/i386/nexus.c (revision 84615) @@ -1,679 +1,685 @@ /* * Copyright 1998 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * This code implements a `root nexus' for Intel Architecture * machines. The function of the root nexus is to serve as an * attachment point for both processors and buses, and to manage * resources which are common to all of them. In particular, * this code implements the core resource managers for interrupt * requests, DMA requests (which rightfully should be a part of the * ISA code but it's easier to do it here for now), I/O port addresses, * and I/O memory address space. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef APIC_IO #include #include #endif #include #ifdef PC98 #include #else #include #endif #include #include #include #ifdef PC98 static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle"); #endif static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); struct nexus_device { struct resource_list nx_resources; int nx_pcibus; }; #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static int nexus_attach(device_t); static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format); static int nexus_print_all_resources(device_t dev); static int nexus_print_child(device_t, device_t); static device_t nexus_add_child(device_t bus, int order, const char *name, int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); static int nexus_write_ivar(device_t, device_t, int, uintptr_t); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, struct resource *); static int nexus_release_resource(device_t, device_t, int, int, struct resource *); static int nexus_setup_intr(device_t, device_t, struct resource *, int flags, void (*)(void *), void *, void **); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); static void nexus_delete_resource(device_t, device_t, int, int); static device_method_t nexus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nexus_probe), DEVMETHOD(device_attach, nexus_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, nexus_read_ivar), DEVMETHOD(bus_write_ivar, nexus_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), DEVMETHOD(bus_delete_resource, nexus_delete_resource), { 0, 0 } }; static driver_t nexus_driver = { "nexus", nexus_methods, 1, /* no softc */ }; static devclass_t nexus_devclass; DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); static int nexus_probe(device_t dev) { device_quiet(dev); /* suppress attach message for neatness */ /* * XXX working notes: * * - IRQ resource creation should be moved to the PIC/APIC driver. * - DRQ resource creation should be moved to the DMAC driver. * - The above should be sorted to probe earlier than any child busses. * * - Leave I/O and memory creation here, as child probes may need them. * (especially eg. ACPI) */ /* * IRQ's are on the mainboard on old systems, but on the ISA part * of PCI->ISA bridges. There would be multiple sets of IRQs on * multi-ISA-bus systems. PCI interrupts are routed to the ISA * component, so in a way, PCI can be a partial child of an ISA bus(!). * APIC interrupts are global though. * * XXX We depend on the AT PIC driver correctly claiming IRQ 2 * to prevent its reuse elsewhere in the !APIC_IO case. */ irq_rman.rm_start = 0; irq_rman.rm_type = RMAN_ARRAY; irq_rman.rm_descr = "Interrupt request lines"; #ifdef APIC_IO irq_rman.rm_end = APIC_INTMAPSIZE - 1; #else irq_rman.rm_end = 15; #endif if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, irq_rman.rm_start, irq_rman.rm_end)) panic("nexus_probe irq_rman"); /* * ISA DMA on PCI systems is implemented in the ISA part of each * PCI->ISA bridge and the channels can be duplicated if there are * multiple bridges. (eg: laptops with docking stations) */ drq_rman.rm_start = 0; #ifdef PC98 drq_rman.rm_end = 3; #else drq_rman.rm_end = 7; #endif drq_rman.rm_type = RMAN_ARRAY; drq_rman.rm_descr = "DMA request lines"; /* XXX drq 0 not available on some machines */ if (rman_init(&drq_rman) || rman_manage_region(&drq_rman, drq_rman.rm_start, drq_rman.rm_end)) panic("nexus_probe drq_rman"); /* * However, IO ports and Memory truely are global at this level, * as are APIC interrupts (however many IO APICS there turn out * to be on large systems..) */ port_rman.rm_start = 0; port_rman.rm_end = 0xffff; port_rman.rm_type = RMAN_ARRAY; port_rman.rm_descr = "I/O ports"; if (rman_init(&port_rman) || rman_manage_region(&port_rman, 0, 0xffff)) panic("nexus_probe port_rman"); mem_rman.rm_start = 0; mem_rman.rm_end = ~0u; mem_rman.rm_type = RMAN_ARRAY; mem_rman.rm_descr = "I/O memory addresses"; if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0)) panic("nexus_probe mem_rman"); return bus_generic_probe(dev); } static int nexus_attach(device_t dev) { device_t child; /* * First, deal with the children we know about already */ bus_generic_attach(dev); /* * And if we didn't see EISA or ISA on a pci bridge, create some * connection points now so they show up "on motherboard". */ if (!devclass_get_device(devclass_find("eisa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "eisa", 0); if (child == NULL) panic("nexus_attach eisa"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("mca"), 0)) { child = BUS_ADD_CHILD(dev, 0, "mca", 0); if (child == 0) panic("nexus_probe mca"); device_probe_and_attach(child); } if (!devclass_get_device(devclass_find("isa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "isa", 0); if (child == NULL) panic("nexus_attach isa"); device_probe_and_attach(child); } return 0; } static int nexus_print_resources(struct resource_list *rl, const char *name, int type, const char *format) { struct resource_list_entry *rle; int printed, retval; printed = 0; retval = 0; /* Yes, this is kinda cheating */ SLIST_FOREACH(rle, rl, link) { if (rle->type == type) { if (printed == 0) retval += printf(" %s ", name); else if (printed > 0) retval += printf(","); printed++; retval += printf(format, rle->start); if (rle->count > 1) { retval += printf("-"); retval += printf(format, rle->start + rle->count - 1); } } } return retval; } static int nexus_print_all_resources(device_t dev) { struct nexus_device *ndev = DEVTONX(dev); struct resource_list *rl = &ndev->nx_resources; int retval = 0; if (SLIST_FIRST(rl) || ndev->nx_pcibus != -1) retval += printf(" at"); retval += nexus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); retval += nexus_print_resources(rl, "iomem", SYS_RES_MEMORY, "%#lx"); retval += nexus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); return retval; } static int nexus_print_child(device_t bus, device_t child) { struct nexus_device *ndev = DEVTONX(child); int retval = 0; retval += bus_print_child_header(bus, child); retval += nexus_print_all_resources(child); if (ndev->nx_pcibus != -1) retval += printf(" pcibus %d", ndev->nx_pcibus); retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */ return (retval); } static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { device_t child; struct nexus_device *ndev; ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); if (!ndev) return(0); resource_list_init(&ndev->nx_resources); ndev->nx_pcibus = -1; child = device_add_child_ordered(bus, order, name, unit); /* should we free this in nexus_child_detached? */ device_set_ivars(child, ndev); return(child); } static int nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: *result = ndev->nx_pcibus; break; default: return ENOENT; } return 0; } static int nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) { struct nexus_device *ndev = DEVTONX(child); switch (which) { case NEXUS_IVAR_PCIBUS: ndev->nx_pcibus = value; break; default: return ENOENT; } return 0; } /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. * (Exceptions include npx.) */ static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct nexus_device *ndev = DEVTONX(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int needactivate = flags & RF_ACTIVE; /* * If this is an allocation of the "default" range for a given RID, and * we know what the resources for this device are (ie. they aren't maintained * by a child bus), then work out the start/end values. */ if ((start == 0UL) && (end == ~0UL) && (count == 1)) { if (ndev == NULL) return(NULL); rle = resource_list_find(&ndev->nx_resources, type, *rid); if (rle == NULL) return(NULL); start = rle->start; end = rle->end; count = rle->count; } flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_IRQ: rm = &irq_rman; break; case SYS_RES_DRQ: rm = &drq_rman; break; case SYS_RES_IOPORT: rm = &port_rman; break; case SYS_RES_MEMORY: rm = &mem_rman; break; default: return 0; } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) return 0; #ifdef PC98 /* Allocate bushandle. */ rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE, M_NOWAIT | M_ZERO); if (rv->r_bushandle == 0) { rman_release_resource(rv); return 0; } #endif if (type == SYS_RES_MEMORY) { rman_set_bustag(rv, I386_BUS_SPACE_MEM); } else if (type == SYS_RES_IOPORT) { rman_set_bustag(rv, I386_BUS_SPACE_IO); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ rv->r_bushandle->bsh_base = rv->r_start; - rv->r_bushandle->bsh_iat = NULL; + rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; rv->r_bushandle->bsh_iatsz = 0; rv->r_bushandle->bsh_res = NULL; rv->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(rv, rv->r_start); #endif } if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { #ifdef PC98 free(rv->r_bushandle, M_BUSSPACEHANDLE); #endif rman_release_resource(rv); return 0; } } return rv; } static int nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, map it into the kernel. */ if (rman_get_bustag(r) == I386_BUS_SPACE_MEM) { caddr_t vaddr = 0; if (rman_get_end(r) < 1024 * 1024) { /* * The first 1Mb is mapped at KERNBASE. */ vaddr = (caddr_t)(uintptr_t)(KERNBASE + rman_get_start(r)); } else { u_int32_t paddr; u_int32_t psize; u_int32_t poffs; paddr = rman_get_start(r); psize = rman_get_size(r); poffs = paddr - trunc_page(paddr); vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; } rman_set_virtual(r, vaddr); #ifdef PC98 /* PC-98: the type of bus_space_handle_t is the structure. */ r->r_bushandle->bsh_base = (bus_addr_t) vaddr; - r->r_bushandle->bsh_iat = NULL; + r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; r->r_bushandle->bsh_iatsz = 0; r->r_bushandle->bsh_res = NULL; r->r_bushandle->bsh_ressz = 0; + + /* default: direct access */ + r->r_bushandle->bsh_bam = r->r_bustag->bs_da; #else /* IBM-PC: the type of bus_space_handle_t is u_int */ rman_set_bushandle(r, (bus_space_handle_t) vaddr); #endif } return (rman_activate_resource(r)); } static int nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* * If this is a memory resource, unmap it. */ if ((rman_get_bustag(r) == I386_BUS_SPACE_MEM) && (rman_get_end(r) >= 1024 * 1024)) { u_int32_t psize; psize = rman_get_size(r); pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize); } return (rman_deactivate_resource(r)); } static int nexus_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { if (rman_get_flags(r) & RF_ACTIVE) { int error = bus_deactivate_resource(child, type, rid, r); if (error) return error; } #ifdef PC98 free(r->r_bushandle, M_BUSSPACEHANDLE); #endif return (rman_release_resource(r)); } /* * Currently this uses the really grody interface from kern/kern_intr.c * (which really doesn't belong in kern/anything.c). Eventually, all of * the code in kern_intr.c and machdep_intr.c should get moved here, since * this is going to be the official interface. */ static int nexus_setup_intr(device_t bus, device_t child, struct resource *irq, int flags, void (*ihand)(void *), void *arg, void **cookiep) { driver_t *driver; int error; /* somebody tried to setup an irq that failed to allocate! */ if (irq == NULL) panic("nexus_setup_intr: NULL irq resource!"); *cookiep = 0; if ((irq->r_flags & RF_SHAREABLE) == 0) flags |= INTR_EXCL; driver = device_get_driver(child); /* * We depend here on rman_activate_resource() being idempotent. */ error = rman_activate_resource(irq); if (error) return (error); error = inthand_add(device_get_nameunit(child), irq->r_start, ihand, arg, flags, cookiep); return (error); } static int nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) { return (inthand_remove(ih)); } static int nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; /* XXX this should return a success/failure indicator */ resource_list_add(rl, type, rid, start, start + count - 1, count); return(0); } static int nexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; struct resource_list_entry *rle; rle = resource_list_find(rl, type, rid); device_printf(child, "type %d rid %d startp %p countp %p - got %p\n", type, rid, startp, countp, rle); if (!rle) return(ENOENT); if (startp) *startp = rle->start; if (countp) *countp = rle->count; return(0); } static void nexus_delete_resource(device_t dev, device_t child, int type, int rid) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; resource_list_delete(rl, type, rid); } /* * Placeholder which claims PnP 'devices' which describe system * resources. */ static struct isa_pnp_id sysresource_ids[] = { { 0x010cd041 /* PNP0c01 */, "System Memory" }, { 0x020cd041 /* PNP0c02 */, "System Resource" }, { 0 } }; static int sysresource_probe(device_t dev) { int result; if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) { device_quiet(dev); } return(result); } static int sysresource_attach(device_t dev) { return(0); } static device_method_t sysresource_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sysresource_probe), DEVMETHOD(device_attach, sysresource_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), { 0, 0 } }; static driver_t sysresource_driver = { "sysresource", sysresource_methods, 1, /* no softc */ }; static devclass_t sysresource_devclass; DRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0); Index: head/sys/i386/include/bus_pio_ind.h =================================================================== --- head/sys/i386/include/bus_pio_ind.h (revision 84614) +++ head/sys/i386/include/bus_pio_ind.h (nonexistent) @@ -1,31 +0,0 @@ -/* - * Copyright (c) 1997 Justin Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _I386_BUS_PIO_IND_H_ -#define _I386_BUS_PIO_IND_H_ -#endif /* _I386_BUS_PIO_IND_H_ */ Property changes on: head/sys/i386/include/bus_pio_ind.h ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/sys/i386/include/bus_pc98.h =================================================================== --- head/sys/i386/include/bus_pc98.h (revision 84614) +++ head/sys/i386/include/bus_pc98.h (revision 84615) @@ -1,1446 +1,474 @@ +/* $FreeBSD$ */ +/* $NecBSD: busio.h,v 3.25.4.2.2.1 2000/06/12 03:53:08 honda Exp $ */ /* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ -/*- - * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. - * All rights reserved. +/* + * [NetBSD for NEC PC-98 series] + * Copyright (c) 1997, 1998 + * NetBSD/pc98 porting staff. All rights reserved. * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. + * [Ported for FreeBSD] + * Copyright (c) 2001 + * TAKAHASHI Yoshihiro. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright (c) 1996 Charles M. Hannum. All rights reserved. - * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. + * Copyright (c) 1997, 1998 + * Naofumi HONDA. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This module support generic bus address relocation mechanism. + * To reduce a function call overhead, we employ pascal call methods. */ -/* $FreeBSD$ */ #ifndef _I386_BUS_PC98_H_ #define _I386_BUS_PC98_H_ #include /* - * To remain compatible with NetBSD's interface, default to both memio and - * pio when neither of them is defined. - */ -#if !defined(_I386_BUS_PIO_H_) && !defined(_I386_BUS_PIO_IND_H_) && !defined(_I386_BUS_MEMIO_H_) -#define _I386_BUS_PIO_H_ -#define _I386_BUS_PIO_IND_H_ -#define _I386_BUS_MEMIO_H_ -#endif - -/* - * Values for the i386 bus space tag, not to be used directly by MI code. - */ -#define I386_BUS_SPACE_IO 0 /* space is i/o space */ -#define I386_BUS_SPACE_MEM 1 /* space is mem space */ -#define I386_BUS_SPACE_IO_IND 2 /* space is i/o space */ - -/* * Bus address and size types */ typedef u_int bus_addr_t; typedef u_int bus_size_t; #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF #define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */ #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF #define BUS_SPACE_MAXADDR 0xFFFFFFFF #define BUS_SPACE_UNRESTRICTED (~0) +#define BUS_SPACE_IAT_MAXSIZE 32 + /* * Access methods for bus resources and address space. */ struct resource; -typedef int bus_space_tag_t; -typedef struct { - bus_addr_t bsh_base; - bus_addr_t *bsh_iat; - size_t bsh_iatsz; - struct resource **bsh_res; - size_t bsh_ressz; -}* bus_space_handle_t; - /* - * Map a region of device bus space into CPU virtual address space. + * bus space tag */ +#define _PASCAL_CALL __P((void)) -#define BUS_SPACE_MAP_CACHEABLE 0x01 -#define BUS_SPACE_MAP_LINEAR 0x02 +#define _BUS_SPACE_CALL_FUNCS_TAB(NAME,TYPE,BWN) \ + NAME##_space_read_##BWN##, \ + NAME##_space_read_multi_##BWN##, \ + NAME##_space_read_region_##BWN##, \ + NAME##_space_write_##BWN##, \ + NAME##_space_write_multi_##BWN##, \ + NAME##_space_write_region_##BWN##, \ + NAME##_space_set_multi_##BWN##, \ + NAME##_space_set_region_##BWN##, \ + NAME##_space_copy_region_##BWN -int bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, - int flags, bus_space_handle_t *bshp); +#define _BUS_SPACE_CALL_FUNCS_PROTO(NAME,TYPE,BWN) \ + TYPE NAME##_space_read_##BWN _PASCAL_CALL; \ + void NAME##_space_read_multi_##BWN _PASCAL_CALL; \ + void NAME##_space_read_region_##BWN _PASCAL_CALL; \ + void NAME##_space_write_##BWN _PASCAL_CALL; \ + void NAME##_space_write_multi_##BWN _PASCAL_CALL; \ + void NAME##_space_write_region_##BWN _PASCAL_CALL; \ + void NAME##_space_set_multi_##BWN _PASCAL_CALL; \ + void NAME##_space_set_region_##BWN _PASCAL_CALL; \ + void NAME##_space_copy_region_##BWN _PASCAL_CALL; -/* - * Unmap a region of device bus space. - */ +#define _BUS_SPACE_CALL_FUNCS(NAME,TYPE,BWN) \ + TYPE (*##NAME##_read_##BWN) _PASCAL_CALL; \ + void (*##NAME##_read_multi_##BWN) _PASCAL_CALL; \ + void (*##NAME##_read_region_##BWN) _PASCAL_CALL; \ + void (*##NAME##_write_##BWN) _PASCAL_CALL; \ + void (*##NAME##_write_multi_##BWN) _PASCAL_CALL; \ + void (*##NAME##_write_region_##BWN) _PASCAL_CALL; \ + void (*##NAME##_set_multi_##BWN) _PASCAL_CALL; \ + void (*##NAME##_set_region_##BWN) _PASCAL_CALL; \ + void (*##NAME##_copy_region_##BWN) _PASCAL_CALL; -void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t size); +struct bus_space_access_methods { + /* 8 bits access methods */ + _BUS_SPACE_CALL_FUNCS(bs,u_int8_t,1) -/* - * Get a new handle for a subregion of an already-mapped area of bus space. - */ + /* 16 bits access methods */ + _BUS_SPACE_CALL_FUNCS(bs,u_int16_t,2) -int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t offset, bus_size_t size, - bus_space_handle_t *nbshp); + /* 32 bits access methods */ + _BUS_SPACE_CALL_FUNCS(bs,u_int32_t,4) +}; -/* - * Allocate a region of memory that is accessible to devices in bus space. - */ +struct bus_space_tag { +#define BUS_SPACE_IO 0 +#define BUS_SPACE_MEM 1 + u_int bs_tag; /* bus space flags */ -int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, - bus_addr_t rend, bus_size_t size, bus_size_t align, - bus_size_t boundary, int flags, bus_addr_t *addrp, - bus_space_handle_t *bshp); + struct bus_space_access_methods bs_da; /* direct access */ + struct bus_space_access_methods bs_ra; /* relocate access */ +#if 0 + struct bus_space_access_methods bs_ida; /* indexed direct access */ +#endif +}; +typedef struct bus_space_tag *bus_space_tag_t; /* - * Free a region of bus space accessible memory. + * Values for the i386 bus space tag, not to be used directly by MI code. */ +extern struct bus_space_tag SBUS_io_space_tag; +extern struct bus_space_tag SBUS_mem_space_tag; -void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t size); +#define I386_BUS_SPACE_IO (&SBUS_io_space_tag) +#define I386_BUS_SPACE_MEM (&SBUS_mem_space_tag) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - /* - * Read a 1, 2, 4, or 8 byte quantity from bus space - * described by tag/handle/offset. + * bus space handle */ -static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); +struct bus_space_handle { + bus_addr_t bsh_base; + bus_addr_t bsh_iat[BUS_SPACE_IAT_MAXSIZE]; + size_t bsh_maxiatsz; + size_t bsh_iatsz; -static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); + struct resource **bsh_res; + size_t bsh_ressz; -static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); + struct bus_space_access_methods bsh_bam; +}; +typedef struct bus_space_handle *bus_space_handle_t; -static __inline u_int8_t -bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - return (inb(bsh->bsh_base + offset)); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - return (inb(bsh->bsh_iat[offset])); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - else -#endif - return (*(volatile u_int8_t *)(bsh->bsh_base + offset)); -#endif -} - -static __inline u_int16_t -bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - return (inw(bsh->bsh_base + offset)); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - return (inw(bsh->bsh_iat[offset])); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - else -#endif - return (*(volatile u_int16_t *)(bsh->bsh_base + offset)); -#endif -} - -static __inline u_int32_t -bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - return (inl(bsh->bsh_base + offset)); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - return (inl(bsh->bsh_iat[offset])); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - else -#endif - return (*(volatile u_int32_t *)(bsh->bsh_base + offset)); -#endif -} - -#if 0 /* Cause a link error for bus_space_read_8 */ -#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! -#endif - /* - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle/offset and copy into buffer provided. + * Access methods for bus resources and address space. */ -static __inline void bus_space_read_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, - size_t count); +#define _BUS_ACCESS_METHODS_PROTO(TYPE,BWN) \ + static __inline TYPE bus_space_read_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, bus_size_t offset)); \ + static __inline void bus_space_read_multi_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, \ + bus_size_t, TYPE *, size_t)); \ + static __inline void bus_space_read_region_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, \ + bus_size_t, TYPE *, size_t)); \ + static __inline void bus_space_write_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE)); \ + static __inline void bus_space_write_multi_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, \ + bus_size_t, const TYPE *, size_t)); \ + static __inline void bus_space_write_region_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, \ + bus_size_t, const TYPE *, size_t)); \ + static __inline void bus_space_set_multi_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t));\ + static __inline void bus_space_set_region_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t));\ + static __inline void bus_space_copy_region_##BWN \ + __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, \ + bus_space_handle_t, bus_size_t, size_t)); -static __inline void bus_space_read_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, - size_t count); +_BUS_ACCESS_METHODS_PROTO(u_int8_t,1) +_BUS_ACCESS_METHODS_PROTO(u_int16_t,2) +_BUS_ACCESS_METHODS_PROTO(u_int32_t,4) -static __inline void bus_space_read_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, - size_t count); - -static __inline void -bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - insb(bsh->bsh_base + offset, addr, count); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - insb(bsh->bsh_iat[offset], addr, count); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - __asm __volatile(" \n\ - cld \n\ - 1: movb (%2),%%al \n\ - stosb \n\ - loop 1b" : - "=D" (addr), "=c" (count) : - "r" (bsh->bsh_base + offset), "0" (addr), "1" (count) : - "%eax", "memory"); - } -#endif +/* + * read methods + */ +#define _BUS_SPACE_READ(TYPE,BWN) \ +static __inline TYPE \ +bus_space_read_##BWN##(tag, bsh, offset) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ +{ \ + register TYPE result; \ + \ + __asm __volatile("call *%2" \ + :"=a" (result), \ + "=d" (offset) \ + :"o" (bsh->bsh_bam.bs_read_##BWN), \ + "b" (bsh), \ + "1" (offset) \ + ); \ + \ + return result; \ } -static __inline void -bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - insw(bsh->bsh_base + offset, addr, count); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - insw(bsh->bsh_iat[offset], addr, count); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - __asm __volatile(" \n\ - cld \n\ - 1: movw (%2),%%ax \n\ - stosw \n\ - loop 1b" : - "=D" (addr), "=c" (count) : - "r" (bsh->bsh_base + offset), "0" (addr), "1" (count) : - "%eax", "memory"); - } -#endif -} +_BUS_SPACE_READ(u_int8_t,1) +_BUS_SPACE_READ(u_int16_t,2) +_BUS_SPACE_READ(u_int32_t,4) -static __inline void -bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - insl(bsh->bsh_base + offset, addr, count); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - insl(bsh->bsh_iat[offset], addr, count); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - __asm __volatile(" \n\ - cld \n\ - 1: movl (%2),%%eax \n\ - stosl \n\ - loop 1b" : - "=D" (addr), "=c" (count) : - "r" (bsh->bsh_base + offset), "0" (addr), "1" (count) : - "%eax", "memory"); - } -#endif -} - -#if 0 /* Cause a link error for bus_space_read_multi_8 */ -#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! -#endif - /* - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle and starting at `offset' and copy into - * buffer provided. + * write methods */ -static __inline void bus_space_read_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, - size_t count); +#define _BUS_SPACE_WRITE(TYPE,BWN) \ +static __inline void \ +bus_space_write_##BWN##(tag, bsh, offset, val) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ + TYPE val; \ +{ \ + \ + __asm __volatile("call *%1" \ + :"=d" (offset) \ + :"o" (bsh->bsh_bam.bs_write_##BWN), \ + "a" (val), \ + "b" (bsh), \ + "0" (offset) \ + ); \ +} -static __inline void bus_space_read_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, - size_t count); +_BUS_SPACE_WRITE(u_int8_t,1) +_BUS_SPACE_WRITE(u_int16_t,2) +_BUS_SPACE_WRITE(u_int32_t,4) -static __inline void bus_space_read_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, - size_t count); - - -static __inline void -bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - 1: inb %w2,%%al \n\ - stosb \n\ - incl %2 \n\ - loop 1b" : - "=D" (addr), "=c" (count), "=d" (_port_) : - "0" (addr), "1" (count), "2" (_port_) : - "%eax", "memory", "cc"); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - int i; - for (i = 0; i < count; i++) - addr[i] = inb(bsh->bsh_iat[offset + i]); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - repne \n\ - movsb" : - "=D" (addr), "=c" (count), "=S" (_port_) : - "0" (addr), "1" (count), "2" (_port_) : - "memory", "cc"); - } -#endif +/* + * multi read + */ +#define _BUS_SPACE_READ_MULTI(TYPE,BWN) \ +static __inline void \ +bus_space_read_multi_##BWN##(tag, bsh, offset, buf, cnt) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ + TYPE *buf; \ + size_t cnt; \ +{ \ + \ + __asm __volatile("call *%3" \ + :"=c" (cnt), \ + "=d" (offset), \ + "=D" (buf) \ + :"o" (bsh->bsh_bam.bs_read_multi_##BWN), \ + "b" (bsh), \ + "0" (cnt), \ + "1" (offset), \ + "2" (buf) \ + :"memory"); \ } -static __inline void -bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - 1: inw %w2,%%ax \n\ - stosw \n\ - addl $2,%2 \n\ - loop 1b" : - "=D" (addr), "=c" (count), "=d" (_port_) : - "0" (addr), "1" (count), "2" (_port_) : - "%eax", "memory", "cc"); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - int i; - for (i = 0; i < count; i += 2) - addr[i] = inw(bsh->bsh_iat[offset + i]); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - repne \n\ - movsw" : - "=D" (addr), "=c" (count), "=S" (_port_) : - "0" (addr), "1" (count), "2" (_port_) : - "memory", "cc"); - } -#endif -} +_BUS_SPACE_READ_MULTI(u_int8_t,1) +_BUS_SPACE_READ_MULTI(u_int16_t,2) +_BUS_SPACE_READ_MULTI(u_int32_t,4) -static __inline void -bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - 1: inl %w2,%%eax \n\ - stosl \n\ - addl $4,%2 \n\ - loop 1b" : - "=D" (addr), "=c" (count), "=d" (_port_) : - "0" (addr), "1" (count), "2" (_port_) : - "%eax", "memory", "cc"); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - int i; - for (i = 0; i < count; i += 4) - addr[i] = inl(bsh->bsh_iat[offset + i]); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - repne \n\ - movsl" : - "=D" (addr), "=c" (count), "=S" (_port_) : - "0" (addr), "1" (count), "2" (_port_) : - "memory", "cc"); - } -#endif -} - -#if 0 /* Cause a link error for bus_space_read_region_8 */ -#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! -#endif - /* - * Write the 1, 2, 4, or 8 byte value `value' to bus space - * described by tag/handle/offset. + * multi write */ - -static __inline void bus_space_write_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value); - -static __inline void bus_space_write_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value); - -static __inline void bus_space_write_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value); - -static __inline void -bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - outb(bsh->bsh_base + offset, value); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - outb(bsh->bsh_iat[offset], value); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - *(volatile u_int8_t *)(bsh->bsh_base + offset) = value; -#endif +#define _BUS_SPACE_WRITE_MULTI(TYPE,BWN) \ +static __inline void \ +bus_space_write_multi_##BWN##(tag, bsh, offset, buf, cnt) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ + const TYPE *buf; \ + size_t cnt; \ +{ \ + \ + __asm __volatile("call *%3" \ + :"=c" (cnt), \ + "=d" (offset), \ + "=S" (buf) \ + :"o" (bsh->bsh_bam.bs_write_multi_##BWN), \ + "b" (bsh), \ + "0" (cnt), \ + "1" (offset), \ + "2" (buf) \ + ); \ } -static __inline void -bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - outw(bsh->bsh_base + offset, value); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - outw(bsh->bsh_iat[offset], value); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - *(volatile u_int16_t *)(bsh->bsh_base + offset) = value; -#endif -} +_BUS_SPACE_WRITE_MULTI(u_int8_t,1) +_BUS_SPACE_WRITE_MULTI(u_int16_t,2) +_BUS_SPACE_WRITE_MULTI(u_int32_t,4) -static __inline void -bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - outl(bsh->bsh_base + offset, value); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - outl(bsh->bsh_iat[offset], value); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - *(volatile u_int32_t *)(bsh->bsh_base + offset) = value; -#endif -} - -#if 0 /* Cause a link error for bus_space_write_8 */ -#define bus_space_write_8 !!! bus_space_write_8 not implemented !!! -#endif - /* - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer - * provided to bus space described by tag/handle/offset. + * region read */ - -static __inline void bus_space_write_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static __inline void bus_space_write_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count); - -static __inline void bus_space_write_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int32_t *addr, - size_t count); - -static __inline void -bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - outsb(bsh->bsh_base + offset, addr, count); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - outsb(bsh->bsh_iat[offset], addr, count); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - __asm __volatile(" \n\ - cld \n\ - 1: lodsb \n\ - movb %%al,(%2) \n\ - loop 1b" : - "=S" (addr), "=c" (count) : - "r" (bsh->bsh_base + offset), "0" (addr), "1" (count) : - "%eax", "memory", "cc"); - } -#endif +#define _BUS_SPACE_READ_REGION(TYPE,BWN) \ +static __inline void \ +bus_space_read_region_##BWN##(tag, bsh, offset, buf, cnt) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ + TYPE *buf; \ + size_t cnt; \ +{ \ + \ + __asm __volatile("call *%3" \ + :"=c" (cnt), \ + "=d" (offset), \ + "=D" (buf) \ + :"o" (bsh->bsh_bam.bs_read_region_##BWN), \ + "b" (bsh), \ + "0" (cnt), \ + "1" (offset), \ + "2" (buf) \ + :"memory"); \ } -static __inline void -bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - outsw(bsh->bsh_base + offset, addr, count); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - outsw(bsh->bsh_iat[offset], addr, count); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - __asm __volatile(" \n\ - cld \n\ - 1: lodsw \n\ - movw %%ax,(%2) \n\ - loop 1b" : - "=S" (addr), "=c" (count) : - "r" (bsh->bsh_base + offset), "0" (addr), "1" (count) : - "%eax", "memory", "cc"); - } -#endif -} +_BUS_SPACE_READ_REGION(u_int8_t,1) +_BUS_SPACE_READ_REGION(u_int16_t,2) +_BUS_SPACE_READ_REGION(u_int32_t,4) -static __inline void -bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - outsl(bsh->bsh_base + offset, addr, count); -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - outsl(bsh->bsh_iat[offset], addr, count); -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - __asm __volatile(" \n\ - cld \n\ - 1: lodsl \n\ - movl %%eax,(%2) \n\ - loop 1b" : - "=S" (addr), "=c" (count) : - "r" (bsh->bsh_base + offset), "0" (addr), "1" (count) : - "%eax", "memory", "cc"); - } -#endif -} - -#if 0 /* Cause a link error for bus_space_write_multi_8 */ -#define bus_space_write_multi_8(t, h, o, a, c) \ - !!! bus_space_write_multi_8 unimplemented !!! -#endif - /* - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided - * to bus space described by tag/handle starting at `offset'. + * region write */ - -static __inline void bus_space_write_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static __inline void bus_space_write_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count); -static __inline void bus_space_write_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int32_t *addr, - size_t count); - -static __inline void -bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - 1: lodsb \n\ - outb %%al,%w0 \n\ - incl %0 \n\ - loop 1b" : - "=d" (_port_), "=S" (addr), "=c" (count) : - "0" (_port_), "1" (addr), "2" (count) : - "%eax", "memory", "cc"); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - int i; - for (i = 0; i < count; i++) - outb(bsh->bsh_iat[offset + i], addr[i]); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - repne \n\ - movsb" : - "=D" (_port_), "=S" (addr), "=c" (count) : - "0" (_port_), "1" (addr), "2" (count) : - "memory", "cc"); - } -#endif +#define _BUS_SPACE_WRITE_REGION(TYPE,BWN) \ +static __inline void \ +bus_space_write_region_##BWN##(tag, bsh, offset, buf, cnt) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ + const TYPE *buf; \ + size_t cnt; \ +{ \ + \ + __asm __volatile("call *%3" \ + :"=c" (cnt), \ + "=d" (offset), \ + "=S" (buf) \ + :"o" (bsh->bsh_bam.bs_write_region_##BWN), \ + "b" (bsh), \ + "0" (cnt), \ + "1" (offset), \ + "2" (buf) \ + ); \ } -static __inline void -bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - 1: lodsw \n\ - outw %%ax,%w0 \n\ - addl $2,%0 \n\ - loop 1b" : - "=d" (_port_), "=S" (addr), "=c" (count) : - "0" (_port_), "1" (addr), "2" (count) : - "%eax", "memory", "cc"); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - int i; - for (i = 0; i < count; i += 2) - outw(bsh->bsh_iat[offset + i], addr[i]); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - repne \n\ - movsw" : - "=D" (_port_), "=S" (addr), "=c" (count) : - "0" (_port_), "1" (addr), "2" (count) : - "memory", "cc"); - } -#endif -} +_BUS_SPACE_WRITE_REGION(u_int8_t,1) +_BUS_SPACE_WRITE_REGION(u_int16_t,2) +_BUS_SPACE_WRITE_REGION(u_int32_t,4) -static __inline void -bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - 1: lodsl \n\ - outl %%eax,%w0 \n\ - addl $4,%0 \n\ - loop 1b" : - "=d" (_port_), "=S" (addr), "=c" (count) : - "0" (_port_), "1" (addr), "2" (count) : - "%eax", "memory", "cc"); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - int i; - for (i = 0; i < count; i += 4) - outl(bsh->bsh_iat[offset + i], addr[i]); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - int _port_ = bsh->bsh_base + offset; \ - __asm __volatile(" \n\ - cld \n\ - repne \n\ - movsl" : - "=D" (_port_), "=S" (addr), "=c" (count) : - "0" (_port_), "1" (addr), "2" (count) : - "memory", "cc"); - } -#endif -} - -#if 0 /* Cause a link error for bus_space_write_region_8 */ -#define bus_space_write_region_8 \ - !!! bus_space_write_region_8 unimplemented !!! -#endif - /* - * Write the 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle/offset `count' times. + * multi set */ - -static __inline void bus_space_set_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int8_t value, size_t count); -static __inline void bus_space_set_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int16_t value, size_t count); -static __inline void bus_space_set_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int32_t value, size_t count); - -static __inline void -bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - while (count--) - outb(addr, value); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - bus_addr_t addr = bsh->bsh_iat[offset]; - while (count--) - outb(addr, value); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - while (count--) - *(volatile u_int8_t *)(addr) = value; - } -#endif +#define _BUS_SPACE_SET_MULTI(TYPE,BWN) \ +static __inline void \ +bus_space_set_multi_##BWN##(tag, bsh, offset, val, cnt) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ + TYPE val; \ + size_t cnt; \ +{ \ + \ + __asm __volatile("call *%2" \ + :"=c" (cnt), \ + "=d" (offset) \ + :"o" (bsh->bsh_bam.bs_set_multi_##BWN), \ + "a" (val), \ + "b" (bsh), \ + "0" (cnt), \ + "1" (offset) \ + ); \ } -static __inline void -bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - while (count--) - outw(addr, value); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - bus_addr_t addr = bsh->bsh_iat[offset]; - while (count--) - outw(addr, value); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - while (count--) - *(volatile u_int16_t *)(addr) = value; - } -#endif -} +_BUS_SPACE_SET_MULTI(u_int8_t,1) +_BUS_SPACE_SET_MULTI(u_int16_t,2) +_BUS_SPACE_SET_MULTI(u_int32_t,4) -static __inline void -bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - while (count--) - outl(addr, value); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - bus_addr_t addr = bsh->bsh_iat[offset]; - while (count--) - outl(addr, value); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - while (count--) - *(volatile u_int32_t *)(addr) = value; - } -#endif -} - -#if 0 /* Cause a link error for bus_space_set_multi_8 */ -#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! -#endif - /* - * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle starting at `offset'. + * region set */ - -static __inline void bus_space_set_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, - size_t count); -static __inline void bus_space_set_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, - size_t count); -static __inline void bus_space_set_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, - size_t count); - -static __inline void -bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - for (; count != 0; count--, addr++) - outb(addr, value); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - for (; count != 0; count--, offset++) - outb(bsh->bsh_iat[offset], value); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - for (; count != 0; count--, addr++) - *(volatile u_int8_t *)(addr) = value; - } -#endif +#define _BUS_SPACE_SET_REGION(TYPE,BWN) \ +static __inline void \ +bus_space_set_region_##BWN##(tag, bsh, offset, val, cnt) \ + bus_space_tag_t tag; \ + bus_space_handle_t bsh; \ + bus_size_t offset; \ + TYPE val; \ + size_t cnt; \ +{ \ + \ + __asm __volatile("call *%2" \ + :"=c" (cnt), \ + "=d" (offset) \ + :"o" (bsh->bsh_bam.bs_set_region_##BWN), \ + "a" (val), \ + "b" (bsh), \ + "0" (cnt), \ + "1" (offset) \ + ); \ } -static __inline void -bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - for (; count != 0; count--, addr += 2) - outw(addr, value); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - for (; count != 0; count--, offset += 2) - outw(bsh->bsh_iat[offset], value); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - for (; count != 0; count--, addr += 2) - *(volatile u_int16_t *)(addr) = value; - } -#endif -} +_BUS_SPACE_SET_REGION(u_int8_t,1) +_BUS_SPACE_SET_REGION(u_int16_t,2) +_BUS_SPACE_SET_REGION(u_int32_t,4) -static __inline void -bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - for (; count != 0; count--, addr += 4) - outl(addr, value); - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - for (; count != 0; count--, offset += 4) - outl(bsh->bsh_iat[offset], value); - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr = bsh->bsh_base + offset; - for (; count != 0; count--, addr += 4) - *(volatile u_int32_t *)(addr) = value; - } -#endif -} - -#if 0 /* Cause a link error for bus_space_set_region_8 */ -#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! -#endif - /* - * Copy `count' 1, 2, 4, or 8 byte values from bus space starting - * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. + * copy */ - -static __inline void bus_space_copy_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void bus_space_copy_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void bus_space_copy_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void -bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr1 = bsh1->bsh_base + off1; - bus_addr_t addr2 = bsh2->bsh_base + off2; - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1++, addr2++) - outb(addr2, inb(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += (count - 1), addr2 += (count - 1); - count != 0; count--, addr1--, addr2--) - outb(addr2, inb(addr1)); - } - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - if (bsh1->bsh_iat[off1] >= bsh2->bsh_iat[off2]) { - /* src after dest: copy forward */ - for (; count != 0; count--, off1++, off2++) - outb(bsh2->bsh_iat[off2], - inb(bsh1->bsh_iat[off1])); - } else { - /* dest after src: copy backwards */ - for (off1 += (count - 1), off2 += (count - 1); - count != 0; count--, off1--, off2--) - outb(bsh2->bsh_iat[off2], - inb(bsh1->bsh_iat[off1])); - } - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr1 = bsh1->bsh_base + off1; - bus_addr_t addr2 = bsh2->bsh_base + off2; - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1++, addr2++) - *(volatile u_int8_t *)(addr2) = - *(volatile u_int8_t *)(addr1); - } else { - /* dest after src: copy backwards */ - for (addr1 += (count - 1), addr2 += (count - 1); - count != 0; count--, addr1--, addr2--) - *(volatile u_int8_t *)(addr2) = - *(volatile u_int8_t *)(addr1); - } - } -#endif +#define _BUS_SPACE_COPY_REGION(BWN) \ +static __inline void \ +bus_space_copy_region_##BWN##(tag, sbsh, src, dbsh, dst, cnt) \ + bus_space_tag_t tag; \ + bus_space_handle_t sbsh; \ + bus_size_t src; \ + bus_space_handle_t dbsh; \ + bus_size_t dst; \ + size_t cnt; \ +{ \ + \ + if (dbsh->bsh_bam.bs_copy_region_1 != sbsh->bsh_bam.bs_copy_region_1) \ + panic("bus_space_copy_region: funcs mismatch (ENOSUPPORT)");\ + \ + __asm __volatile("call *%3" \ + :"=c" (cnt), \ + "=S" (src), \ + "=D" (dst) \ + :"o" (dbsh->bsh_bam.bs_copy_region_##BWN), \ + "a" (sbsh), \ + "b" (dbsh), \ + "0" (cnt), \ + "1" (src), \ + "2" (dst) \ + ); \ } -static __inline void -bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr1 = bsh1->bsh_base + off1; - bus_addr_t addr2 = bsh2->bsh_base + off2; - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 2, addr2 += 2) - outw(addr2, inw(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); - count != 0; count--, addr1 -= 2, addr2 -= 2) - outw(addr2, inw(addr1)); - } - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - if (bsh1->bsh_iat[off1] >= bsh2->bsh_iat[off2]) { - /* src after dest: copy forward */ - for (; count != 0; count--, off1 += 2, off2 += 2) - outw(bsh2->bsh_iat[off2], - inw(bsh1->bsh_iat[off1])); - } else { - /* dest after src: copy backwards */ - for (off1 += 2 * (count - 1), off2 += 2 * (count - 1); - count != 0; count--, off1 -= 2, off2 -= 2) - outw(bsh2->bsh_iat[off2], - inw(bsh1->bsh_iat[off1])); - } - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr1 = bsh1->bsh_base + off1; - bus_addr_t addr2 = bsh2->bsh_base + off2; - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 2, addr2 += 2) - *(volatile u_int16_t *)(addr2) = - *(volatile u_int16_t *)(addr1); - } else { - /* dest after src: copy backwards */ - for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); - count != 0; count--, addr1 -= 2, addr2 -= 2) - *(volatile u_int16_t *)(addr2) = - *(volatile u_int16_t *)(addr1); - } - } -#endif -} - -static __inline void -bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ -#if defined(_I386_BUS_PIO_H_) -#if defined(_I386_BUS_PIO_IND_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO) -#endif - { - bus_addr_t addr1 = bsh1->bsh_base + off1; - bus_addr_t addr2 = bsh2->bsh_base + off2; - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 4, addr2 += 4) - outl(addr2, inl(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); - count != 0; count--, addr1 -= 4, addr2 -= 4) - outl(addr2, inl(addr1)); - } - } -#endif -#if defined(_I386_BUS_PIO_IND_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) - if (tag == I386_BUS_SPACE_IO_IND) -#endif - { - if (bsh1->bsh_iat[off1] >= bsh2->bsh_iat[off2]) { - /* src after dest: copy forward */ - for (; count != 0; count--, off1 += 4, off2 += 4) - outl(bsh2->bsh_iat[off2], - inl(bsh1->bsh_iat[off1])); - } else { - /* dest after src: copy backwards */ - for (off1 += 4 * (count - 1), off2 += 4 * (count - 1); - count != 0; count--, off1 -= 4, off2 -= 4) - outl(bsh2->bsh_iat[off2], - inl(bsh1->bsh_iat[off1])); - } - } -#endif -#if defined(_I386_BUS_MEMIO_H_) -#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_PIO_IND_H_) - if (tag == I386_BUS_SPACE_MEM) -#endif - { - bus_addr_t addr1 = bsh1->bsh_base + off1; - bus_addr_t addr2 = bsh2->bsh_base + off2; - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 4, addr2 += 4) - *(volatile u_int32_t *)(addr2) = - *(volatile u_int32_t *)(addr1); - } else { - /* dest after src: copy backwards */ - for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); - count != 0; count--, addr1 -= 4, addr2 -= 4) - *(volatile u_int32_t *)(addr2) = - *(volatile u_int32_t *)(addr1); - } - } -#endif -} - -#endif /* defined(_I386_BUS_PIO_H_) || defined(_I386_MEM_IO_H_) */ - -#if 0 /* Cause a link error for bus_space_copy_8 */ -#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! -#endif +_BUS_SPACE_COPY_REGION(1) +_BUS_SPACE_COPY_REGION(2) +_BUS_SPACE_COPY_REGION(4) /* * Bus read/write barrier methods. * * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, * bus_size_t offset, bus_size_t len, int flags); * * * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than * prevent reordering by the compiler; all Intel x86 processors currently * retire operations outside the CPU in program order. */ #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ static __inline void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, bus_size_t len, int flags) { if (flags & BUS_SPACE_BARRIER_READ) __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory"); else __asm __volatile("" : : : "memory"); } #endif /* _I386_BUS_PC98_H_ */ Index: head/sys/i386/isa/isa.c =================================================================== --- head/sys/i386/isa/isa.c (revision 84614) +++ head/sys/i386/isa/isa.c (revision 84615) @@ -1,261 +1,264 @@ /*- * Copyright (c) 1998 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Modifications for Intel architecture by Garrett A. Wollman. * Copyright 1998 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include void isa_init(void) { } /* * This implementation simply passes the request up to the parent * bus, which in our case is the special i386 nexus, substituting any * configured values if the caller defaulted. We can get away with * this because there is no special mapping for ISA resources on an Intel * platform. When porting this code to another architecture, it may be * necessary to interpose a mapping layer here. */ struct resource * isa_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { /* * Consider adding a resource definition. We allow rid 0-1 for * irq and drq, 0-3 for memory and 0-7 for ports which is * sufficient for isapnp. */ int passthrough = (device_get_parent(child) != bus); int isdefault = (start == 0UL && end == ~0UL); struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; struct resource_list_entry *rle; if (!passthrough && !isdefault) { rle = resource_list_find(rl, type, *rid); if (!rle) { if (*rid < 0) return 0; switch (type) { case SYS_RES_IRQ: if (*rid >= ISA_NIRQ) return 0; break; case SYS_RES_DRQ: if (*rid >= ISA_NDRQ) return 0; break; case SYS_RES_MEMORY: if (*rid >= ISA_NMEM) return 0; break; case SYS_RES_IOPORT: if (*rid >= ISA_NPORT) return 0; break; default: return 0; } resource_list_add(rl, type, *rid, start, end, count); } } return resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags); } #ifdef PC98 /* * Indirection support. The type of bus_space_handle_t is * defined in sys/i386/include/bus_pc98.h. */ struct resource * isa_alloc_resourcev(device_t child, int type, int *rid, bus_addr_t *res, bus_size_t count, u_int flags) { struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; device_t bus = device_get_parent(child); bus_addr_t start; struct resource *re; struct resource **bsre; int i, j, k, linear_cnt, ressz, bsrid; start = bus_get_resource_start(child, type, *rid); linear_cnt = count; ressz = 1; for (i = 1; i < count; ++i) { if (res[i] != res[i - 1] + 1) { if (i < linear_cnt) linear_cnt = i; ++ressz; } } re = isa_alloc_resource(bus, child, type, rid, start + res[0], start + res[linear_cnt - 1], linear_cnt, flags); if (re == NULL) return NULL; bsre = malloc(sizeof (struct resource *) * ressz, M_DEVBUF, M_NOWAIT); if (bsre == NULL) { resource_list_release(rl, bus, child, type, *rid, re); return NULL; } bsre[0] = re; for (i = linear_cnt, k = 1; i < count; i = j, k++) { for (j = i + 1; j < count; j++) { if (res[j] != res[j - 1] + 1) break; } bsrid = *rid + k; bsre[k] = isa_alloc_resource(bus, child, type, &bsrid, start + res[i], start + res[j - 1], j - i, flags); if (bsre[k] == NULL) { for (k--; k >= 0; k--) resource_list_release(rl, bus, child, type, *rid + k, bsre[k]); free(bsre, M_DEVBUF); return NULL; } } re->r_bushandle->bsh_res = bsre; re->r_bushandle->bsh_ressz = ressz; return re; } int isa_load_resourcev(struct resource *re, bus_addr_t *res, bus_size_t count) { - bus_addr_t *addr; + bus_addr_t start; int i; - addr = malloc(sizeof (bus_addr_t) * count, M_DEVBUF, M_NOWAIT); - if (addr == NULL) - return 1; + if (count > re->r_bushandle->bsh_maxiatsz) { + printf("isa_load_resourcev: map size too large\n"); + return EINVAL; + } - for (i = 0; i < count; i++) - addr[i] = rman_get_start(re) + res[i]; + start = rman_get_start(re); + for (i = 0; i < re->r_bushandle->bsh_maxiatsz; i++) { + if (i < count) + re->r_bushandle->bsh_iat[i] = start + res[i]; + else + re->r_bushandle->bsh_iat[i] = start; + } - rman_set_bustag(re, I386_BUS_SPACE_IO_IND); - re->r_bushandle->bsh_iat = addr; re->r_bushandle->bsh_iatsz = count; + re->r_bushandle->bsh_bam = re->r_bustag->bs_ra; /* relocate access */ return 0; } #endif /* PC98 */ int isa_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; #ifdef PC98 /* * Indirection support. The type of bus_space_handle_t is * defined in sys/i386/include/bus_pc98.h. */ int i; for (i = 1; i < r->r_bushandle->bsh_ressz; i++) resource_list_release(rl, bus, child, type, rid + i, r->r_bushandle->bsh_res[i]); if (r->r_bushandle->bsh_res != NULL) free(r->r_bushandle->bsh_res, M_DEVBUF); - if (r->r_bushandle->bsh_iat != NULL) - free(r->r_bushandle->bsh_iat, M_DEVBUF); #endif return resource_list_release(rl, bus, child, type, rid, r); } /* * We can't use the bus_generic_* versions of these methods because those * methods always pass the bus param as the requesting device, and we need * to pass the child (the i386 nexus knows about this and is prepared to * deal). */ int isa_setup_intr(device_t bus, device_t child, struct resource *r, int flags, void (*ihand)(void *), void *arg, void **cookiep) { return (BUS_SETUP_INTR(device_get_parent(bus), child, r, flags, ihand, arg, cookiep)); } int isa_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie) { return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie)); } Index: head/sys/pc98/i386/busio.s =================================================================== --- head/sys/pc98/i386/busio.s (nonexistent) +++ head/sys/pc98/i386/busio.s (revision 84615) @@ -0,0 +1,1671 @@ +/* $FreeBSD$ */ +/* $NecBSD: busio.s,v 1.16.4.1 1999/08/16 09:06:08 kmatsuda Exp $ */ +/* $NetBSD$ */ + +/* + * [NetBSD for NEC PC-98 series] + * Copyright (c) 1996, 1997, 1998 + * NetBSD/pc98 porting staff. All rights reserved. + * + * [Ported for FreeBSD] + * Copyright (c) 2001 + * TAKAHASHI Yoshihiro. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1997, 1998 + * Naofumi HONDA. All rights reserved. + */ + +#include + +#include "assym.s" + +/*********************************************************** + * Bus IO access methods (Direct Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + addl BUS_SPACE_HANDLE_BASE/**/(%/**/BSHREG/**/),%/**/ADDRREG + +/* + * read_N + * IN: edx port + * OUT: eax data + */ +ENTRY(SBUS_DA_io_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + inb %dx,%al + ret + +ENTRY(SBUS_DA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + inw %dx,%ax + ret + +ENTRY(SBUS_DA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + inl %dx,%eax + ret + +/* + * write_N + * IN:eax DATA + * edx PORT + */ +ENTRY(SBUS_DA_io_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + outb %al,%dx + ret + +ENTRY(SBUS_DA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + outw %ax,%dx + ret + +ENTRY(SBUS_DA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + outl %eax,%dx + ret + +/* + * read_multi_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_DA_io_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insb + ret + +ENTRY(SBUS_DA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insw + ret + +ENTRY(SBUS_DA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insl + ret + +/* + * write_multi_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_DA_io_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsb + ret + +ENTRY(SBUS_DA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsw + ret + +ENTRY(SBUS_DA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsl + ret + +/* + * read_region_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_DA_io_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inb %dx,%al + stosb + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inw %dx,%ax + stosw + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inl %dx,%eax + stosl + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_region_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_DA_io_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * set_multi_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_DA_io_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_DA_io_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + ret + +/* + * copy_region_N + * IN: ecx COUNT + * esi SPORT + * edi DPORT + */ +ENTRY(SBUS_DA_io_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inb %dx,%al + incl %esi + + movl %edi,%edx + outb %al,%dx + incl %edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_DA_io_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inw %dx,%ax + addl $2,%esi + + movl %edi,%edx + outw %ax,%dx + addl $2,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_DA_io_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inl %dx,%eax + addl $4,%esi + + movl %edi,%edx + outl %eax,%dx + addl $4,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +/*********************************************************** + * Bus Memory access methods (Direct Access) + ***********************************************************/ +/* + * read_N + */ +ENTRY(SBUS_DA_mem_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + movb (%edx),%al + ret + +ENTRY(SBUS_DA_mem_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + movw (%edx),%ax + ret + +ENTRY(SBUS_DA_mem_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + movl (%edx),%eax + ret + +/* + * write_N + */ +ENTRY(SBUS_DA_mem_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + movb %al,(%edx) + ret + +ENTRY(SBUS_DA_mem_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + movw %ax,(%edx) + ret + +ENTRY(SBUS_DA_mem_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + movl %eax,(%edx) + ret + +/* + * read_multi_N + */ +ENTRY(SBUS_DA_mem_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movb (%edx),%al + stosb + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movw (%edx),%ax + stosw + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movl (%edx),%eax + stosl + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_multi_N + */ +ENTRY(SBUS_DA_mem_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + movb %al,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * read_region_N + */ +ENTRY(SBUS_DA_mem_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsb + popl %esi + ret + +ENTRY(SBUS_DA_mem_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsw + popl %esi + ret + +ENTRY(SBUS_DA_mem_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsl + popl %esi + ret + +/* + * write_region_N + */ +ENTRY(SBUS_DA_mem_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsb + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsw + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsl + popl %edi + ret + +/* + * set_multi_N + */ +ENTRY(SBUS_DA_mem_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movb %al,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_mem_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_mem_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + */ +ENTRY(SBUS_DA_mem_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosb + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosw + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosl + popl %edi + ret + +/* + * copy_region_N + */ +ENTRY(SBUS_DA_mem_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsb + ret + +ENTRY(SBUS_DA_mem_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsw + ret + +ENTRY(SBUS_DA_mem_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsl + ret + +#undef BUS_ACCESS_ADDR + +/*********************************************************** + * Bus IO access methods (Relocate Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + movl BUS_SPACE_HANDLE_IAT/**/(%/**/BSHREG/**/, %/**/ADDRREG/**/, 4), \ + %/**/ADDRREG +/* + * read_N + * IN: edx port + * OUT: eax data + */ +ENTRY(SBUS_RA_io_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + inb %dx,%al + ret + +ENTRY(SBUS_RA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + inw %dx,%ax + ret + +ENTRY(SBUS_RA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + inl %dx,%eax + ret + +/* + * write_N + * IN:eax DATA + * edx PORT + */ +ENTRY(SBUS_RA_io_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + outb %al,%dx + ret + +ENTRY(SBUS_RA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + outw %ax,%dx + ret + +ENTRY(SBUS_RA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + outl %eax,%dx + ret + +/* + * read_multi_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_RA_io_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insb + ret + +ENTRY(SBUS_RA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insw + ret + +ENTRY(SBUS_RA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insl + ret + +/* + * write_multi_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_RA_io_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsb + ret + +ENTRY(SBUS_RA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsw + ret + +ENTRY(SBUS_RA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsl + ret + +/* + * read_region_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_RA_io_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inb %dx,%al + stosb + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inw %dx,%ax + stosw + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inl %dx,%eax + stosl + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_region_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_RA_io_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * set_multi_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_RA_io_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_RA_io_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + ret + +/* + * copy_region_N + * IN: ecx COUNT + * esi SPORT + * edi DPORT + */ +ENTRY(SBUS_RA_io_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inb %dx,%al + incl %esi + + movl %edi,%edx + outb %al,%dx + incl %edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_RA_io_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inw %dx,%ax + addl $2,%esi + + movl %edi,%edx + outw %ax,%dx + addl $2,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_RA_io_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inl %dx,%eax + addl $4,%esi + + movl %edi,%edx + outl %eax,%dx + addl $4,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +/*********************************************************** + * Bus Memory access methods + ***********************************************************/ +/* + * read_N + */ +ENTRY(SBUS_RA_mem_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + movb (%edx),%al + ret + +ENTRY(SBUS_RA_mem_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + movw (%edx),%ax + ret + +ENTRY(SBUS_RA_mem_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + movl (%edx),%eax + ret + +/* + * write_N + */ +ENTRY(SBUS_RA_mem_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + movb %al,(%edx) + ret + +ENTRY(SBUS_RA_mem_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + movw %ax,(%edx) + ret + +ENTRY(SBUS_RA_mem_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + movl %eax,(%edx) + ret + +/* + * read_multi_N + */ +ENTRY(SBUS_RA_mem_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movb (%edx),%al + stosb + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movw (%edx),%ax + stosw + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movl (%edx),%eax + stosl + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_multi_N + */ +ENTRY(SBUS_RA_mem_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + movb %al,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * read_region_N + */ +ENTRY(SBUS_RA_mem_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsb + popl %esi + ret + +ENTRY(SBUS_RA_mem_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsw + popl %esi + ret + +ENTRY(SBUS_RA_mem_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsl + popl %esi + ret + +/* + * write_region_N + */ +ENTRY(SBUS_RA_mem_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsb + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsw + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsl + popl %edi + ret + +/* + * set_multi_N + */ +ENTRY(SBUS_RA_mem_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movb %al,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_mem_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_mem_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + */ +ENTRY(SBUS_RA_mem_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosb + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosw + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosl + popl %edi + ret + +/* + * copy_region_N + */ +ENTRY(SBUS_RA_mem_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsb + ret + +ENTRY(SBUS_RA_mem_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsw + ret + +ENTRY(SBUS_RA_mem_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsl + ret + +#undef BUS_ACCESS_ADDR + + +#include "opt_mecia.h" +#ifdef DEV_MECIA + +/*********************************************************** + * NEPC pcmcia 16 bits bus access + ***********************************************************/ +#define NEPC_SWITCH_BUS16 \ + pushl %ebp ;\ + pushl %eax ;\ + pushl %edx ;\ + movl $0x2a8e,%edx ;\ + inb %dx,%al ;\ + movl %eax,%ebp ;\ + andl $~0x20,%eax ;\ + outb %al,%dx ;\ + popl %edx ;\ + popl %eax + +#define NEPC_BUS_RESTORE \ + pushl %eax ;\ + movl %ebp,%eax ;\ + xchgl %edx,%ebp ;\ + movl $0x2a8e,%edx ;\ + outb %al,%dx ;\ + xchgl %ebp,%edx ;\ + popl %eax ;\ + popl %ebp + +/*********************************************************** + * NEPC pcmcia 16 bits bus acces (Direct Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + addl BUS_SPACE_HANDLE_BASE/**/(%/**/BSHREG/**/),%/**/ADDRREG + +ENTRY(NEPC_DA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inw %dx,%ax + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_DA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outw %ax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_read_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_write_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_set_multi_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_multi_2 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_DA_io_space_set_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_copy_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_copy_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inl %dx,%eax + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outl %eax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_read_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_write_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_set_multi_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_multi_4 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_DA_io_space_set_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_copy_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_copy_region_4 + NEPC_BUS_RESTORE + ret + +#undef BUS_ACCESS_ADDR + +/*********************************************************** + * NEPC pcmcia 16 bits bus acces (Relocate Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + movl BUS_SPACE_HANDLE_IAT/**/(%/**/BSHREG/**/, %/**/ADDRREG/**/, 4), \ + %/**/ADDRREG + +ENTRY(NEPC_RA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inw %dx,%ax + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_RA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outw %ax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_read_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_write_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_set_multi_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_multi_2 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_RA_io_space_set_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_copy_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_copy_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inl %dx,%eax + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outl %eax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_read_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_write_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_set_multi_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_multi_4 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_RA_io_space_set_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_copy_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_copy_region_4 + NEPC_BUS_RESTORE + ret + +#endif /* DEV_MECIA */ Property changes on: head/sys/pc98/i386/busio.s ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/pc98/i386/busiosubr.c =================================================================== --- head/sys/pc98/i386/busiosubr.c (nonexistent) +++ head/sys/pc98/i386/busiosubr.c (revision 84615) @@ -0,0 +1,144 @@ +/* $FreeBSD$ */ +/* $NecBSD: busiosubr.c,v 1.30.4.4 1999/08/28 02:25:35 honda Exp $ */ +/* $NetBSD$ */ + +/* + * [NetBSD for NEC PC-98 series] + * Copyright (c) 1996, 1997, 1998 + * NetBSD/pc98 porting staff. All rights reserved. + * + * [Ported for FreeBSD] + * Copyright (c) 2001 + * TAKAHASHI Yoshihiro. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1997, 1998 + * Naofumi HONDA. All rights reserved. + */ + +#include +#include +#include +#include + +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int32_t,4) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int32_t,4) + +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int32_t,4) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int32_t,4) + +struct bus_space_tag SBUS_io_space_tag = { + BUS_SPACE_IO, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int32_t,4), + } +}; + +struct bus_space_tag SBUS_mem_space_tag = { + BUS_SPACE_MEM, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4), + } +}; + + +#include "opt_mecia.h" +#ifdef DEV_MECIA + +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int32_t,4) + +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int32_t,4) + +struct bus_space_tag NEPC_io_space_tag = { + BUS_SPACE_IO, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int32_t,4), + } +}; + +struct bus_space_tag NEPC_mem_space_tag = { + BUS_SPACE_MEM, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4), + } +}; + +#endif /* DEV_MECIA */ Property changes on: head/sys/pc98/i386/busiosubr.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/pc98/pc98/busio.s =================================================================== --- head/sys/pc98/pc98/busio.s (nonexistent) +++ head/sys/pc98/pc98/busio.s (revision 84615) @@ -0,0 +1,1671 @@ +/* $FreeBSD$ */ +/* $NecBSD: busio.s,v 1.16.4.1 1999/08/16 09:06:08 kmatsuda Exp $ */ +/* $NetBSD$ */ + +/* + * [NetBSD for NEC PC-98 series] + * Copyright (c) 1996, 1997, 1998 + * NetBSD/pc98 porting staff. All rights reserved. + * + * [Ported for FreeBSD] + * Copyright (c) 2001 + * TAKAHASHI Yoshihiro. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1997, 1998 + * Naofumi HONDA. All rights reserved. + */ + +#include + +#include "assym.s" + +/*********************************************************** + * Bus IO access methods (Direct Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + addl BUS_SPACE_HANDLE_BASE/**/(%/**/BSHREG/**/),%/**/ADDRREG + +/* + * read_N + * IN: edx port + * OUT: eax data + */ +ENTRY(SBUS_DA_io_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + inb %dx,%al + ret + +ENTRY(SBUS_DA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + inw %dx,%ax + ret + +ENTRY(SBUS_DA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + inl %dx,%eax + ret + +/* + * write_N + * IN:eax DATA + * edx PORT + */ +ENTRY(SBUS_DA_io_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + outb %al,%dx + ret + +ENTRY(SBUS_DA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + outw %ax,%dx + ret + +ENTRY(SBUS_DA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + outl %eax,%dx + ret + +/* + * read_multi_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_DA_io_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insb + ret + +ENTRY(SBUS_DA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insw + ret + +ENTRY(SBUS_DA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insl + ret + +/* + * write_multi_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_DA_io_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsb + ret + +ENTRY(SBUS_DA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsw + ret + +ENTRY(SBUS_DA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsl + ret + +/* + * read_region_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_DA_io_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inb %dx,%al + stosb + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inw %dx,%ax + stosw + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inl %dx,%eax + stosl + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_region_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_DA_io_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_io_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * set_multi_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_DA_io_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_DA_io_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_io_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + ret + +/* + * copy_region_N + * IN: ecx COUNT + * esi SPORT + * edi DPORT + */ +ENTRY(SBUS_DA_io_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inb %dx,%al + incl %esi + + movl %edi,%edx + outb %al,%dx + incl %edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_DA_io_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inw %dx,%ax + addl $2,%esi + + movl %edi,%edx + outw %ax,%dx + addl $2,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_DA_io_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inl %dx,%eax + addl $4,%esi + + movl %edi,%edx + outl %eax,%dx + addl $4,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +/*********************************************************** + * Bus Memory access methods (Direct Access) + ***********************************************************/ +/* + * read_N + */ +ENTRY(SBUS_DA_mem_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + movb (%edx),%al + ret + +ENTRY(SBUS_DA_mem_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + movw (%edx),%ax + ret + +ENTRY(SBUS_DA_mem_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + movl (%edx),%eax + ret + +/* + * write_N + */ +ENTRY(SBUS_DA_mem_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + movb %al,(%edx) + ret + +ENTRY(SBUS_DA_mem_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + movw %ax,(%edx) + ret + +ENTRY(SBUS_DA_mem_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + movl %eax,(%edx) + ret + +/* + * read_multi_N + */ +ENTRY(SBUS_DA_mem_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movb (%edx),%al + stosb + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movw (%edx),%ax + stosw + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movl (%edx),%eax + stosl + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_multi_N + */ +ENTRY(SBUS_DA_mem_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + movb %al,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_DA_mem_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * read_region_N + */ +ENTRY(SBUS_DA_mem_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsb + popl %esi + ret + +ENTRY(SBUS_DA_mem_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsw + popl %esi + ret + +ENTRY(SBUS_DA_mem_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsl + popl %esi + ret + +/* + * write_region_N + */ +ENTRY(SBUS_DA_mem_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsb + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsw + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsl + popl %edi + ret + +/* + * set_multi_N + */ +ENTRY(SBUS_DA_mem_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movb %al,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_mem_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_DA_mem_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + */ +ENTRY(SBUS_DA_mem_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosb + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosw + popl %edi + ret + +ENTRY(SBUS_DA_mem_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosl + popl %edi + ret + +/* + * copy_region_N + */ +ENTRY(SBUS_DA_mem_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsb + ret + +ENTRY(SBUS_DA_mem_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsw + ret + +ENTRY(SBUS_DA_mem_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsl + ret + +#undef BUS_ACCESS_ADDR + +/*********************************************************** + * Bus IO access methods (Relocate Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + movl BUS_SPACE_HANDLE_IAT/**/(%/**/BSHREG/**/, %/**/ADDRREG/**/, 4), \ + %/**/ADDRREG +/* + * read_N + * IN: edx port + * OUT: eax data + */ +ENTRY(SBUS_RA_io_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + inb %dx,%al + ret + +ENTRY(SBUS_RA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + inw %dx,%ax + ret + +ENTRY(SBUS_RA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + inl %dx,%eax + ret + +/* + * write_N + * IN:eax DATA + * edx PORT + */ +ENTRY(SBUS_RA_io_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + outb %al,%dx + ret + +ENTRY(SBUS_RA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + outw %ax,%dx + ret + +ENTRY(SBUS_RA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + outl %eax,%dx + ret + +/* + * read_multi_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_RA_io_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insb + ret + +ENTRY(SBUS_RA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insw + ret + +ENTRY(SBUS_RA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + insl + ret + +/* + * write_multi_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_RA_io_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsb + ret + +ENTRY(SBUS_RA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsw + ret + +ENTRY(SBUS_RA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + rep + outsl + ret + +/* + * read_region_N + * IN: ecx COUNT + * edx PORT + * edi BUFP + */ +ENTRY(SBUS_RA_io_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inb %dx,%al + stosb + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inw %dx,%ax + stosw + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + inl %dx,%eax + stosl + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_region_N + * IN: ecx COUNT + * edx PORT + * esi BUFP + */ +ENTRY(SBUS_RA_io_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_io_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * set_multi_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_RA_io_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + * IN: eax DATA + * ecx COUNT + * edx PORT + */ +ENTRY(SBUS_RA_io_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outb %al,%dx + incl %edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outw %ax,%dx + addl $2,%edx + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_io_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + outl %eax,%dx + addl $4,%edx + decl %ecx + jnz 1b +2: + ret + +/* + * copy_region_N + * IN: ecx COUNT + * esi SPORT + * edi DPORT + */ +ENTRY(SBUS_RA_io_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inb %dx,%al + incl %esi + + movl %edi,%edx + outb %al,%dx + incl %edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_RA_io_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inw %dx,%ax + addl $2,%esi + + movl %edi,%edx + outw %ax,%dx + addl $2,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +ENTRY(SBUS_RA_io_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + pushl %eax + pushl %edx + orl %ecx,%ecx + jz 2f +1: + movl %esi,%edx + inl %dx,%eax + addl $4,%esi + + movl %edi,%edx + outl %eax,%dx + addl $4,%edi + + decl %ecx + jnz 1b +2: + popl %edx + popl %eax + ret + +/*********************************************************** + * Bus Memory access methods + ***********************************************************/ +/* + * read_N + */ +ENTRY(SBUS_RA_mem_space_read_1) + BUS_ACCESS_ADDR(ebx,edx) + movb (%edx),%al + ret + +ENTRY(SBUS_RA_mem_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + movw (%edx),%ax + ret + +ENTRY(SBUS_RA_mem_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + movl (%edx),%eax + ret + +/* + * write_N + */ +ENTRY(SBUS_RA_mem_space_write_1) + BUS_ACCESS_ADDR(ebx,edx) + movb %al,(%edx) + ret + +ENTRY(SBUS_RA_mem_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + movw %ax,(%edx) + ret + +ENTRY(SBUS_RA_mem_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + movl %eax,(%edx) + ret + +/* + * read_multi_N + */ +ENTRY(SBUS_RA_mem_space_read_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movb (%edx),%al + stosb + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movw (%edx),%ax + stosw + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + movl (%edx),%eax + stosl + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * write_multi_N + */ +ENTRY(SBUS_RA_mem_space_write_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsb + movb %al,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsw + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +ENTRY(SBUS_RA_mem_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %eax + orl %ecx,%ecx + jz 2f +1: + lodsl + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + popl %eax + ret + +/* + * read_region_N + */ +ENTRY(SBUS_RA_mem_space_read_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsb + popl %esi + ret + +ENTRY(SBUS_RA_mem_space_read_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsw + popl %esi + ret + +ENTRY(SBUS_RA_mem_space_read_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %esi + movl %edx,%esi + rep + movsl + popl %esi + ret + +/* + * write_region_N + */ +ENTRY(SBUS_RA_mem_space_write_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsb + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_write_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsw + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_write_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + movsl + popl %edi + ret + +/* + * set_multi_N + */ +ENTRY(SBUS_RA_mem_space_set_multi_1) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movb %al,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_mem_space_set_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movw %ax,(%edx) + decl %ecx + jnz 1b +2: + ret + +ENTRY(SBUS_RA_mem_space_set_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + orl %ecx,%ecx + jz 2f +1: + movl %eax,(%edx) + decl %ecx + jnz 1b +2: + ret + +/* + * set_region_N + */ +ENTRY(SBUS_RA_mem_space_set_region_1) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosb + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_set_region_2) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosw + popl %edi + ret + +ENTRY(SBUS_RA_mem_space_set_region_4) + BUS_ACCESS_ADDR(ebx,edx) + cld + pushl %edi + movl %edx,%edi + rep + stosl + popl %edi + ret + +/* + * copy_region_N + */ +ENTRY(SBUS_RA_mem_space_copy_region_1) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsb + ret + +ENTRY(SBUS_RA_mem_space_copy_region_2) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsw + ret + +ENTRY(SBUS_RA_mem_space_copy_region_4) + BUS_ACCESS_ADDR(eax,esi) + BUS_ACCESS_ADDR(ebx,edi) + cld + rep + movsl + ret + +#undef BUS_ACCESS_ADDR + + +#include "opt_mecia.h" +#ifdef DEV_MECIA + +/*********************************************************** + * NEPC pcmcia 16 bits bus access + ***********************************************************/ +#define NEPC_SWITCH_BUS16 \ + pushl %ebp ;\ + pushl %eax ;\ + pushl %edx ;\ + movl $0x2a8e,%edx ;\ + inb %dx,%al ;\ + movl %eax,%ebp ;\ + andl $~0x20,%eax ;\ + outb %al,%dx ;\ + popl %edx ;\ + popl %eax + +#define NEPC_BUS_RESTORE \ + pushl %eax ;\ + movl %ebp,%eax ;\ + xchgl %edx,%ebp ;\ + movl $0x2a8e,%edx ;\ + outb %al,%dx ;\ + xchgl %ebp,%edx ;\ + popl %eax ;\ + popl %ebp + +/*********************************************************** + * NEPC pcmcia 16 bits bus acces (Direct Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + addl BUS_SPACE_HANDLE_BASE/**/(%/**/BSHREG/**/),%/**/ADDRREG + +ENTRY(NEPC_DA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inw %dx,%ax + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_DA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outw %ax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_read_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_write_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_set_multi_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_multi_2 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_DA_io_space_set_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_copy_region_2) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_copy_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inl %dx,%eax + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outl %eax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_read_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_read_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_write_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_write_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_set_multi_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_multi_4 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_DA_io_space_set_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_set_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_DA_io_space_copy_region_4) + NEPC_SWITCH_BUS16 + call SBUS_DA_io_space_copy_region_4 + NEPC_BUS_RESTORE + ret + +#undef BUS_ACCESS_ADDR + +/*********************************************************** + * NEPC pcmcia 16 bits bus acces (Relocate Access) + ***********************************************************/ +#define BUS_ACCESS_ADDR(BSHREG,ADDRREG) \ + movl BUS_SPACE_HANDLE_IAT/**/(%/**/BSHREG/**/, %/**/ADDRREG/**/, 4), \ + %/**/ADDRREG + +ENTRY(NEPC_RA_io_space_read_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inw %dx,%ax + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_RA_io_space_write_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outw %ax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_multi_2) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsw + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_read_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_write_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_set_multi_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_multi_2 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_RA_io_space_set_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_copy_region_2) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_copy_region_2 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + inl %dx,%eax + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + outl %eax,%dx + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + insl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_multi_4) + BUS_ACCESS_ADDR(ebx,edx) + NEPC_SWITCH_BUS16 + cld + rep + outsl + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_read_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_read_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_write_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_write_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_set_multi_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_multi_4 + NEPC_BUS_RESTORE + ret + + +ENTRY(NEPC_RA_io_space_set_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_set_region_4 + NEPC_BUS_RESTORE + ret + +ENTRY(NEPC_RA_io_space_copy_region_4) + NEPC_SWITCH_BUS16 + call SBUS_RA_io_space_copy_region_4 + NEPC_BUS_RESTORE + ret + +#endif /* DEV_MECIA */ Property changes on: head/sys/pc98/pc98/busio.s ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/pc98/pc98/busiosubr.c =================================================================== --- head/sys/pc98/pc98/busiosubr.c (nonexistent) +++ head/sys/pc98/pc98/busiosubr.c (revision 84615) @@ -0,0 +1,144 @@ +/* $FreeBSD$ */ +/* $NecBSD: busiosubr.c,v 1.30.4.4 1999/08/28 02:25:35 honda Exp $ */ +/* $NetBSD$ */ + +/* + * [NetBSD for NEC PC-98 series] + * Copyright (c) 1996, 1997, 1998 + * NetBSD/pc98 porting staff. All rights reserved. + * + * [Ported for FreeBSD] + * Copyright (c) 2001 + * TAKAHASHI Yoshihiro. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1997, 1998 + * Naofumi HONDA. All rights reserved. + */ + +#include +#include +#include +#include + +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int32_t,4) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int32_t,4) + +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int32_t,4) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int8_t,1) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int32_t,4) + +struct bus_space_tag SBUS_io_space_tag = { + BUS_SPACE_IO, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int32_t,4), + } +}; + +struct bus_space_tag SBUS_mem_space_tag = { + BUS_SPACE_MEM, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4), + } +}; + + +#include "opt_mecia.h" +#ifdef DEV_MECIA + +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int32_t,4) + +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int16_t,2) +_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int32_t,4) + +struct bus_space_tag NEPC_io_space_tag = { + BUS_SPACE_IO, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int32_t,4), + } +}; + +struct bus_space_tag NEPC_mem_space_tag = { + BUS_SPACE_MEM, + + /* direct bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4), + }, + + /* relocate bus access methods */ + { + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2), + _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4), + } +}; + +#endif /* DEV_MECIA */ Property changes on: head/sys/pc98/pc98/busiosubr.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property