FreeBSD/mips booting on Sibyte 1250

View: New views
7 Messages — Rating Filter:   Alert me  

FreeBSD/mips booting on Sibyte 1250

by Neelkanth Natu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi,

I am now able boot the mips port on a Sibyte 1250 processor on the SWARM
reference platform.

You can find more details about the processor here (including user manual):
http://www.broadcom.com/products/Enterprise-Networking/Communications-Processors/BCM1250
http://www.broadcom.com/products/Enterprise-Networking/Communications-Processors/BCM91250A

Some details about my setup:
- 2GB of memory (cannot use all of it since some is mapped beyond 4GB)
- Kernel is netbooted by the CFE
- Root filesystem comes off a compact flash card connected via parallel ATA
  or a USB stick.
- bge ethernet card on the PCI expansion slot for network connectivity
- Using CFE to read and write from the console

Things that still remain to be done are mostly to enable the devices on
the chip (e.g. uart, gigabit ethernet, pcmcia) and also to start using
the second core.

Most of my changes were platform-dependent however I had to make some
changes to:
- busdma (to deal with physical memory beyond the directly mapped window)
- pmap (zero pages through cacheable direct mapped window)
- interrupts (allow masking and unmasking of shared interrupts)

I don't want to keep holding diffs against -current for this, so I was
hoping to get this checked in. How do I go about doing that?

best
Neel

Boot log:
CFE version 1.4.0 for SWARM (64bit,MP,LE,MIPS)
Build Date: Sat May  5 17:32:29 PDT 2007 (neelnatu@sim19)
Copyright (C) 2000,2001,2002,2003,2004,2005 Broadcom Corporation.

Initializing Arena.
Initializing PCI. [normal]
HyperTransport: 400 MHz
PCI bus 0 slot 0/0: SiByte, Inc. BCM1250 PCI Host Bridge (host bridge, rev 0x02)
PCI bus 0 slot 1/0: SiByte, Inc. BCM1250 HyperTransport Host Bridge (host bridge, rev 0x02)
PCI bus 0 slot 5/0: unknown vendor 0x1033 product 0x0035 (USB serial bus, interface 0x10, rev 0x43)
PCI bus 0 slot 5/1: unknown vendor 0x1033 product 0x0035 (USB serial bus, interface 0x10, rev 0x43)
PCI bus 0 slot 5/2: unknown vendor 0x1033 product 0x00e0 (USB serial bus, interface 0x20, rev 0x04)
PCI bus 0 slot 6/0: Broadcom BCM5701 10/100/1000 Ethernet (ethernet network, rev 0x15)
PCI bus 0 slot 7/0: Opti 82C862 FireLink USB Controller (USB serial bus, interface 0x10, rev 0x10)
PCI bus 1 slot 1/0: Alliance Semiconductor SP1011 HyperTransport-PCI Bridge (PCI bridge)
PCI bus 2 slot 0/0: Intel product 0x1008 (ethernet network, rev 0x02)
Initializing Devices.
SWARM board revision 3
sbeth: found phy 1, vendor 000818 part 0E
sbeth: found phy 1, vendor 000818 part 0E
PCIIDE: 0 controllers found
Config switch: 2
CPU: BCM1250 A8/A10
L2 Cache Status: OK
Wafer ID:   0x1F918019  [Lot 2020, Wafer 12]
Manuf Test: Bin A [2CPU_FI_FD_F2 (OK)]
SysCfg: 00000000289B0680 [PLL_DIV: 13, IOB0_DIV: CPUCLK/4, IOB1_DIV: CPUCLK/3]
CPU type 0x1040102: 650MHz
Total memory: 0x80000000 bytes (2048MB)

Total memory used by CFE:  0x8FE95000 - 0x8FFFF480 (1483904)
Initialized Data:          0x8FEF4880 - 0x8FEFCDB0 (34096)
BSS Area:                  0x8FEFCDB0 - 0x8FEFD470 (1728)
Local Heap:                0x8FEFD480 - 0x8FFFD480 (1048576)
Stack Area:                0x8FFFD480 - 0x8FFFF480 (8192)
Text (code) segment:       0x8FE95000 - 0x8FEF3F63 (388963)
Boot area (physical):      0x0FE54000 - 0x0FE94000
Relocation Factor:         I:F0295000 - D:F0295000

CFE> ifconfig -auto eth2; boot -elf -tftp neelnatu1:kernel
eth2: Link speed: 100BaseT FDX
Device eth2:  hwaddr 00-10-18-04-04-4F, ipaddr 10.33.27.25, mask 255.255.252.0
        gateway 10.33.24.1, nameserver 10.99.158.106
Loader:elf Filesys:tftp Dev:eth2 File:neelnatu1:kernel Options:(null)
Loading: 0xffffffff80100010/3180292 0xffffffff80831fac/200 0xffffffff80832074/1494268 0xffffffff8040a800/4356012 Entry at 0x80131350
Closing network.
eth2: 13559 sent, 13581 received, 25042 interrupts
Starting program at 0x80131350

cfe_enummem: 0x0000000000000000/266948608.
cfe_enummem: 0x0000000080000000/536870912.
cfe_enummem: 0x00000000c0000000/268435456.
cfe_enummem: 0x0000000100000000/1073741824.
Ignoring 1073741824 bytes of memory at 0x100000000 that is above maxmem 4096MB
  icache is virtual
  picache_stride    = 8192
  picache_loopcount = 4
  pdcache_stride    = 4096
  pdcache_loopcount = 8
cpu0: Broadcom processor v2.1
  MMU: Standard TLB, 64 entries
  L1 i-cache: 4 ways of 256 sets, 32 bytes per line
  L1 d-cache: 4 ways of 256 sets, 32 bytes per line
Physical memory chunk(s):
0x99ed70 - 0xfe94fff, 256860816 bytes (62710 pages)
0x80000000 - 0x9fffffff, 536870912 bytes (131072 pages)
0xc0000000 - 0xcfffffff, 268435456 bytes (65536 pages)
Maxmem is 0xd0000000
Va=0xc0002000 Ve=ffffc000
init kernel_segmap va >> = 768 nkpt:256
avail_start:0xab2d70 avail_end:0xd0000000
KDB: debugger backends: ddb
KDB: current backend: ddb
hz=100 cyl_per_hz:650000 cyl_per_usec:650 freq:650000000 cyl_per_hz:6500000 cyl_per_sec:650000000
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
    The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 8.0-CURRENT #25: Fri Jun 12 12:03:39 PDT 2009
    neelnatu@neelnatu1:/usr/obj/mips/neelnatu/p4/freebsd_sibyte/src/sys/SWARM
WARNING: WITNESS option enabled, expect reduced performance.
real memory  = 1072254976 (1047124K bytes)
Physical memory chunk(s):
0x00ab3000 - 0x0fe94fff, 255729664 bytes (62434 pages)
0x80000000 - 0x9bf04fff, 468733952 bytes (114437 pages)
0xc0000000 - 0xcfffffff, 268435456 bytes (65536 pages)
avail memory = 989282304 (943MB)
null: <null device, zero device>
nfslock: pseudo-device
mem: <memory>
nexus0: <MIPS32 root nexus>
clock0: <Generic MIPS32 ticker> on nexus0
Establish HARD IRQ 5: filt 0x8039519c handler 0 arg 0
clock0: [FILTER]
zbbus0: <Broadcom/Sibyte ZBbus> at mem 0xc740b400-0x477d827f on nexus0
zbbus0: attached.
zbbus0: Adding hinted child zbpci0
zbbus0: Adding hinted child scd0
zbbus0: Adding hinted child ata0
zbbus0: Assigning memory resource 0x100b0000/65536 to child ata0
zbbus0: Assigning irq resource 36 to child ata0
zbpci0: <Broadcom/Sibyte PCI I/O Bridge> on zbbus0
zbpci0: attached.
pci0: <PCI bus> on zbpci0
pci0: domain=0, physical bus=0
found->    vendor=0x166d, dev=0x0001, revid=0x02
    domain=0, bus=0, slot=0, func=0
    class=06-00-00, hdrtype=0x00, mfdev=0
    cmdreg=0x0156, statreg=0x02a0, cachelnsz=8 (dwords)
    lattimer=0xfc (7560 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
    intpin=a, irq=56
    map[10]: type Prefetchable Memory, range 32, base 0x60000000, size 29, enabled
    map[18]: type Prefetchable Memory, range 32, base 0x70000000, size 28, enabled
    map[1c]: type Prefetchable Memory, range 32, base 0x71000000, size 24, enabled
    map[24]: type Prefetchable Memory, range 32, base 0x80000000, size 31, enabled
found->    vendor=0x166d, dev=0x0002, revid=0x02
    domain=0, bus=0, slot=1, func=0
    class=06-00-00, hdrtype=0x01, mfdev=0
    cmdreg=0x0107, statreg=0x0010, cachelnsz=0 (dwords)
    lattimer=0x00 (0 ns), mingnt=0x02 (500 ns), maxlat=0x00 (0 ns)
found->    vendor=0x1033, dev=0x0035, revid=0x43
    domain=0, bus=0, slot=5, func=0
    class=0c-03-10, hdrtype=0x00, mfdev=1
    cmdreg=0x0156, statreg=0x0210, cachelnsz=8 (dwords)
    lattimer=0xfc (7560 ns), mingnt=0x01 (250 ns), maxlat=0x2a (10500 ns)
    intpin=a, irq=56
    powerspec 2  supports D0 D1 D2 D3  current D0
    map[10]: type Memory, range 32, base 0x41011000, size 12, enabled
found->    vendor=0x1033, dev=0x0035, revid=0x43
    domain=0, bus=0, slot=5, func=1
    class=0c-03-10, hdrtype=0x00, mfdev=0
    cmdreg=0x0156, statreg=0x0210, cachelnsz=8 (dwords)
    lattimer=0xfc (7560 ns), mingnt=0x01 (250 ns), maxlat=0x2a (10500 ns)
    intpin=b, irq=57
    powerspec 2  supports D0 D1 D2 D3  current D0
    map[10]: type Memory, range 32, base 0x41010000, size 12, enabled
found->    vendor=0x1033, dev=0x00e0, revid=0x04
    domain=0, bus=0, slot=5, func=2
    class=0c-03-20, hdrtype=0x00, mfdev=0
    cmdreg=0x0156, statreg=0x0210, cachelnsz=8 (dwords)
    lattimer=0xfc (7560 ns), mingnt=0x10 (4000 ns), maxlat=0x22 (8500 ns)
    intpin=c, irq=58
    powerspec 2  supports D0 D1 D2 D3  current D0
    map[10]: type Memory, range 32, base 0x41013000, size  8, enabled
found->    vendor=0x14e4, dev=0x1645, revid=0x15
    domain=0, bus=0, slot=6, func=0
    class=02-00-00, hdrtype=0x00, mfdev=0
    cmdreg=0x0156, statreg=0x02b0, cachelnsz=8 (dwords)
    lattimer=0xf8 (7440 ns), mingnt=0x40 (16000 ns), maxlat=0x00 (0 ns)
    intpin=a, irq=57
    powerspec 2  supports D0 D3  current D0
    MSI supports 8 messages, 64 bit
    map[10]: type Memory, range 64, base 0x41000000, size 16, enabled
found->    vendor=0x1045, dev=0xc861, revid=0x10
    domain=0, bus=0, slot=7, func=0
    class=0c-03-10, hdrtype=0x00, mfdev=0
    cmdreg=0x0157, statreg=0x0280, cachelnsz=8 (dwords)
    lattimer=0xf8 (7440 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
    intpin=a, irq=58
    map[10]: type Memory, range 32, base 0x41012000, size 12, enabled
ohci0: <NEC uPD 9210 USB controller> mem 0x41011000-0x41011fff irq 56 at device 5.0 on pci0
ohci0: Reserved 0x1000 bytes for rid 0x10 type 3 at 0x41011000
Establish HARD IRQ 1: filt 0 handler 0x801ae56c arg 0xc74bd000
ohci0: [MPSAFE]
ohci0: [ITHREAD]
usbus0: <NEC uPD 9210 USB controller> on ohci0
ohci1: <NEC uPD 9210 USB controller> mem 0x41010000-0x41010fff irq 57 at device 5.1 on pci0
ohci1: Reserved 0x1000 bytes for rid 0x10 type 3 at 0x41010000
Establish HARD IRQ 2: filt 0 handler 0x801ae56c arg 0xc74c3000
ohci1: [MPSAFE]
ohci1: [ITHREAD]
usbus1: <NEC uPD 9210 USB controller> on ohci1
ehci0: <NEC uPD 720100 USB 2.0 controller> mem 0x41013000-0x410130ff irq 58 at device 5.2 on pci0
ehci0: Reserved 0x100 bytes for rid 0x10 type 3 at 0x41013000
Establish HARD IRQ 3: filt 0 handler 0x801a8064 arg 0xc74ca000
ehci0: [MPSAFE]
ehci0: [ITHREAD]
usbus2: EHCI version 1.0
usbus2: <NEC uPD 720100 USB 2.0 controller> on ehci0
pci0:0:6:0: bad VPD cksum, remain 14
bge0: <Broadcom NetXtreme Gigabit Ethernet Controller, ASIC rev. 0x105> mem 0x41000000-0x4100ffff irq 57 at device 6.0 on pci0
bge0: Reserved 0x10000 bytes for rid 0x10 type 3 at 0x41000000
bge0: CHIP ID 0x01050000; ASIC REV 0x00; CHIP REV 0x01; PCI
miibus0: <MII bus> on bge0
brgphy0: <BCM5701 10/100/1000baseTX PHY> PHY 1 on miibus0
brgphy0: OUI 0x000818, model 0x0011, rev. 0
brgphy0:  10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 1000baseT-FDX, auto
bge0: Ethernet address: 00:10:18:04:04:4f
Establish HARD IRQ 2: filt 0 handler 0x8017257c arg 0xc74e4000
bge0: [MPSAFE]
bge0: [ITHREAD]
ohci2: <OPTi 82C861 (FireLink) USB controller> mem 0x41012000-0x41012fff irq 58 at device 7.0 on pci0
ohci2: Reserved 0x1000 bytes for rid 0x10 type 3 at 0x41012000
Establish HARD IRQ 3: filt 0 handler 0x801ae56c arg 0xc74f7000
ohci2: [MPSAFE]
ohci2: [ITHREAD]
usbus3: <OPTi 82C861 (FireLink) USB controller> on ohci2
pci1: <PCI bus> on zbpci0
pci1: domain=0, physical bus=1
found->    vendor=0x14d9, dev=0x0010, revid=0x00
    domain=0, bus=1, slot=1, func=0
    class=06-04-00, hdrtype=0x01, mfdev=0
    cmdreg=0x0107, statreg=0x0010, cachelnsz=8 (dwords)
    lattimer=0x00 (0 ns), mingnt=0x02 (500 ns), maxlat=0x00 (0 ns)
pcib0: <PCI-PCI bridge> at device 1.0 on pci1
pcib0:   domain            0
pcib0:   secondary bus     2
pcib0:   subordinate bus   2
pcib0:   I/O decode        0x8000-0x8fff
pcib0:   memory decode     0x41100000-0x411fffff
pcib0:   no prefetched decode
pci2: <PCI bus> on pcib0
pci2: domain=0, physical bus=2
found->    vendor=0x8086, dev=0x1008, revid=0x02
    domain=0, bus=2, slot=0, func=0
    class=02-00-00, hdrtype=0x00, mfdev=0
    cmdreg=0x0157, statreg=0x0230, cachelnsz=8 (dwords)
    lattimer=0xfc (7560 ns), mingnt=0xff (63750 ns), maxlat=0x00 (0 ns)
    intpin=a, irq=57
    powerspec 2  supports D0 D3  current D0
    MSI supports 1 message, 64 bit
    map[10]: type Memory, range 32, base 0x41120000, size 17, enabled
pcib0: requested memory range 0x41120000-0x4113ffff: good
    map[14]: type Memory, range 32, base 0x41140000, size 17, enabled
pcib0: requested memory range 0x41140000-0x4115ffff: good
    map[18]: type I/O Port, range 32, base 0x8000, size  5, enabled
pcib0: requested I/O range 0x8000-0x801f: in range
pci2: <network, ethernet> at device 0.0 (no driver attached)
scd0: <Broadcom/Sibyte System Control and Debug> on zbbus0
scd0: attached.
ata0 on zbbus0
ata0: using a register shift of 5
ata0: using a register offset of 0x1f0
ata0: reset tp1 mask=03 ostat0=50 ostat1=00
ata0: stat0=0x50 err=0x01 lsb=0x00 msb=0x00
ata0: stat1=0x00 err=0x01 lsb=0x00 msb=0x00
ata0: reset tp2 stat0=50 stat1=00 devices=0x1
Establish HARD IRQ 1: filt 0 handler 0x8014c144 arg 0xc74b1000
ata0: [MPSAFE]
ata0: [ITHREAD]
Device configuration finished.
Timecounter "MIPS32" frequency 650000000 Hz quality 800
Timecounters tick every 10.000 msec
ata0: Identifying devices: 00000001
ata0: New devices: 00000001
usbus0: 12Mbps Full Speed USB v1.0
usbus1: 12Mbps Full Speed USB v1.0
usbus2: 480Mbps High Speed USB v2.0
usbus3: 12Mbps Full Speed USB v1.0
ata0-master: pio=PIO4 wdma=WDMA2 udma=UNSUPPORTED cable=40 wire
ad0: 977MB <STI Flash 8.0.0 01/17/07> at ata0-master PIO4
ad0: 2001888 sectors [1986C/16H/63S] 1 sectors/interrupt 1 depth queue
ugen0.1: <NEC> at usbus0
uhub0: <NEC OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus0
ugen1.1: <NEC> at usbus1
uhub1: <NEC OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus1
ugen2.1: <NEC> at usbus2
uhub2: <NEC EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus2
ugen3.1: <OPTi> at usbus3
uhub3: <OPTi OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus3
GEOM: new disk ad0
WARNING: WITNESS option enabled, expect reduced performance.
Root mount waiting for: usbus3 usbus2 usbus1 usbus0
uhub3: 2 ports with 2 removable, self powered
uhub1: 2 ports with 2 removable, self powered
uhub0: 3 ports with 3 removable, self powered
Root mount waiting for: usbus2
uhub2: 5 ports with 5 removable, self powered
Trying to mount root from ufs:/dev/md0

Manual root filesystem specification:
  <fstype>:<device>  Mount <device> using filesystem <fstype>
                       eg. ufs:/dev/da0a
  ?                  List valid disk boot devices
  <empty line>       Abort manual input

mountroot> ufs:/dev/ad0
Trying to mount root from ufs:/dev/ad0
warning: no time-of-day clock registered, system time will not be set accurately
start_init: trying /sbin/init
hello world
Enter full pathname of shell or RETURN for /bin/sh:
# uname -a
FreeBSD  8.0-CURRENT FreeBSD 8.0-CURRENT #25: Fri Jun 12 12:03:39 PDT 2009     neelnatu@neelnatu1:/usr/obj/mips/neelnatu/p4/freebsd_sibyte/src/sys/SWARM  mips



     
_______________________________________________
freebsd-mips@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mips
To unsubscribe, send any mail to "freebsd-mips-unsubscribe@..."

Re: FreeBSD/mips booting on Sibyte 1250

by M. Warner Losh :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

In message: <856232.92278.qm@...>
            Neelkanth Natu <neelnatu@...> writes:
: I don't want to keep holding diffs against -current for this, so I was
: hoping to get this checked in. How do I go about doing that?

diffs would be a good start :)

Usually, we pass them through /projects/mips/* to make sure that we
have a good integration branch before we collapse/merge the changes
into -current.

Warner
_______________________________________________
freebsd-mips@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mips
To unsubscribe, send any mail to "freebsd-mips-unsubscribe@..."

Parent Message unknown Re: FreeBSD/mips booting on Sibyte 1250

by Neelkanth Natu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Ok, thanks. I can do that.

My tree is about 6 weeks stale with respect to -current so let me sync
up and generate the diffs.

I have an account on the FreeBSD perforce server but the last time I tried
to access it I had some trouble. Let me try again.

best
Neel

--- On Fri, 6/12/09, M. Warner Losh <imp@...> wrote:

> From: M. Warner Losh <imp@...>
> Subject: Re: FreeBSD/mips booting on Sibyte 1250
> To: neelnatu@...
> Cc: freebsd-mips@...
> Date: Friday, June 12, 2009, 8:33 PM
> In message: <856232.92278.qm@...>
>             Neelkanth Natu
> <neelnatu@...>
> writes:
> : I don't want to keep holding diffs against -current for
> this, so I was
> : hoping to get this checked in. How do I go about doing
> that?
>
> diffs would be a good start :)
>
> Usually, we pass them through /projects/mips/* to make sure
> that we
> have a good integration branch before we collapse/merge the
> changes
> into -current.
>
> Warner
>



_______________________________________________
freebsd-mips@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mips
To unsubscribe, send any mail to "freebsd-mips-unsubscribe@..."

Parent Message unknown Re: FreeBSD/mips booting on Sibyte 1250

by Neelkanth Natu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Warner,

I have attached the diffs against -current at revision 194280.

There are some changes in the diff that are unrelated to the sibyte
work and probably should be committed separately.

I can provide more information about changes to specific files if necessary.

best
Neel

--- On Fri, 6/12/09, M. Warner Losh <imp@...> wrote:

> From: M. Warner Losh <imp@...>
> Subject: Re: FreeBSD/mips booting on Sibyte 1250
> To: neelnatu@...
> Cc: freebsd-mips@...
> Date: Friday, June 12, 2009, 8:33 PM
> In message: <856232.92278.qm@...>
>             Neelkanth Natu
> <neelnatu@...>
> writes:
> : I don't want to keep holding diffs against -current for
> this, so I was
> : hoping to get this checked in. How do I go about doing
> that?
>
> diffs would be a good start :)
>
> Usually, we pass them through /projects/mips/* to make sure
> that we
> have a good integration branch before we collapse/merge the
> changes
> into -current.
>
> Warner
>


diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/conf/files.mips ./sys/conf/files.mips
--- /u/neelnatu/p4/freebsd_current/src/sys/conf/files.mips 2009-06-15 23:27:26.208231000 -0700
+++ ./sys/conf/files.mips 2009-06-16 17:31:21.727409000 -0700
@@ -94,5 +94,6 @@
 
 dev/cfe/cfe_api.c optional cfe
 dev/cfe/cfe_console.c optional cfe_console
+dev/cfe/cfe_env.c optional cfe_env
 #dev/cfe/cfe_resource.c optional cfe # not yet needed
 
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/conf/options.mips ./sys/conf/options.mips
--- /u/neelnatu/p4/freebsd_current/src/sys/conf/options.mips 2009-06-15 23:27:26.286232000 -0700
+++ ./sys/conf/options.mips 2009-06-16 17:31:21.732415000 -0700
@@ -33,6 +33,7 @@
 CPU_MIPS64 opt_global.h
 CPU_NOFPU opt_global.h
 CPU_SENTRY5 opt_global.h
+CPU_SB1 opt_global.h
 
 ISA_MIPS1 opt_cputype.h
 ISA_MIPS3 opt_cputype.h
@@ -44,6 +45,8 @@
 YAMON opt_global.h
 CFE opt_global.h
 CFE_CONSOLE opt_global.h
+CFE_ENV opt_global.h
+CFE_ENV_SIZE opt_global.h
 
 KERNPHYSADDR opt_global.h
 KERNVIRTADDR opt_global.h
@@ -55,3 +58,8 @@
 
 TICK_USE_YAMON_FREQ opt_global.h
 TICK_USE_MALTA_RTC opt_global.h
+
+PCI_IOSPACE_SIZE opt_global.h
+PCI_IOSPACE_ADDR opt_global.h
+
+MAXMEM opt_global.h
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/dev/cfe/cfe_api.c ./sys/dev/cfe/cfe_api.c
--- /u/neelnatu/p4/freebsd_current/src/sys/dev/cfe/cfe_api.c 2009-06-15 23:27:31.799448000 -0700
+++ ./sys/dev/cfe/cfe_api.c 2009-06-16 17:31:21.738412000 -0700
@@ -160,7 +160,7 @@
 {
     cfe_xiocb_t xiocb;
 
-    xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+    xiocb.xiocb_fcode = CFE_CMD_ENV_ENUM;
     xiocb.xiocb_status = 0;
     xiocb.xiocb_handle = 0;
     xiocb.xiocb_flags = 0;
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/dev/cfe/cfe_console.c ./sys/dev/cfe/cfe_console.c
--- /u/neelnatu/p4/freebsd_current/src/sys/dev/cfe/cfe_console.c 2009-06-15 23:27:31.825449000 -0700
+++ ./sys/dev/cfe/cfe_console.c 2009-06-16 17:31:21.747410000 -0700
@@ -84,14 +84,12 @@
 static void
 cn_drvinit(void *unused)
 {
- char output[32];
  struct tty *tp;
 
  if (cfe_consdev.cn_pri != CN_DEAD &&
     cfe_consdev.cn_name[0] != '\0') {
  tp = tty_alloc(&cfe_ttydevsw, NULL);
- tty_makedev(tp, NULL, "%s", output);
- tty_makealias(tp, "cfecons");
+ tty_makedev(tp, NULL, "cfecons");
  }
 }
 
@@ -117,15 +115,21 @@
 static void
 cfe_tty_outwakeup(struct tty *tp)
 {
- int len;
+ int len, written, rc;
  u_char buf[CFEBURSTLEN];
 
  for (;;) {
  len = ttydisc_getc(tp, buf, sizeof buf);
  if (len == 0)
  break;
- while (cfe_write(conhandle, buf, len) == 0)
- continue;
+
+ written = 0;
+ while (written < len) {
+ rc = cfe_write(conhandle, &buf[written], len - written);
+ if (rc < 0)
+ break;
+ written += rc;
+ }
  }
 }
 
@@ -184,13 +188,9 @@
 static int
 cfe_cngetc(struct consdev *cp)
 {
- int result;
  unsigned char ch;
 
- while ((result = cfe_read(conhandle, &ch, 1)) == 0)
- continue;
-
- if (result > 0) {
+ if (cfe_read(conhandle, &ch, 1) == 1) {
 #if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
  int kdb_brk;
 
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/dev/cfe/cfe_env.c ./sys/dev/cfe/cfe_env.c
--- /u/neelnatu/p4/freebsd_current/src/sys/dev/cfe/cfe_env.c 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/dev/cfe/cfe_env.c 2009-05-12 01:12:44.728865000 -0700
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <dev/cfe/cfe_api.h>
+
+__FBSDID("$FreeBSD$");
+
+#ifndef CFE_ENV_SIZE
+#define CFE_ENV_SIZE PAGE_SIZE /* default is one page */
+#endif
+
+extern void cfe_env_init(void);
+
+static char cfe_env_buf[CFE_ENV_SIZE];
+
+void
+cfe_env_init(void)
+{
+ int idx, len;
+ char name[64], val[128], *cp, *cplim;
+
+ cp = cfe_env_buf;
+ cplim = cp + CFE_ENV_SIZE;
+
+ idx = 0;
+ while (1) {
+ if (cfe_enumenv(idx, name, sizeof(name), val, sizeof(val)) != 0)
+ break;
+
+ if (bootverbose)
+ printf("Importing CFE env: \"%s=%s\"\n", name, val);
+
+ /*
+ * name=val\0\0
+ */
+ len = strlen(name) + 1 + strlen(val) + 1 + 1;
+ if (cplim - cp < len)
+ printf("No space to store CFE env: \"%s=%s\"\n",
+ name, val);
+ else
+ cp += sprintf(cp, "%s=%s", name, val) + 1;
+ ++idx;
+ }
+ *cp++ = '\0';
+
+ kern_envp = cfe_env_buf;
+}
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/conf/SWARM ./sys/mips/conf/SWARM
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/conf/SWARM 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/conf/SWARM 2009-06-13 12:17:44.499588000 -0700
@@ -0,0 +1,82 @@
+#
+# $Id: //depot/user/neelnatu/freebsd_sibyte/src/sys/mips/conf/SWARM#7 $
+#
+
+ident SWARM
+options CPU_NOFPU
+options CPU_SB1
+
+files "../sibyte/files.sibyte"
+hints "SWARM.hints"
+
+options PCI_IOSPACE_ADDR=0xFC000000
+options PCI_IOSPACE_SIZE=0x02000000
+
+#
+# 32-bit kernel cannot deal with physical memory beyond 4GB
+#
+options MAXMEM=4096*1024
+
+options CFE
+options CFE_CONSOLE
+options CFE_ENV
+options ALT_BREAK_TO_DEBUGGER
+
+# cfe loader expects kernel at 0x80001000 for mips32 w/o backwards
+# offsets in the linked elf image (see ldscript hack)
+# XXX can we conditionalize the linker stuff on options CFE?
+options KERNVIRTADDR=0x80001000
+
+makeoptions LDSCRIPT_NAME= ldscript.mips.cfe
+
+#cpu CPU_MIPS64
+#options ISA_MIPS64
+#makeoptions ARCH_FLAGS="-march=mips64 -mgp64 -mabi=o64"
+cpu CPU_MIPS32
+options ISA_MIPS32
+makeoptions ARCH_FLAGS="-march=mips32"
+
+makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+makeoptions MODULES_OVERRIDE=""
+
+options DDB
+options KDB
+
+options SCHED_4BSD #4BSD scheduler
+options INET #InterNETworking
+options NFSCLIENT #Network Filesystem Client
+options NFS_ROOT #NFS usable as /, requires NFSCLIENT
+options PSEUDOFS #Pseudo-filesystem framework
+options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+
+# Debugging for use in -current
+options INVARIANTS
+options INVARIANT_SUPPORT
+options WITNESS
+
+options MD_ROOT
+options MD_ROOT_SIZE=4096
+options FFS #Fast filesystem
+
+device pci
+device miibus
+device bge
+device loop
+device ether
+device md
+
+options USB_DEBUG
+device usb
+device ohci
+device uhci
+device ehci
+
+device umass
+
+device scbus
+device da
+
+device ata
+device atadisk
+device atapicd
+options ATA_STATIC_ID
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/conf/SWARM.hints ./sys/mips/conf/SWARM.hints
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/conf/SWARM.hints 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/conf/SWARM.hints 2009-05-30 19:35:45.581258000 -0700
@@ -0,0 +1,17 @@
+# $FreeBSD$
+hint.zbbus.0.at="nexus0"
+hint.zbpci.0.at="zbbus0"
+hint.scd.0.at="zbbus0"
+
+#
+# SWARM IDE interface is on the generic bus at chip select 4.
+# The CS4 region is 64KB in size and starts at 0x100B0000.
+# The IDE interrupt is wired to GPIO4 (intsrc 36 to the interrupt mapper)
+#
+hint.ata.0.at="zbbus0"
+hint.ata.0.maddr=0x100B0000
+hint.ata.0.msize=0x10000
+hint.ata.0.irq=36
+#hint.ata.0.disabled=0
+#hint.ata.0.regoffset=0x1F0
+#hint.ata.0.regshift=5
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/include/cpu.h ./sys/mips/include/cpu.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/include/cpu.h 2009-06-15 23:27:51.494233000 -0700
+++ ./sys/mips/include/cpu.h 2009-06-16 17:31:21.752415000 -0700
@@ -154,7 +154,11 @@
  * The bits in the CONFIG register
  */
 #define CFG_K0_UNCACHED 2
+#if defined(CPU_SB1)
+#define CFG_K0_COHERENT 5 /* cacheable coherent */
+#else
 #define CFG_K0_CACHED 3
+#endif
 
 /*
  * The bits in the context register.
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/include/cpuregs.h ./sys/mips/include/cpuregs.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/include/cpuregs.h 2009-06-15 23:27:51.500230000 -0700
+++ ./sys/mips/include/cpuregs.h 2009-06-16 17:31:21.758417000 -0700
@@ -103,6 +103,8 @@
 /* CPU dependent mtc0 hazard hook */
 #ifdef TARGET_OCTEON
 #define COP0_SYNC  nop; nop; nop; nop; nop;
+#elif defined(CPU_SB1)
+#define COP0_SYNC  ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop
 #else
 #define COP0_SYNC /* nothing */
 #endif
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/include/intr.h ./sys/mips/include/intr.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/include/intr.h 2009-06-15 23:27:51.535235000 -0700
+++ ./sys/mips/include/intr.h 2009-06-16 17:31:21.766414000 -0700
@@ -75,8 +75,8 @@
 
 typedef void (*mask_fn)(void *);
 
-void mips_mask_irq(void);
-void mips_unmask_irq(void);
+void mips_mask_irq(void *);
+void mips_unmask_irq(void *);
 
 struct trapframe;
 void mips_set_intr(int pri, uint32_t mask,
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/include/intr_machdep.h ./sys/mips/include/intr_machdep.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/include/intr_machdep.h 2009-06-15 23:27:51.537233000 -0700
+++ ./sys/mips/include/intr_machdep.h 2009-06-16 17:31:21.774409000 -0700
@@ -34,6 +34,27 @@
 
 struct trapframe;
 
+/*
+ * An interrupt source is defined by its interrupt number and handlers to
+ * mask and unmask the sources that trigger it.
+ *
+ * Once an interrupt handler is established for a particular interrupt number
+ * we always keep it enabled from the mips core point of view. However we may
+ * choose to mask the interrupt source feeding into it until the ithread has
+ * had a chance to run.
+ *
+ * XXX how does this work with platforms that have no interrupt mapper feeding
+ * interrupts to the cpu core?
+ */
+struct intsrc {
+ int intrnum;
+ void (*mask_func)(struct intsrc *isrc);
+ void (*unmask_func)(struct intsrc *isrc);
+};
+
+int cpu_register_hard_intsrc(struct intsrc *isrc);
+int cpu_register_soft_intsrc(struct intsrc *isrc);
+
 void cpu_establish_hardintr(const char *, int (*)(void*), void (*)(void*),
     void *, int, int, void **);
 void cpu_establish_softintr(const char *, int (*)(void*), void (*)(void*),
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/include/md_var.h ./sys/mips/include/md_var.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/include/md_var.h 2009-06-15 23:27:51.545233000 -0700
+++ ./sys/mips/include/md_var.h 2009-06-16 17:31:21.793420000 -0700
@@ -39,7 +39,7 @@
 /*
  * Miscellaneous machine-dependent declarations.
  */
-extern int Maxmem;
+extern long Maxmem;
 extern char sigcode[];
 extern int szsigcode, szosigcode;
 
@@ -52,6 +52,7 @@
 u_long kvtop(void *addr);
 int is_physical_memory(vm_offset_t addr);
 int is_cacheable_mem(vm_offset_t pa);
+int is_coherent_mem(vm_offset_t pa);
 
 #define MIPS_DEBUG   0
 
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/include/pltfm.h ./sys/mips/include/pltfm.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/include/pltfm.h 2009-06-15 23:27:51.569235000 -0700
+++ ./sys/mips/include/pltfm.h 2009-06-16 17:31:21.801415000 -0700
@@ -6,6 +6,12 @@
 #ifndef _MACHINE_PLTFM_H_
 #define _MACHINE_PLTFM_H_
 
+#ifdef CPU_SB1
+/*
+ * XXX Make sure that these macros are not defined for the SB-1 cpu
+ * since they don't make any sense for it.
+ */
+#else
 /*
  * This files contains platform-specific definitions.
  */
@@ -25,5 +31,6 @@
 #endif
 #define ADDR_NS16550_UART1 0x1ef14000 /* UART */
 #define VADDR_NS16550_UART1 0xbef14000 /* UART */
+#endif
 
 #endif /* !_MACHINE_PLTFM_H_ */
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/include/pte.h ./sys/mips/include/pte.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/include/pte.h 2009-06-15 23:27:51.594236000 -0700
+++ ./sys/mips/include/pte.h 2009-06-16 17:31:21.808412000 -0700
@@ -105,7 +105,11 @@
 #define PTE_ODDPG       0x00001000
 /*#define PG_ATTR 0x0000003f  Not Used */
 #define PTE_UNCACHED 0x00000010
+#ifdef CPU_SB1
+#define PTE_CACHE 0x00000028 /* cacheable coherent */
+#else
 #define PTE_CACHE 0x00000018
+#endif
 /*#define PG_CACHEMODE 0x00000038 Not Used*/
 #define PTE_ROPAGE (PTE_V | PTE_RO | PTE_CACHE) /* Write protected */
 #define PTE_RWPAGE (PTE_V | PTE_M | PTE_CACHE)  /* Not wr-prot not clean */
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/autoconf.c ./sys/mips/mips/autoconf.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/autoconf.c 2009-06-15 23:27:51.705239000 -0700
+++ ./sys/mips/mips/autoconf.c 2009-06-16 17:31:21.813412000 -0700
@@ -93,6 +93,17 @@
 configure(dummy)
  void *dummy;
 {
+ register_t sr;
+
+ /*
+ * Enable interrupts on the processor. The interrupts are still
+ * disabled by the interrupt mask bits until interrupt handlers
+ * are registered.
+ */
+ sr = mips_rd_status();
+ sr &= ~MIPS_INT_MASK;
+ sr |= MIPS_SR_INT_IE;
+ mips_wr_status(sr);
 
  /* initialize new bus architecture */
  root_bus_configure();
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/busdma_machdep.c ./sys/mips/mips/busdma_machdep.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/busdma_machdep.c 2009-06-15 23:27:51.707240000 -0700
+++ ./sys/mips/mips/busdma_machdep.c 2009-06-16 17:31:21.818418000 -0700
@@ -88,6 +88,7 @@
 #include <machine/bus.h>
 #include <machine/cache.h>
 #include <machine/cpufunc.h>
+#include <machine/md_var.h>
 
 struct bus_dma_tag {
  bus_dma_tag_t parent;
@@ -270,8 +271,7 @@
  newtag->map_count = 0;
  newtag->_wbase = 0;
  newtag->_physbase = 0;
- /* XXXMIPS: Should we limit window size to amount of physical memory */
- newtag->_wsize = MIPS_KSEG1_START - MIPS_KSEG0_START;
+ newtag->_wsize = ptoa(Maxmem);
  if (lockfunc != NULL) {
  newtag->lockfunc = lockfunc;
  newtag->lockfuncarg = lockfuncarg;
@@ -397,6 +397,7 @@
                  bus_dmamap_t *mapp)
 {
  bus_dmamap_t newmap = NULL;
+ void *tmpaddr;
 
  int mflags;
 
@@ -417,7 +418,9 @@
  *mapp = newmap;
  newmap->dmat = dmat;
 
-        if (dmat->maxsize <= PAGE_SIZE) {
+        if (dmat->maxsize <= PAGE_SIZE &&
+    dmat->alignment < dmat->maxsize &&
+    dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) {
                 *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
         } else {
                 /*
@@ -450,19 +453,20 @@
  }
  *mapp = NULL;
                 return (ENOMEM);
+ } else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
+ printf("bus_dmamem_alloc failed to align memory properly.\n");
  }
- if (flags & BUS_DMA_COHERENT) {
- void *tmpaddr = (void *)*vaddr;
 
- if (tmpaddr) {
- tmpaddr = (void *)MIPS_PHYS_TO_KSEG1(vtophys(tmpaddr));
- newmap->origbuffer = *vaddr;
- newmap->allocbuffer = tmpaddr;
- mips_dcache_wbinv_range((vm_offset_t)*vaddr,
-    dmat->maxsize);
- *vaddr = tmpaddr;
- } else
- newmap->origbuffer = newmap->allocbuffer = NULL;
+ tmpaddr = (void *)*vaddr;
+ if ((flags & BUS_DMA_COHERENT) && !is_coherent_mem(vtophys(tmpaddr))) {
+ KASSERT(vtophys(tmpaddr) < MIPS_KSEG0_LARGEST_PHYS,
+ ("bus_dmamem_alloc: physaddr 0x%0x cannot "
+ "be mapped in KSEG1", vtophys(tmpaddr)));
+ tmpaddr = (void *)MIPS_PHYS_TO_KSEG1(vtophys(tmpaddr));
+ newmap->origbuffer = *vaddr;
+ newmap->allocbuffer = tmpaddr;
+ mips_dcache_wbinv_range((vm_offset_t)*vaddr, dmat->maxsize);
+ *vaddr = tmpaddr;
  } else
  newmap->origbuffer = newmap->allocbuffer = NULL;
         return (0);
@@ -481,7 +485,9 @@
     ("Trying to freeing the wrong DMA buffer"));
  vaddr = map->origbuffer;
  }
-        if (dmat->maxsize <= PAGE_SIZE)
+        if (dmat->maxsize <= PAGE_SIZE &&
+    dmat->alignment < dmat->maxsize &&
+    dmat->lowaddr >= ptoa(Maxmem))
  free(vaddr, M_DEVBUF);
         else {
  contigfree(vaddr, dmat->maxsize, M_DEVBUF);
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/cpu.c ./sys/mips/mips/cpu.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/cpu.c 2009-06-15 23:27:51.715239000 -0700
+++ ./sys/mips/mips/cpu.c 2009-06-16 17:31:21.824411000 -0700
@@ -92,9 +92,9 @@
     cpuinfo->tlb_nentries = ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1;
 
     /* L1 instruction cache. */
-    tmp = 1 << (((cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT) + 1);
+    tmp = (cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT;
     if (tmp != 0) {
- cpuinfo->l1.ic_linesize = tmp;
+ cpuinfo->l1.ic_linesize = 1 << (tmp + 1);
  cpuinfo->l1.ic_nways = (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFIG1_IA_SHIFT)) + 1;
  cpuinfo->l1.ic_nsets = 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6);
  cpuinfo->l1.ic_size = cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets
@@ -102,9 +102,9 @@
     }
 
     /* L1 data cache. */
-    tmp = 1 << (((cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT) + 1);
+    tmp = (cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT;
     if (tmp != 0) {
- cpuinfo->l1.dc_linesize = tmp;
+ cpuinfo->l1.dc_linesize = 1 << (tmp + 1);
  cpuinfo->l1.dc_nways = (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1;
  cpuinfo->l1.dc_nsets = 1 << (((cfg1 & MIPS_CONFIG1_DS_MASK) >> MIPS_CONFIG1_DS_SHIFT) + 6);
 #ifdef TARGET_OCTEON
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/intr_machdep.c ./sys/mips/mips/intr_machdep.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/intr_machdep.c 2009-06-15 23:27:51.737242000 -0700
+++ ./sys/mips/mips/intr_machdep.c 2009-06-16 17:31:21.829412000 -0700
@@ -53,16 +53,97 @@
 static int last_printed = 0;
 #endif
 
+static struct intsrc *hardintr_srcs[NHARD_IRQS];
+static struct intsrc *softintr_srcs[NSOFT_IRQS];
+
+static int
+cpu_register_intsrc(struct intsrc *intsrcs[], int limit, struct intsrc *isrc)
+{
+ int intrnum;
+
+ intrnum = isrc->intrnum;
+ if (intrnum < 0 || intrnum >= limit)
+ return (EINVAL);
+
+ /*
+ * XXX locking?
+ */
+ if (intsrcs[intrnum] != NULL)
+ return (EEXIST);
+ else
+ intsrcs[intrnum] = isrc;
+ return (0);
+}
+
+int
+cpu_register_hard_intsrc(struct intsrc *isrc)
+{
+
+ return (cpu_register_intsrc(hardintr_srcs, NHARD_IRQS, isrc));
+}
+
+int
+cpu_register_soft_intsrc(struct intsrc *isrc)
+{
+
+ return (cpu_register_intsrc(softintr_srcs, NSOFT_IRQS, isrc));
+}
+
 void
-mips_mask_irq(void)
+mips_mask_irq(void *arg)
 {
+ struct intsrc *isrc = arg;
 
+ if (isrc != NULL)
+ (*isrc->mask_func)(isrc);
 }
 
 void
-mips_unmask_irq(void)
+mips_unmask_irq(void *arg)
+{
+ struct intsrc *isrc = arg;
+
+ if (isrc != NULL)
+ (*isrc->unmask_func)(isrc);
+}
+
+#define SR_HARD_IRQ_MASK(irq) ((1 << ((irq) + 2)) << 8)
+#define SR_SOFT_IRQ_MASK(irq) ((1 << ((irq) + 0)) << 8)
+
+static void
+cpu_disable_hard_irq(int irq)
+{
+ KASSERT(irq >= 0 && irq < NHARD_IRQS,
+ ("cpu_disable_hard_irq: invalid irq %d", irq));
+
+ mips_wr_status(mips_rd_status() & ~SR_HARD_IRQ_MASK(irq));
+}
+
+static void
+cpu_enable_hard_irq(int irq)
 {
+ KASSERT(irq >= 0 && irq < NHARD_IRQS,
+ ("cpu_enable_hard_irq: invalid irq %d", irq));
 
+ mips_wr_status(mips_rd_status() | SR_HARD_IRQ_MASK(irq));
+}
+
+static void
+cpu_disable_soft_irq(int irq)
+{
+ KASSERT(irq >= 0 && irq < NSOFT_IRQS,
+ ("cpu_disable_soft_irq: invalid irq %d", irq));
+
+ mips_wr_status(mips_rd_status() & ~SR_SOFT_IRQ_MASK(irq));
+}
+
+static void
+cpu_enable_soft_irq(int irq)
+{
+ KASSERT(irq >= 0 && irq < NSOFT_IRQS,
+ ("cpu_enable_soft_irq: invalid irq %d", irq));
+
+ mips_wr_status(mips_rd_status() | SR_SOFT_IRQ_MASK(irq));
 }
 
 void
@@ -80,9 +161,20 @@
  if (irq < 0 || irq >= NHARD_IRQS)
  panic("%s called for unknown hard intr %d", __func__, irq);
 
+ /*
+ * XXX Disable the hard irq
+ *
+ * It appears that there is a race between intr_event_add_handler()
+ * and intr_event_handle() that can be triggered if we receive an
+ * interrupt while we are adding the handler.
+ *
+ * Work around that by disabling the hard irq temporarily.
+ */
+ cpu_disable_hard_irq(irq);
+
  event = hardintr_events[irq];
  if (event == NULL) {
- error = intr_event_create(&event, (void *)irq, 0, irq,
+ error = intr_event_create(&event, hardintr_srcs[irq], 0, irq,
     (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq,
     NULL, NULL, "hard intr%d:", irq);
  if (error)
@@ -101,7 +193,7 @@
  intr_event_add_handler(event, name, filt, handler, arg,
     intr_priority(flags), flags, cookiep);
 
- mips_wr_status(mips_rd_status() | (((1 << irq) << 8) << 2));
+ cpu_enable_hard_irq(irq);
 }
 
 void
@@ -117,9 +209,11 @@
  if (irq < 0 || irq > NSOFT_IRQS)
  panic("%s called for unknown hard intr %d", __func__, irq);
 
+ cpu_disable_soft_irq(irq);
+
  event = softintr_events[irq];
  if (event == NULL) {
- error = intr_event_create(&event, (void *)irq, 0, irq,
+ error = intr_event_create(&event, softintr_srcs[irq], 0, irq,
     (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq,
     NULL, NULL, "intr%d:", irq);
  if (error)
@@ -130,7 +224,7 @@
  intr_event_add_handler(event, name, filt, handler, arg,
     intr_priority(flags), flags, cookiep);
 
- mips_wr_status(mips_rd_status() | (((1<< irq) << 8)));
+ cpu_enable_soft_irq(irq);
 }
 
 void
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/locore.S ./sys/mips/mips/locore.S
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/locore.S 2009-06-15 23:27:51.739241000 -0700
+++ ./sys/mips/mips/locore.S 2009-06-16 17:31:21.834416000 -0700
@@ -138,7 +138,11 @@
  mtc0 t2, COP_0_STATUS_REG
  COP0_SYNC
  /* Make sure KSEG0 is cached */
+#ifdef CPU_SB1
+ li t0, CFG_K0_COHERENT
+#else
  li t0, CFG_K0_CACHED
+#endif
  mtc0 t0, MIPS_COP_0_CONFIG
  COP0_SYNC
 
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/machdep.c ./sys/mips/mips/machdep.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/machdep.c 2009-06-15 23:27:51.748240000 -0700
+++ ./sys/mips/mips/machdep.c 2009-06-16 17:31:21.848415000 -0700
@@ -104,6 +104,7 @@
 
 int cold = 1;
 long realmem = 0;
+long Maxmem = 0;
 int cpu_clock = MIPS_DEFAULT_HZ;
 SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
     &cpu_clock, 0, "CPU instruction clock rate");
@@ -255,10 +256,7 @@
  proc_linkup(&proc0, &thread0);
  thread0.td_kstack = kstack0;
  thread0.td_kstack_pages = KSTACK_PAGES - 1;
- if (thread0.td_kstack & (1 << PAGE_SHIFT))
- thread0.td_md.md_realstack = thread0.td_kstack + PAGE_SIZE;
- else
- thread0.td_md.md_realstack = thread0.td_kstack;
+ thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2);
  /* Initialize pcpu info of cpu-zero */
 #ifdef SMP
  pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu));
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/mem.c ./sys/mips/mips/mem.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/mem.c 2009-06-15 23:27:51.752241000 -0700
+++ ./sys/mips/mips/mem.c 2009-06-16 17:31:21.853419000 -0700
@@ -101,8 +101,15 @@
  vm_paddr_t pa;
  register int o;
 
+#ifdef CPU_SB1
+ if (!is_physical_memory(v) ||
+    !is_physical_memory(roundup2(v, PAGE_SIZE) - 1)) {
+ return (EFAULT);
+ }
+#else
  if (v + c > (SDRAM_ADDR_START + ctob(physmem)))
  return (EFAULT);
+#endif
 
  if (is_cacheable_mem(v) && is_cacheable_mem(v + c)) {
  struct fpage *fp;
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/nexus.c ./sys/mips/mips/nexus.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/nexus.c 2009-06-15 23:27:51.762242000 -0700
+++ ./sys/mips/mips/nexus.c 2009-06-16 17:31:21.866418000 -0700
@@ -76,6 +76,7 @@
 
 static struct rman irq_rman;
 static struct rman mem_rman;
+static struct rman port_rman;
 
 #ifdef notyet
 /*
@@ -173,6 +174,21 @@
  panic("%s: mem_rman", __func__);
  }
 
+ /*
+ * MIPS has no concept of the x86 I/O address space but some cpus
+ * provide a memory mapped window to access the PCI I/O BARs.
+ */
+ port_rman.rm_start = 0;
+#ifdef PCI_IOSPACE_SIZE
+ port_rman.rm_end = PCI_IOSPACE_SIZE - 1;
+#endif
+ port_rman.rm_type = RMAN_ARRAY;
+ port_rman.rm_descr = "I/O ports";
+ if (rman_init(&port_rman) != 0 ||
+    rman_manage_region(&port_rman, 0, port_rman.rm_end) != 0)
+ panic("%s: port_rman", __func__);
+
+
  return (0);
 }
 
@@ -180,16 +196,21 @@
 nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
     driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
 {
- int irq;
+ int irq, error;
 
- register_t sr = intr_disable();
  irq = rman_get_start(res);
  if (irq >= NUM_MIPS_IRQS)
  return (0);
 
+ if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
+ flags |= INTR_EXCL;
+
+ error = rman_activate_resource(res);
+ if (error)
+ return (error);
+
  cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg,
     irq, flags, cookiep);
- intr_restore(sr);
  return (0);
 }
 
@@ -238,6 +259,7 @@
 
  retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
  retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
+ retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
 
  return (retval);
 }
@@ -338,6 +360,9 @@
  case SYS_RES_MEMORY:
  rm = &mem_rman;
  break;
+ case SYS_RES_IOPORT:
+ rm = &port_rman;
+ break;
  default:
  printf("%s: unknown resource type %d\n", __func__, type);
  return (0);
@@ -380,6 +405,11 @@
                 u_int32_t poffs;
                 
                 paddr = rman_get_start(r);
+#ifdef PCI_IOSPACE_ADDR
+ if (type == SYS_RES_IOPORT) {
+ paddr += PCI_IOSPACE_ADDR;
+ }
+#endif
                 psize = rman_get_size(r);
                 poffs = paddr - trunc_page(paddr);
                 vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
@@ -473,6 +503,12 @@
 nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
   struct resource *r)
 {
+ vm_offset_t va;
+
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ va = (vm_offset_t)rman_get_virtual(r);
+ pmap_unmapdev(va, rman_get_size(r));
+ }
 
  return (rman_deactivate_resource(r));
 }
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/pmap.c ./sys/mips/mips/pmap.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/pmap.c 2009-06-15 23:27:51.769243000 -0700
+++ ./sys/mips/mips/pmap.c 2009-06-16 17:31:21.873419000 -0700
@@ -313,6 +313,8 @@
  }
  }
 
+ Maxmem = atop(phys_avail[i - 1]);
+
  if (bootverbose) {
  printf("Physical memory chunk(s):\n");
  for (i = 0; phys_avail[i + 1] != 0; i += 2) {
@@ -324,6 +326,7 @@
     (uintmax_t) phys_avail[i + 1] - 1,
     (uintmax_t) size, (uintmax_t) size / PAGE_SIZE);
  }
+ printf("Maxmem is 0x%0lx\n", ptoa(Maxmem));
  }
  /*
  * Steal the message buffer from the beginning of memory.
@@ -2226,7 +2229,7 @@
 #endif
  if (phys < MIPS_KSEG0_LARGEST_PHYS) {
 
- va = MIPS_PHYS_TO_UNCACHED(phys);
+ va = MIPS_PHYS_TO_CACHED(phys);
 
  bzero((caddr_t)va, PAGE_SIZE);
  mips_dcache_wbinv_range(va, PAGE_SIZE);
@@ -2282,7 +2285,7 @@
  } else
 #endif
  if (phys < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_UNCACHED(phys);
+ va = MIPS_PHYS_TO_CACHED(phys);
  bzero((char *)(caddr_t)va + off, size);
  mips_dcache_wbinv_range(va + off, size);
  } else {
@@ -2321,7 +2324,7 @@
  } else
 #endif
  if (phys < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_UNCACHED(phys);
+ va = MIPS_PHYS_TO_CACHED(phys);
  bzero((caddr_t)va, PAGE_SIZE);
  mips_dcache_wbinv_range(va, PAGE_SIZE);
  } else {
@@ -2803,11 +2806,12 @@
  return (void *)MIPS_PHYS_TO_KSEG1(pa);
  else {
  offset = pa & PAGE_MASK;
- size = roundup(size, PAGE_SIZE);
+ size = roundup(size + offset, PAGE_SIZE);
         
  va = kmem_alloc_nofault(kernel_map, size);
  if (!va)
  panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
+ pa = trunc_page(pa);
  for (tmpva = va; size > 0;) {
  pmap_kenter(tmpva, pa);
  size -= PAGE_SIZE;
@@ -2822,6 +2826,18 @@
 void
 pmap_unmapdev(vm_offset_t va, vm_size_t size)
 {
+ vm_offset_t base, offset, tmpva;
+
+ /* If the address is within KSEG1 then there is nothing to do */
+ if (va >= MIPS_KSEG1_START && va <= MIPS_KSEG1_END)
+ return;
+
+ base = trunc_page(va);
+ offset = va & PAGE_MASK;
+ size = roundup(size + offset, PAGE_SIZE);
+ for (tmpva = base; tmpva < base + size; tmpva += PAGE_SIZE)
+ pmap_kremove(tmpva);
+ kmem_free(kernel_map, base, size);
 }
 
 /*
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/swtch.S ./sys/mips/mips/swtch.S
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/swtch.S 2009-06-15 23:27:51.778242000 -0700
+++ ./sys/mips/mips/swtch.S 2009-06-16 17:31:21.878416000 -0700
@@ -81,14 +81,14 @@
 #define _MFC0 dmfc0
 #define _MTC0 dmtc0
 #define WIRED_SHIFT 34
-#define PAGE_SHIFT 34
+#define PAGE_SHIFT 12
 #else
 #define _SLL sll
 #define _SRL srl
 #define _MFC0 mfc0
 #define _MTC0 mtc0
 #define WIRED_SHIFT 2
-#define PAGE_SHIFT 2
+#define PAGE_SHIFT 12
 #endif
  .set noreorder # Noreorder is default style!
 #if defined(ISA_MIPS32)
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/tick.c ./sys/mips/mips/tick.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/tick.c 2009-06-15 23:27:51.779247000 -0700
+++ ./sys/mips/mips/tick.c 2009-06-16 17:31:21.884415000 -0700
@@ -229,7 +229,7 @@
 
  /* Check to see if the timer has wrapped around. */
  if (cur < last)
- delta += (cur + (cycles_per_hz - last));
+ delta += (cur + (0xffffffff - last) + 1);
  else
  delta += (cur - last);
 
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/tlb.S ./sys/mips/mips/tlb.S
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/tlb.S 2009-06-15 23:27:51.781242000 -0700
+++ ./sys/mips/mips/tlb.S 2009-06-16 17:31:21.889422000 -0700
@@ -81,14 +81,14 @@
 #define _MFC0 dmfc0
 #define _MTC0 dmtc0
 #define WIRED_SHIFT 34
-#define PAGE_SHIFT 34
+#define PAGE_SHIFT 12
 #else
 #define _SLL sll
 #define _SRL srl
 #define _MFC0 mfc0
 #define _MTC0 mtc0
 #define WIRED_SHIFT 2
-#define PAGE_SHIFT 2
+#define PAGE_SHIFT 12
 #endif
  .set noreorder # Noreorder is default style!
 #if defined(ISA_MIPS32)
@@ -473,7 +473,17 @@
  _MFC0 t4, COP_0_TLB_HI # Get current PID
  move t2, a0
  mfc0 t1, COP_0_TLB_WIRED
+
+ #
+ # Load invalid entry, each TLB entry should have it's own bogus
+ # address calculated by following expression:
+ # MIPS_KSEG0_START + 0x0fff0000 + 2 * i * PAGE_SIZE;
+ # One bogus value for every TLB entry might cause MCHECK exception
+ #
+ sll t3, t1, PAGE_SHIFT + 1
  li v0, MIPS_KSEG0_START + 0x0fff0000 # invalid address
+ addu v0, t3
+
  mfc0 t3, COP_0_TLB_PG_MASK # save current pgMask
 
  # do {} while (t1 < t2)
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/trap.c ./sys/mips/mips/trap.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/trap.c 2009-06-15 23:27:51.783244000 -0700
+++ ./sys/mips/mips/trap.c 2009-06-16 17:31:21.895420000 -0700
@@ -365,7 +365,7 @@
  printf("cpuid = %d\n", PCPU_GET(cpuid));
 #endif
  MachTLBGetPID(pid);
- printf("badaddr = %p, pc = %p, ra = %p, sp = %p, sr = 0x%x, pid = %d, ASID = 0x%x\n",
+ printf("badaddr = 0x%0x, pc = 0x%0x, ra = 0x%0x, sp = 0x%0x, sr = 0x%x, pid = %d, ASID = 0x%x\n",
     trapframe->badvaddr, trapframe->pc, trapframe->ra,
     trapframe->sp, trapframe->sr,
     (curproc ? curproc->p_pid : -1), pid);
@@ -389,7 +389,7 @@
     ((type & ~T_USER) != T_SYSCALL)) {
  if (++count == 3) {
  trap_frame_dump(trapframe);
- panic("too many faults at %p\n", last_badvaddr);
+ panic("too many faults at %x\n", last_badvaddr);
  }
  } else {
  last_badvaddr = this_badvaddr;
@@ -570,7 +570,7 @@
  --p->p_lock;
  PROC_UNLOCK(p);
 #ifdef VMFAULT_TRACE
- printf("vm_fault(%x (pmap %x), %x (%x), %x, %d) -> %x at pc %x\n",
+ printf("vm_fault(%p (pmap %p), %x (%x), %x, %d) -> %x at pc %x\n",
     map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, flag,
     rv, trapframe->pc);
 #endif
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/vm_machdep.c ./sys/mips/mips/vm_machdep.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/mips/vm_machdep.c 2009-06-15 23:27:51.787242000 -0700
+++ ./sys/mips/mips/vm_machdep.c 2009-06-16 17:31:21.901417000 -0700
@@ -395,6 +395,24 @@
  * Currently used by the kernel coredump code in order to avoid
  * dumping non-memory physical address space.
  */
+#ifdef CPU_SB1
+int
+is_physical_memory(vm_offset_t addr)
+{
+
+ if ((addr >= 0x00000000UL && addr < 0x10000000UL) ||
+    (addr >= 0x80000000UL && addr < 0xa0000000UL) ||
+    (addr >= 0xc0000000UL && addr < 0xd0000000UL)) {
+ return (1);
+ }
+#ifdef ISA_MIPS64
+ if (addr >= 0x0100000000ULL && addr < 0x8000000000ULL) {
+ return (1);
+ }
+#endif
+ return (0);
+}
+#else
 int
 is_physical_memory(vm_offset_t addr)
 {
@@ -403,7 +421,26 @@
  else
  return 0;
 }
+#endif /* CPU_SB1 */
 
+#ifdef CPU_SB1
+int
+is_cacheable_mem(vm_offset_t pa)
+{
+
+ return (is_physical_memory(pa));
+}
+
+int
+is_coherent_mem(vm_offset_t pa)
+{
+
+ /*
+ * All physical memory is marked cacheable-coherent on the sibyte.
+ */
+ return (is_physical_memory(pa));
+}
+#else
 int
 is_cacheable_mem(vm_offset_t pa)
 {
@@ -418,6 +455,14 @@
  return 0;
 }
 
+int
+is_coherent_mem(vm_offset_t pa)
+{
+
+ return (0);
+}
+#endif /* CPU_SB1 */
+
 /*
  * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-))
  */
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/ata_zbbus.c ./sys/mips/sibyte/ata_zbbus.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/ata_zbbus.c 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/ata_zbbus.c 2009-05-21 23:42:26.999969000 -0700
@@ -0,0 +1,170 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sema.h>
+#include <sys/taskqueue.h>
+
+#include <machine/bus.h>
+
+#include <vm/uma.h>
+
+#include <sys/ata.h>
+#include <dev/ata/ata-all.h>
+
+#include <machine/resource.h>
+
+__FBSDID("$FreeBSD$");
+
+static int
+ata_zbbus_probe(device_t dev)
+{
+
+ return (ata_probe(dev));
+}
+
+static int
+ata_zbbus_attach(device_t dev)
+{
+ int i, rid, regshift, regoffset;
+ struct ata_channel *ch;
+ struct resource *io;
+
+ ch = device_get_softc(dev);
+
+ if (ch->attached)
+ return (0);
+ ch->attached = 1;
+
+ rid = 0;
+ io = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE);
+ if (io == NULL)
+ return (ENXIO);
+
+ /*
+ * SWARM needs an address shift of 5 when accessing ATA registers.
+ *
+ * For e.g. an access to register 4 actually needs an address
+ * of (4 << 5) to be output on the generic bus.
+ */
+ regshift = 5;
+ resource_int_value(device_get_name(dev), device_get_unit(dev),
+   "regshift", ®shift);
+ if (regshift && bootverbose)
+ device_printf(dev, "using a register shift of %d\n", regshift);
+
+ regoffset = 0x1F0;
+ resource_int_value(device_get_name(dev), device_get_unit(dev),
+   "regoffset", ®offset);
+ if (regoffset && bootverbose) {
+ device_printf(dev, "using a register offset of 0x%0x\n",
+      regoffset);
+ }
+
+ /* setup the ata register addresses */
+ for (i = ATA_DATA; i <= ATA_COMMAND; ++i) {
+ ch->r_io[i].res = io;
+ ch->r_io[i].offset = (regoffset + i) << regshift;
+ }
+
+ ch->r_io[ATA_CONTROL].res = io;
+ ch->r_io[ATA_CONTROL].offset = (regoffset + ATA_CTLOFFSET) << regshift;
+ ch->r_io[ATA_IDX_ADDR].res = io; /* XXX what is this used for */
+ ata_default_registers(dev);
+
+ /* initialize softc for this channel */
+ ch->unit = 0;
+ ch->flags |= ATA_USE_16BIT;
+ ata_generic_hw(dev);
+
+ return (ata_attach(dev));
+}
+
+static int
+ata_zbbus_detach(device_t dev)
+{
+ int error;
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if (!ch->attached)
+ return (0);
+ ch->attached = 0;
+
+ error = ata_detach(dev);
+
+ bus_release_resource(dev, SYS_RES_MEMORY, 0,
+     ch->r_io[ATA_IDX_ADDR].res);
+
+ return (error);
+}
+
+static int
+ata_zbbus_suspend(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if (!ch->attached)
+ return (0);
+
+ return (ata_suspend(dev));
+}
+
+static int
+ata_zbbus_resume(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if (!ch->attached)
+ return (0);
+
+ return (ata_resume(dev));
+}
+
+static device_method_t ata_zbbus_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, ata_zbbus_probe),
+ DEVMETHOD(device_attach, ata_zbbus_attach),
+ DEVMETHOD(device_detach, ata_zbbus_detach),
+ DEVMETHOD(device_suspend, ata_zbbus_suspend),
+ DEVMETHOD(device_resume, ata_zbbus_resume),
+
+ { 0, 0 }
+};
+
+static driver_t ata_zbbus_driver = {
+ "ata",
+ ata_zbbus_methods,
+ sizeof(struct ata_channel)
+};
+
+DRIVER_MODULE(ata, zbbus, ata_zbbus_driver, ata_devclass, 0, 0);
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/files.sibyte ./sys/mips/sibyte/files.sibyte
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/files.sibyte 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/files.sibyte 2009-05-21 23:34:27.313938000 -0700
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+mips/sibyte/sb_machdep.c standard
+mips/sibyte/sb_zbbus.c standard
+mips/sibyte/sb_zbpci.c standard
+mips/sibyte/sb_scd.c standard
+mips/sibyte/ata_zbbus.c standard
+
+mips/sibyte/sb_asm.S standard
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_asm.S ./sys/mips/sibyte/sb_asm.S
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_asm.S 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/sb_asm.S 2009-05-18 20:25:17.798702000 -0700
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * 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.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * We compile a 32-bit kernel to run on the SB-1 processor which is a 64-bit
+ * processor. It has some registers that must be accessed using 64-bit load
+ * and store instructions.
+ *
+ * So we have to resort to assembly because the compiler does not emit the
+ * 'ld' and 'sd' instructions since it thinks that it is compiling for a
+ * 32-bit mips processor.
+ */
+
+.set mips64
+.set noat
+.set noreorder
+
+/*
+ * return (MIPS_PHYS_TO_KSEG1(0x10020008))
+ * Parameters: none
+ */
+LEAF(sb_read_syscfg)
+ lui     v0, 0xb002
+ ori     v0, v0, 0x8
+ ld      v1, 0(v0) /* syscfg = MIPS_PHYS_TO_KSEG1(0x10020008) */
+ move v0, v1
+ dsll32 v0, v0, 0
+ dsrl32 v0, v0, 0 /* v0 = lower_uint32(mask) */
+ jr ra
+ dsrl32 v1, v1, 0 /* v1 = upper_uint32(mask) */
+END(sb_read_syscfg)
+
+/*
+ * MIPS_PHYS_TO_KSEG1(0x10020008) = (uint64_t)val
+ * Parameters:
+ * - lower_uint32(val): a0
+ * - upper_uint32(val): a1
+ */
+LEAF(sb_write_syscfg)
+ lui     v0, 0xb002
+ ori     v0, v0, 0x8
+ dsll32 a1, a1, 0 /* clear lower 32 bits of a1 */
+ dsll32 a0, a0, 0
+ dsrl32 a0, a0, 0 /* clear upper 32 bits of a0 */
+ or a1, a1, a0
+ sd a1, 0(v0) /* MIPS_PHYS_TO_KSEG1(0x10020008) = val */
+ jr ra
+ nop
+ nop
+END(sb_write_syscfg)
+
+/*
+ * MIPS_PHYS_TO_KSEG1(0x10020028) |= (1 << intsrc)
+ *
+ * Parameters:
+ * - intsrc (a0)
+ */
+LEAF(sb_disable_intsrc)
+ lui     v0, 0xb002
+ ori     v0, v0, 0x28
+ ld      v1, 0(v0) /* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */
+ li      a1, 1
+ dsllv   a1, a1, a0
+ or      a1, a1, v1 /* mask |= (1 << intsrc) */
+ jr ra
+ sd      a1, 0(v0) /* MIPS_PHYS_TO_KSEG1(0x10020028) = mask */
+END(sb_disable_intsrc)
+
+/*
+ * MIPS_PHYS_TO_KSEG1(0x10020028) &= ~(1 << intsrc)
+ *
+ * Parameters:
+ * - intsrc (a0)
+ */
+LEAF(sb_enable_intsrc)
+ lui     v0, 0xb002
+ ori     v0, v0, 0x28
+ ld      v1, 0(v0) /* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */
+ li      a2, 1
+ dsllv   a2, a2, a0
+ nor     a2, zero, a2
+ and     a2, a2, v1 /* mask &= ~(1 << intsrc) */
+ sd      a2, 0(v0) /* MIPS_PHYS_TO_KSEG1(0x10020028) = mask */
+ jr      ra
+ nop
+END(sb_enable_intsrc)
+
+/*
+ * return ((uint64_t)MIPS_PHYS_TO_KSEG1(0x10020028))
+ * Parameters: none
+ */
+LEAF(sb_read_intsrc_mask)
+ lui     v0, 0xb002
+ ori     v0, v0, 0x28
+ ld      v1, 0(v0) /* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */
+ move v0, v1
+ dsll32 v0, v0, 0
+ dsrl32 v0, v0, 0 /* v0 = lower_uint32(mask) */
+ jr ra
+ dsrl32 v1, v1, 0 /* v1 = upper_uint32(mask) */
+END(sb_read_intsrc_mask)
+
+/*
+ * return ((uint64_t *)MIPS_PHYS_TO_KSEG1(0x10020200) + intsrc)
+ * Parameters:
+ * - intsrc (a0)
+ */
+LEAF(sb_read_intmap)
+ sll a0, a0, 3 /* compute the offset of the intmap register */
+ lui     v0, 0xb002
+ addu    a0, a0, v0
+ ld      v0, 512(a0) /* v0 = MIPS_PHYS_TO_KSEG1(0x10020200) + off */
+ jr      ra
+ nop
+END(sb_read_intmap)
+
+/*
+ * (uint64_t *)MIPS_PHYS_TO_KSEG1(0x10020200) + intsrc = irq
+ * Parameters:
+ * - intsrc (a0)
+ * - irq    (a1)
+ */
+LEAF(sb_write_intmap)
+ sll     a0, a0, 0x3 /* compute the offset of the intmap register */
+ lui     v0, 0xb002
+ addu    a0, a0, v0
+ sd      a1, 512(a0) /* MIPS_PHYS_TO_KSEG1(0x10020200) + off = irq */
+ jr      ra
+ nop
+END(sb_write_intmap)
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_machdep.c ./sys/mips/sibyte/sb_machdep.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_machdep.c 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/sb_machdep.c 2009-06-10 13:53:30.333084000 -0700
@@ -0,0 +1,259 @@
+/*-
+ * Copyright (c) 2007 Bruce M. Simpson.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <machine/cpuregs.h>
+
+#include "opt_ddb.h"
+#include "opt_kdb.h"
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/imgact.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/cons.h>
+#include <sys/exec.h>
+#include <sys/ucontext.h>
+#include <sys/proc.h>
+#include <sys/kdb.h>
+#include <sys/ptrace.h>
+#include <sys/reboot.h>
+#include <sys/signalvar.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/user.h>
+
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+#include <machine/cache.h>
+#include <machine/clock.h>
+#include <machine/cpu.h>
+#include <machine/cpuinfo.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuregs.h>
+#include <machine/hwfunc.h>
+#include <machine/intr_machdep.h>
+#include <machine/locore.h>
+#include <machine/md_var.h>
+#include <machine/pte.h>
+#include <machine/sigframe.h>
+#include <machine/trap.h>
+#include <machine/vmparam.h>
+
+#ifdef CFE
+#include <dev/cfe/cfe_api.h>
+#endif
+
+#include "sb_scd.h"
+
+#ifdef DDB
+#ifndef KDB
+#error KDB must be enabled in order for DDB to work!
+#endif
+#endif
+
+#ifdef CFE
+extern uint32_t cfe_handle;
+extern uint32_t cfe_vector;
+#endif
+
+#ifdef CFE_ENV
+extern void cfe_env_init(void);
+#endif
+
+extern int *edata;
+extern int *end;
+
+static void
+mips_init(void)
+{
+ int i, cfe_mem_idx, tmp;
+ uint64_t maxmem;
+
+#ifdef CFE_ENV
+ cfe_env_init();
+#endif
+
+ TUNABLE_INT_FETCH("boothowto", &boothowto);
+
+ if (boothowto & RB_VERBOSE)
+ bootverbose++;
+
+#ifdef MAXMEM
+ tmp = MAXMEM;
+#else
+ tmp = 0;
+#endif
+ TUNABLE_INT_FETCH("hw.physmem", &tmp);
+ maxmem = (uint64_t)tmp * 1024;
+
+#ifdef CFE
+ /*
+ * Query DRAM memory map from CFE.
+ */
+ physmem = 0;
+ cfe_mem_idx = 0;
+ for (i = 0; i < 10; i += 2) {
+ int result;
+ uint64_t addr, len, type;
+
+ result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type);
+ if (result < 0) {
+ phys_avail[i] = phys_avail[i + 1] = 0;
+ break;
+ }
+
+ KASSERT(type == CFE_MI_AVAILABLE,
+ ("CFE DRAM region is not available?"));
+
+ if (bootverbose)
+ printf("cfe_enummem: 0x%016jx/%llu.\n", addr, len);
+
+ if (maxmem != 0) {
+ if (addr >= maxmem) {
+ printf("Ignoring %llu bytes of memory at 0x%jx "
+       "that is above maxmem %dMB\n",
+       len, addr,
+       (int)(maxmem / (1024 * 1024)));
+ continue;
+ }
+
+ if (addr + len > maxmem) {
+ printf("Ignoring %llu bytes of memory "
+       "that is above maxmem %dMB\n",
+       (addr + len) - maxmem,
+       (int)(maxmem / (1024 * 1024)));
+ len = maxmem - addr;
+ }
+ }
+
+ phys_avail[i] = addr;
+ if (i == 0 && addr == 0) {
+ /*
+ * If this is the first physical memory segment probed
+ * from CFE, omit the region at the start of physical
+ * memory where the kernel has been loaded.
+ */
+ phys_avail[i] += MIPS_KSEG0_TO_PHYS((vm_offset_t)&end);
+ }
+ phys_avail[i + 1] = addr + len;
+ physmem += len;
+ }
+
+ realmem = btoc(physmem);
+#endif
+
+ physmem = realmem;
+
+ init_param1();
+ init_param2(physmem);
+ mips_cpu_init();
+ pmap_bootstrap();
+ mips_proc0_init();
+ mutex_init();
+
+ kdb_init();
+#ifdef KDB
+ if (boothowto & RB_KDB)
+ kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
+#endif
+}
+
+void
+platform_halt(void)
+{
+
+}
+
+
+void
+platform_identify(void)
+{
+
+}
+
+void
+platform_reset(void)
+{
+
+ /*
+ * XXX SMP
+ * XXX flush data caches
+ */
+ sb_system_reset();
+}
+
+void
+platform_trap_enter(void)
+{
+
+}
+
+void
+platform_trap_exit(void)
+{
+
+}
+
+void
+platform_start(__register_t a0 __unused, __register_t a1 __unused,
+    __register_t a2 __unused, __register_t a3 __unused)
+{
+ vm_offset_t kernend;
+
+ /* clear the BSS and SBSS segments */
+ memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata);
+ kernend = round_page((vm_offset_t)&end);
+
+#ifdef CFE
+ /*
+ * Initialize CFE firmware trampolines before
+ * we initialize the low-level console.
+ */
+ if (cfe_handle != 0)
+ cfe_init(cfe_handle, cfe_vector);
+#endif
+ cninit();
+
+#ifdef CFE
+ if (cfe_handle == 0)
+ panic("CFE was not detected by locore.\n");
+#endif
+ mips_init();
+
+ mips_timer_init_params(sb_cpu_speed(), 0);
+}
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_scd.c ./sys/mips/sibyte/sb_scd.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_scd.c 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/sb_scd.c 2009-05-15 16:51:56.362688000 -0700
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * 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.
+ */
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/resource.h>
+
+#include "sb_scd.h"
+
+__FBSDID("$FreeBSD$");
+
+/*
+ * System Control and Debug (SCD) unit on the Sibyte ZBbus.
+ */
+
+/*
+ * Extract the value starting at bit position 'b' for 'n' bits from 'x'.
+ */
+#define GET_VAL_64(x, b, n) (((x) >> (b)) & ((1ULL << (n)) - 1))
+
+#define SYSCFG_PLLDIV(x) GET_VAL_64((x), 7, 5)
+
+uint64_t
+sb_cpu_speed(void)
+{
+ int plldiv;
+ const uint64_t MHZ = 1000000;
+
+ plldiv = SYSCFG_PLLDIV(sb_read_syscfg());
+ if (plldiv == 0) {
+ printf("PLL_DIV is 0 - assuming 6 (300MHz).\n");
+ plldiv = 6;
+ }
+
+ return (plldiv * 50 * MHZ);
+}
+
+void
+sb_system_reset(void)
+{
+ uint64_t syscfg;
+
+ const uint64_t SYSTEM_RESET = 1ULL << 60;
+ const uint64_t EXT_RESET = 1ULL << 59;
+ const uint64_t SOFT_RESET = 1ULL << 58;
+
+ syscfg = sb_read_syscfg();
+ syscfg &= ~SOFT_RESET;
+ syscfg |= SYSTEM_RESET | EXT_RESET;
+ sb_write_syscfg(syscfg);
+}
+
+int
+sb_route_intsrc(int intsrc)
+{
+ int intrnum;
+
+ KASSERT(intsrc >= 0 && intsrc < NUM_INTSRC,
+ ("Invalid interrupt source number (%d)", intsrc));
+
+ /*
+ * Interrupt 5 is used by sources internal to the CPU (e.g. timer).
+ * Use a deterministic mapping for the remaining sources to map to
+ * interrupt numbers 0 through 4.
+ */
+ intrnum = intsrc % 5;
+
+ /*
+ * Program the interrupt mapper while we are here.
+ */
+ sb_write_intmap(intsrc, intrnum);
+
+ return (intrnum);
+}
+
+#define SCD_PHYSADDR 0x10000000
+#define SCD_SIZE 0x00060000
+
+static int
+scd_probe(device_t dev)
+{
+
+ device_set_desc(dev, "Broadcom/Sibyte System Control and Debug");
+ return (0);
+}
+
+static int
+scd_attach(device_t dev)
+{
+ int rid;
+ struct resource *res;
+
+ if (bootverbose) {
+ device_printf(dev, "attached.\n");
+ }
+
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, SCD_PHYSADDR,
+ SCD_PHYSADDR + SCD_SIZE - 1, SCD_SIZE, 0);
+ if (res == NULL) {
+ panic("Cannot allocate resource for system control and debug.");
+ }
+
+ return (0);
+}
+
+static device_method_t scd_methods[] ={
+ /* Device interface */
+ DEVMETHOD(device_probe, scd_probe),
+ DEVMETHOD(device_attach, scd_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 scd_driver = {
+ "scd",
+ scd_methods
+};
+
+static devclass_t scd_devclass;
+
+DRIVER_MODULE(scd, zbbus, scd_driver, scd_devclass, 0, 0);
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_scd.h ./sys/mips/sibyte/sb_scd.h
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_scd.h 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/sb_scd.h 2009-05-15 01:58:12.318422000 -0700
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * 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.
+ */
+
+#ifndef _SB_SCD_H_
+#define _SB_SCD_H_
+
+#define NUM_INTSRC 64 /* total number of interrupt sources */
+
+uint64_t sb_cpu_speed(void);
+void sb_system_reset(void);
+
+int sb_route_intsrc(int src);
+void sb_enable_intsrc(int src);
+void sb_disable_intsrc(int src);
+uint64_t sb_read_intsrc_mask(void);
+
+int sb_read_intmap(int intsrc);
+void sb_write_intmap(int intsrc, int intrnum);
+
+uint64_t sb_read_syscfg(void);
+void sb_write_syscfg(uint64_t val);
+
+#endif /* _SB_SCD_H_ */
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_zbbus.c ./sys/mips/sibyte/sb_zbbus.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_zbbus.c 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/sb_zbbus.c 2009-06-13 12:29:39.515055000 -0700
@@ -0,0 +1,501 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+
+#include <machine/resource.h>
+#include <machine/intr_machdep.h>
+
+#include "sb_scd.h"
+
+__FBSDID("$FreeBSD$");
+
+static MALLOC_DEFINE(M_INTMAP, "sb1250 intmap", "Sibyte 1250 Interrupt Mapper");
+
+#define NUM_HARD_IRQS 6
+
+struct sb_intmap {
+ int intsrc; /* interrupt mapper register number (0 - 63) */
+ int active; /* Does this source generate interrupts? */
+
+ /*
+ * The device that the interrupt belongs to. Note that multiple
+ * devices may share an interrupt. For e.g. PCI_INT_x lines.
+ *
+ * The device 'dev' in combination with the 'rid' uniquely
+ * identify this interrupt source.
+ */
+ device_t dev;
+ int rid;
+
+ SLIST_ENTRY(sb_intmap) next;
+};
+
+/*
+ * We register 'sb_intsrc.isrc' using cpu_register_hard_intsrc() for each
+ * hard interrupt source [0-5].
+ *
+ * The mask/unmask callbacks use the information in 'sb_intmap' to figure
+ * out the corresponding interrupt sources to mask/unmask.
+ */
+struct sb_intsrc {
+ struct intsrc isrc;
+ SLIST_HEAD(, sb_intmap) sb_intmap_head;
+};
+
+static struct sb_intsrc sb_intsrc[NUM_HARD_IRQS];
+
+static struct sb_intmap *
+sb_intmap_lookup(int intrnum, device_t dev, int rid)
+{
+ struct sb_intsrc *isrc;
+ struct sb_intmap *map;
+
+ isrc = &sb_intsrc[intrnum];
+ SLIST_FOREACH(map, &isrc->sb_intmap_head, next) {
+ if (dev == map->dev && rid == map->rid)
+ break;
+ }
+ return (map);
+}
+
+/*
+ * Keep track of which (dev,rid) tuple is using the interrupt source.
+ *
+ * We don't actually unmask the interrupt source until the device calls
+ * a bus_setup_intr() on the resource.
+ */
+static void
+sb_intmap_add(int intrnum, device_t dev, int rid, int intsrc)
+{
+ struct sb_intsrc *isrc;
+ struct sb_intmap *map;
+ register_t sr;
+
+ KASSERT(intrnum >= 0 && intrnum < NUM_HARD_IRQS,
+ ("intrnum is out of range: %d", intrnum));
+
+ isrc = &sb_intsrc[intrnum];
+ map = sb_intmap_lookup(intrnum, dev, rid);
+ if (map) {
+ KASSERT(intsrc == map->intsrc,
+ ("%s%d allocating SYS_RES_IRQ resource with rid %d "
+ "with a different intsrc (%d versus %d)",
+ device_get_name(dev), device_get_unit(dev), rid,
+ intsrc, map->intsrc));
+ return;
+ }
+
+ map = malloc(sizeof(*map), M_INTMAP, M_WAITOK | M_ZERO);
+ map->intsrc = intsrc;
+ map->dev = dev;
+ map->rid = rid;
+
+ sr = intr_disable();
+ SLIST_INSERT_HEAD(&isrc->sb_intmap_head, map, next);
+ intr_restore(sr);
+}
+
+static void
+sb_intmap_activate(int intrnum, device_t dev, int rid)
+{
+ struct sb_intmap *map;
+ register_t sr;
+
+ KASSERT(intrnum >= 0 && intrnum < NUM_HARD_IRQS,
+ ("intrnum is out of range: %d", intrnum));
+
+ map = sb_intmap_lookup(intrnum, dev, rid);
+ if (map) {
+ /*
+ * See comments in sb_unmask_func() about disabling cpu intr
+ */
+ sr = intr_disable();
+ map->active = 1;
+ sb_enable_intsrc(map->intsrc);
+ intr_restore(sr);
+ } else {
+ /*
+ * In zbbus_setup_intr() we blindly call sb_intmap_activate()
+ * for every interrupt activation that comes our way.
+ *
+ * We might end up here if we did not "hijack" the SYS_RES_IRQ
+ * resource in zbbus_alloc_resource().
+ */
+ printf("sb_intmap_activate: unable to activate interrupt %d "
+       "for device %s%d rid %d.\n", intrnum,
+       device_get_name(dev), device_get_unit(dev), rid);
+ }
+}
+
+static void
+sb_mask_func(struct intsrc *arg)
+{
+ struct sb_intmap *map;
+ struct sb_intsrc *isrc;
+ uint64_t isrc_bitmap;
+
+ isrc_bitmap = 0;
+ isrc = (struct sb_intsrc *)arg;
+ SLIST_FOREACH(map, &isrc->sb_intmap_head, next) {
+ if (map->active == 0)
+ continue;
+ /*
+ * If we have already disabled this interrupt source then don't
+ * do it again. This can happen when multiple devices share
+ * an interrupt source (e.g. PCI_INT_x).
+ */
+ if (isrc_bitmap & (1ULL << map->intsrc))
+ continue;
+ sb_disable_intsrc(map->intsrc);
+ isrc_bitmap |= 1ULL << map->intsrc;
+ }
+}
+
+static void
+sb_unmask_func(struct intsrc *arg)
+{
+ struct sb_intmap *map;
+ struct sb_intsrc *sb_isrc;
+ uint64_t isrc_bitmap;
+ register_t sr;
+
+ isrc_bitmap = 0;
+ sb_isrc = (struct sb_intsrc *)arg;
+
+ /*
+ * Make sure we disable the cpu interrupts when enabling the
+ * interrupt sources.
+ *
+ * This is to prevent a condition where some interrupt sources have
+ * been enabled (but not all) and one of those interrupt sources
+ * triggers an interrupt.
+ *
+ * If any of the interrupt handlers executes in an ithread then
+ * cpu_intr() will return with all interrupt sources feeding into
+ * that cpu irq masked. But when the loop below picks up where it
+ * left off it will enable the remaining interrupt sources!!!
+ *
+ * If the disable the cpu interrupts then this race does not happen.
+ */
+ sr = intr_disable();
+
+ SLIST_FOREACH(map, &sb_isrc->sb_intmap_head, next) {
+ if (map->active == 0)
+ continue;
+ /*
+ * If we have already enabled this interrupt source then don't
+ * do it again. This can happen when multiple devices share
+ * an interrupt source (e.g. PCI_INT_x).
+ */
+ if (isrc_bitmap & (1ULL << map->intsrc))
+ continue;
+ sb_enable_intsrc(map->intsrc);
+ isrc_bitmap |= 1ULL << map->intsrc;
+ }
+
+ intr_restore(sr);
+}
+
+struct zbbus_devinfo {
+ struct resource_list resources;
+};
+
+static MALLOC_DEFINE(M_ZBBUSDEV, "zbbusdev", "zbbusdev");
+
+static int
+zbbus_probe(device_t dev)
+{
+
+ device_set_desc(dev, "Broadcom/Sibyte ZBbus");
+ return (0);
+}
+
+static int
+zbbus_attach(device_t dev)
+{
+ int i, error;
+ struct intsrc *isrc;
+
+ if (bootverbose) {
+ device_printf(dev, "attached.\n");
+ }
+
+ for (i = 0; i < NUM_HARD_IRQS; ++i) {
+ isrc = &sb_intsrc[i].isrc;
+ isrc->intrnum = i;
+ isrc->mask_func = sb_mask_func;
+ isrc->unmask_func = sb_unmask_func;
+ error = cpu_register_hard_intsrc(isrc);
+ if (error)
+ panic("Error %d registering intsrc %d", error, i);
+ }
+
+ bus_generic_probe(dev);
+ bus_enumerate_hinted_children(dev);
+ bus_generic_attach(dev);
+
+ return (0);
+}
+
+static void
+zbbus_hinted_child(device_t bus, const char *dname, int dunit)
+{
+ device_t child;
+ long maddr, msize;
+ int err, irq;
+
+ if (resource_disabled(dname, dunit))
+ return;
+
+ child = BUS_ADD_CHILD(bus, 0, dname, dunit);
+ if (child == NULL) {
+ panic("zbbus: could not add child %s unit %d\n", dname, dunit);
+ }
+
+ if (bootverbose)
+ device_printf(bus, "Adding hinted child %s%d\n", dname, dunit);
+
+ /*
+ * Assign any pre-defined resources to the child.
+ */
+ if (resource_long_value(dname, dunit, "msize", &msize) == 0 &&
+    resource_long_value(dname, dunit, "maddr", &maddr) == 0) {
+ if (bootverbose) {
+ device_printf(bus, "Assigning memory resource "
+   "0x%0lx/%ld to child %s%d\n",
+   maddr, msize, dname, dunit);
+ }
+ err = bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize);
+ if (err) {
+ device_printf(bus, "Unable to set memory resource "
+   "0x%0lx/%ld for child %s%d: %d\n",
+   maddr, msize, dname, dunit, err);
+ }
+ }
+
+ if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
+ if (bootverbose) {
+ device_printf(bus, "Assigning irq resource %d to "
+   "child %s%d\n", irq, dname, dunit);
+ }
+ err = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
+ if (err) {
+ device_printf(bus, "Unable to set irq resource %d"
+   "for child %s%d: %d\n",
+   irq, dname, dunit, err);
+ }
+ }
+}
+
+static struct resource *
+zbbus_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 resource *res;
+ int intrnum, intsrc, isdefault;
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
+ struct zbbus_devinfo *dinfo;
+
+ isdefault = (start == 0UL && end == ~0UL && count == 1);
+
+ /*
+ * Our direct child is asking for a default resource allocation.
+ */
+ if (device_get_parent(child) == bus) {
+ dinfo = device_get_ivars(child);
+ rl = &dinfo->resources;
+ rle = resource_list_find(rl, type, *rid);
+ if (rle) {
+ if (rle->res)
+ panic("zbbus_alloc_resource: resource is busy");
+ if (isdefault) {
+ start = rle->start;
+ count = ulmax(count, rle->count);
+ end = ulmax(rle->end, start + count - 1);
+ }
+ } else {
+ if (isdefault) {
+ /*
+ * Our child is requesting a default
+ * resource allocation but we don't have the
+ * 'type/rid' tuple in the resource list.
+ *
+ * We have to fail the resource allocation.
+ */
+ return (NULL);
+ } else {
+ /*
+ * The child is requesting a non-default
+ * resource. We just pass the request up
+ * to our parent. If the resource allocation
+ * succeeds we will create a resource list
+ * entry corresponding to that resource.
+ */
+ }
+ }
+ } else {
+ rl = NULL;
+ rle = NULL;
+ }
+
+ /*
+ * nexus doesn't know about the interrupt mapper and only wants to
+ * see the hard irq numbers [0-6]. We translate from the interrupt
+ * source presented to the mapper to the interrupt number presented
+ * to the cpu.
+ */
+ if ((count == 1) && (type == SYS_RES_IRQ)) {
+ intsrc = start;
+ intrnum = sb_route_intsrc(intsrc);
+ start = end = intrnum;
+ } else {
+ intsrc = -1; /* satisfy gcc */
+ intrnum = -1;
+ }
+
+ res = bus_generic_alloc_resource(bus, child, type, rid,
+ start, end, count, flags);
+
+ /*
+ * Keep track of the input into the interrupt mapper that maps
+ * to the resource allocated by 'child' with resource id 'rid'.
+ *
+ * If we don't record the mapping here then we won't be able to
+ * locate the interrupt source when bus_setup_intr(child,rid) is
+ * called.
+ */
+ if (res != NULL && intrnum != -1)
+ sb_intmap_add(intrnum, child, rman_get_rid(res), intsrc);
+
+ /*
+ * If a non-default resource allocation by our child was successful
+ * then keep track of the resource in the resource list associated
+ * with the child.
+ */
+ if (res != NULL && rle == NULL && device_get_parent(child) == bus) {
+ resource_list_add(rl, type, *rid, start, end, count);
+ rle = resource_list_find(rl, type, *rid);
+ if (rle == NULL)
+ panic("zbbus_alloc_resource: cannot find resource");
+ }
+
+ if (rle != NULL) {
+ KASSERT(device_get_parent(child) == bus,
+ ("rle should be NULL for passthru device"));
+ rle->res = res;
+ if (rle->res) {
+ rle->start = rman_get_start(rle->res);
+ rle->end = rman_get_end(rle->res);
+ rle->count = count;
+ }
+ }
+
+ return (res);
+}
+
+static int
+zbbus_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
+ driver_filter_t *filter, driver_intr_t *intr, void *arg,
+ void **cookiep)
+{
+ int error;
+
+ error = bus_generic_setup_intr(dev, child, irq, flags,
+       filter, intr, arg, cookiep);
+ if (error == 0)
+ sb_intmap_activate(rman_get_start(irq), child,
+   rman_get_rid(irq));
+
+ return (error);
+}
+
+static device_t
+zbbus_add_child(device_t bus, int order, const char *name, int unit)
+{
+ device_t child;
+ struct zbbus_devinfo *dinfo;
+
+ child = device_add_child_ordered(bus, order, name, unit);
+ if (child != NULL) {
+ dinfo = malloc(sizeof(struct zbbus_devinfo), M_ZBBUSDEV,
+       M_WAITOK | M_ZERO);
+ resource_list_init(&dinfo->resources);
+ device_set_ivars(child, dinfo);
+ }
+
+ return (child);
+}
+
+static struct resource_list *
+zbbus_get_resource_list(device_t dev, device_t child)
+{
+ struct zbbus_devinfo *dinfo = device_get_ivars(child);
+
+ return (&dinfo->resources);
+}
+
+static device_method_t zbbus_methods[] ={
+ /* Device interface */
+ DEVMETHOD(device_probe, zbbus_probe),
+ DEVMETHOD(device_attach, zbbus_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_alloc_resource, zbbus_alloc_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_get_resource_list,zbbus_get_resource_list),
+ DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
+ DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource),
+ DEVMETHOD(bus_setup_intr, zbbus_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_add_child, zbbus_add_child),
+ DEVMETHOD(bus_hinted_child, zbbus_hinted_child),
+
+ { 0, 0 }
+};
+
+static driver_t zbbus_driver = {
+ "zbbus",
+ zbbus_methods
+};
+
+static devclass_t zbbus_devclass;
+
+DRIVER_MODULE(zbbus, nexus, zbbus_driver, zbbus_devclass, 0, 0);
diff -Nurd /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_zbpci.c ./sys/mips/sibyte/sb_zbpci.c
--- /u/neelnatu/p4/freebsd_current/src/sys/mips/sibyte/sb_zbpci.c 1969-12-31 16:00:00.000000000 -0800
+++ ./sys/mips/sibyte/sb_zbpci.c 2009-06-13 12:31:52.042328000 -0700
@@ -0,0 +1,283 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/pcpu.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcib_private.h>
+
+#include <machine/pmap.h>
+#include <machine/resource.h>
+
+#include "pcib_if.h"
+
+#include "sb_scd.h"
+
+__FBSDID("$FreeBSD$");
+
+static struct {
+ vm_offset_t vaddr;
+ vm_paddr_t  paddr;
+} zbpci_config_space[MAXCPU];
+
+static const vm_paddr_t CFG_PADDR_BASE = 0xFE000000;
+
+static int
+zbpci_probe(device_t dev)
+{
+
+ device_set_desc(dev, "Broadcom/Sibyte PCI I/O Bridge");
+ return (0);
+}
+
+static int
+zbpci_attach(device_t dev)
+{
+ int n, rid, size;
+ vm_offset_t va;
+ struct resource *res;
+
+ /*
+ * Reserve the the physical memory that is used to read/write to the
+ * pci config space but don't activate it. We are using a page worth
+ * of KVA as a window over this region.
+ */
+ rid = 0;
+ size = (PCI_BUSMAX + 1) * (PCI_SLOTMAX + 1) * (PCI_FUNCMAX + 1) * 256;
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, CFG_PADDR_BASE,
+ CFG_PADDR_BASE + size - 1, size, 0);
+ if (res == NULL) {
+ panic("Cannot allocate resource for config space accesses.");
+ }
+
+ /*
+ * Allocate KVA for accessing PCI config space.
+ */
+ va = kmem_alloc_nofault(kernel_map, PAGE_SIZE * mp_ncpus);
+ if (va == 0) {
+ device_printf(dev, "Cannot allocate virtual addresses for "
+   "config space access.\n");
+ return (ENOMEM);
+ }
+
+ for (n = 0; n < mp_ncpus; ++n) {
+ zbpci_config_space[n].vaddr = va + n * PAGE_SIZE;
+ }
+
+ /*
+ * Sibyte has the PCI bus hierarchy rooted at bus 0 and HT-PCI
+ * hierarchy rooted at bus 1.
+ */
+ if (device_add_child(dev, "pci", 0) == NULL) {
+ panic("zbpci_attach: could not add pci bus 0.\n");
+ }
+
+ if (device_add_child(dev, "pci", 1) == NULL) {
+ panic("zbpci_attach: could not add pci bus 1.\n");
+ }
+
+ if (bootverbose) {
+ device_printf(dev, "attached.\n");
+ }
+
+ return (bus_generic_attach(dev));
+}
+
+static int
+zbpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+
+ switch (which) {
+ case PCIB_IVAR_DOMAIN:
+ *result = 0; /* single PCI domain */
+ return (0);
+ case PCIB_IVAR_BUS:
+ *result = device_get_unit(child); /* PCI bus 0 or 1 */
+ return (0);
+ default:
+ return (ENOENT);
+ }
+}
+
+/*
+ * We rely on the CFE to have configured the intline correctly to point to
+ * one of PCI-A/PCI-B/PCI-C/PCI-D in the interupt mapper.
+ */
+static int
+zbpci_route_interrupt(device_t pcib, device_t dev, int pin)
+{
+
+ return (PCI_INVALID_IRQ);
+}
+
+/*
+ * This function is expected to be called in a critical section since it
+ * changes the per-cpu pci config space va-to-pa mappings.
+ */
+static vm_offset_t
+zbpci_config_space_va(int bus, int slot, int func, int reg, int bytes)
+{
+ int cpu;
+ vm_offset_t va_page;
+ vm_paddr_t pa, pa_page;
+
+ if (bus <= PCI_BUSMAX && slot <= PCI_SLOTMAX && func <= PCI_FUNCMAX &&
+    reg <= PCI_REGMAX && (bytes == 1 || bytes == 2 || bytes == 4) &&
+    ((reg & (bytes - 1)) == 0)) {
+ cpu = PCPU_GET(cpuid);
+ va_page = zbpci_config_space[cpu].vaddr;
+ pa = CFG_PADDR_BASE |
+     (bus << 16) | (slot << 11) | (func << 8) | reg;
+ pa_page = pa & ~(PAGE_SIZE - 1);
+ if (zbpci_config_space[cpu].paddr != pa_page) {
+ pmap_kremove(va_page);
+ pmap_kenter(va_page, pa_page);
+ zbpci_config_space[cpu].paddr = pa_page;
+ }
+ return (va_page + (pa - pa_page));
+ } else {
+ return (0);
+ }
+}
+
+static uint32_t
+zbpci_read_config(device_t dev, u_int b, u_int s, u_int f, u_int r, int w)
+{
+ uint32_t data;
+ vm_offset_t va;
+
+ critical_enter();
+
+ va = zbpci_config_space_va(b, s, f, r, w);
+ if (va == 0) {
+ panic("zbpci_read_config: invalid %d/%d/%d[%d] %d\n",
+      b, s, f, r, w);
+ }
+
+ switch (w) {
+ case 4:
+ data = *(uint32_t *)va;
+ break;
+ case 2:
+ data = *(uint16_t *)va;
+ break;
+ case 1:
+ data = *(uint8_t *)va;
+ break;
+ default:
+ panic("zbpci_read_config: invalid width %d\n", w);
+ }
+
+ critical_exit();
+
+ return (data);
+}
+
+static void
+zbpci_write_config(device_t d, u_int b, u_int s, u_int f, u_int r,
+   uint32_t data, int w)
+{
+ vm_offset_t va;
+
+ critical_enter();
+
+ va = zbpci_config_space_va(b, s, f, r, w);
+ if (va == 0) {
+ panic("zbpci_write_config: invalid %d/%d/%d[%d] %d/%d\n",
+      b, s, f, r, data, w);
+ }
+
+ switch (w) {
+ case 4:
+ *(uint32_t *)va = data;
+ break;
+ case 2:
+ *(uint16_t *)va = data;
+ break;
+ case 1:
+ *(uint8_t *)va = data;
+ break;
+ default:
+ panic("zbpci_write_config: invalid width %d\n", w);
+ }
+
+ critical_exit();
+}
+
+static device_method_t zbpci_methods[] ={
+ /* Device interface */
+ DEVMETHOD(device_probe, zbpci_probe),
+ DEVMETHOD(device_attach, zbpci_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_read_ivar, zbpci_read_ivar),
+ DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_add_child, bus_generic_add_child),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, pcib_maxslots),
+ DEVMETHOD(pcib_read_config, zbpci_read_config),
+ DEVMETHOD(pcib_write_config, zbpci_write_config),
+ DEVMETHOD(pcib_route_interrupt, zbpci_route_interrupt),
+
+ { 0, 0 }
+};
+
+/*
+ * The "zbpci" class inherits from the "pcib" base class. Therefore in
+ * addition to drivers that belong to the "zbpci" class we will also
+ * consider drivers belonging to the "pcib" when probing children of
+ * "zbpci".
+ */
+DECLARE_CLASS(pcib_driver);
+DEFINE_CLASS_1(zbpci, zbpci_driver, zbpci_methods, 0, pcib_driver);
+
+static devclass_t zbpci_devclass;
+
+DRIVER_MODULE(zbpci, zbbus, zbpci_driver, zbpci_devclass, 0, 0);

_______________________________________________
freebsd-mips@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mips
To unsubscribe, send any mail to "freebsd-mips-unsubscribe@..."

Re: FreeBSD/mips booting on Sibyte 1250

by Oleksandr Tymoshenko-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Neelkanth Natu wrote:
> Hi Warner,
>
> I have attached the diffs against -current at revision 194280.
>
> There are some changes in the diff that are unrelated to the sibyte
> work and probably should be committed separately.
>
> I can provide more information about changes to specific files if necessary.
     Thanks for contribution. I'm trying to make platform-independent
part of mips/ tree and userland stable and once it's done more time
will be available for adding new platforms (I hope it will be soon
enough) :)
     Meanwhile I'd appreciate if you test attached patch for busdma
with your hardware. This implementation has been shamelessly ripped
from arm code tree and should handle alignment/boundaries limitations
properly. If possible, test with several DMA-enabled devices working
simultaneously. Thanks.

Patch: http://people.freebsd.org/~gonzo/busdma.diff
_______________________________________________
freebsd-mips@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mips
To unsubscribe, send any mail to "freebsd-mips-unsubscribe@..."

Parent Message unknown Re: FreeBSD/mips booting on Sibyte 1250

by Neelkanth Natu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi Oleksandr,

I'll try out your patch and let you know how it goes.

Do you have anything in particular that you will be working on in the
platform-independent part? I could help if needed.

best
Neel

--- On Fri, 6/26/09, Oleksandr Tymoshenko <gonzo@...> wrote:

> From: Oleksandr Tymoshenko <gonzo@...>
> Subject: Re: FreeBSD/mips booting on Sibyte 1250
> To: "Neelkanth Natu" <neelnatu@...>
> Cc: freebsd-mips@..., "Alexandr Rybalko" <ray@...>
> Date: Friday, June 26, 2009, 2:14 PM
> Neelkanth Natu wrote:
> > Hi Warner,
> >
> > I have attached the diffs against -current at revision
> 194280.
> >
> > There are some changes in the diff that are unrelated
> to the sibyte
> > work and probably should be committed separately.
> >
> > I can provide more information about changes to
> specific files if necessary.
>     Thanks for contribution. I'm trying to make
> platform-independent
> part of mips/ tree and userland stable and once it's done
> more time
> will be available for adding new platforms (I hope it will
> be soon
> enough) :)
>     Meanwhile I'd appreciate if you test attached
> patch for busdma
> with your hardware. This implementation has been
> shamelessly ripped
> from arm code tree and should handle alignment/boundaries
> limitations
> properly. If possible, test with several DMA-enabled
> devices working
> simultaneously. Thanks.
>
> Patch: http://people.freebsd.org/~gonzo/busdma.diff
>


     
_______________________________________________
freebsd-mips@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mips
To unsubscribe, send any mail to "freebsd-mips-unsubscribe@..."

Re: FreeBSD/mips booting on Sibyte 1250

by Oleksandr Tymoshenko-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Neelkanth Natu wrote:
> Hi Oleksandr,
>
> I'll try out your patch and let you know how it goes.
>
> Do you have anything in particular that you will be working on in the
> platform-independent part? I could help if needed.
>  
    I just tried to build several ports and see if it's going to
succeed. As a result
bug in pmap_qenter was fixed and threads work in FreeBSD/mips now.  So far
I managed to build python and perl(with system malloc) and they seem
to work. More thorough testing required though.
   

> best
> Neel
>
> --- On Fri, 6/26/09, Oleksandr Tymoshenko <gonzo@...> wrote:
>
>  
>> From: Oleksandr Tymoshenko <gonzo@...>
>> Subject: Re: FreeBSD/mips booting on Sibyte 1250
>> To: "Neelkanth Natu" <neelnatu@...>
>> Cc: freebsd-mips@..., "Alexandr Rybalko" <ray@...>
>> Date: Friday, June 26, 2009, 2:14 PM
>> Neelkanth Natu wrote:
>>    
>>> Hi Warner,
>>>
>>> I have attached the diffs against -current at revision
>>>      
>> 194280.
>>    
>>> There are some changes in the diff that are unrelated
>>>      
>> to the sibyte
>>    
>>> work and probably should be committed separately.
>>>
>>> I can provide more information about changes to
>>>      
>> specific files if necessary.
>>     Thanks for contribution. I'm trying to make
>> platform-independent
>> part of mips/ tree and userland stable and once it's done
>> more time
>> will be available for adding new platforms (I hope it will
>> be soon
>> enough) :)
>>     Meanwhile I'd appreciate if you test attached
>> patch for busdma
>> with your hardware. This implementation has been
>> shamelessly ripped
>> from arm code tree and should handle alignment/boundaries
>> limitations
>> properly. If possible, test with several DMA-enabled
>> devices working
>> simultaneously. Thanks.
>>
>> Patch: http://people.freebsd.org/~gonzo/busdma.diff
>>
>>    
>
>
>      
>
>  

_______________________________________________
freebsd-mips@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mips
To unsubscribe, send any mail to "freebsd-mips-unsubscribe@..."