summaryrefslogtreecommitdiff
path: root/os/pc
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/pc
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/pc')
-rw-r--r--os/pc/NOTICE10
-rw-r--r--os/pc/apbootstrap.h15
-rw-r--r--os/pc/apbootstrap.s110
-rw-r--r--os/pc/apic.c378
-rw-r--r--os/pc/apm.c151
-rw-r--r--os/pc/apmjump.s98
-rw-r--r--os/pc/archmp.c138
-rw-r--r--os/pc/audio.h15
-rw-r--r--os/pc/cga.c127
-rw-r--r--os/pc/cgamemscr.c203
-rw-r--r--os/pc/crystal.h1118
-rw-r--r--os/pc/dat.h258
-rw-r--r--os/pc/devarch.c940
-rw-r--r--os/pc/devds1620.c368
-rw-r--r--os/pc/devether.c539
-rw-r--r--os/pc/devfloppy.c1082
-rw-r--r--os/pc/devi82365.c1044
-rw-r--r--os/pc/devlm78.c346
-rw-r--r--os/pc/devlpt.c245
-rw-r--r--os/pc/devmouse.c672
-rw-r--r--os/pc/devmpeg.c1063
-rw-r--r--os/pc/devpccard.c1949
-rw-r--r--os/pc/devpnp.c652
-rw-r--r--os/pc/devrtc.c461
-rw-r--r--os/pc/devtv.c1826
-rw-r--r--os/pc/devusb.c951
-rw-r--r--os/pc/devvga.c620
-rw-r--r--os/pc/devzt5512.c308
-rw-r--r--os/pc/dma.c237
-rw-r--r--os/pc/ether2000.c232
-rw-r--r--os/pc/ether2114x.c1830
-rw-r--r--os/pc/ether589.c214
-rw-r--r--os/pc/ether79c960.c523
-rw-r--r--os/pc/ether79c970.c645
-rw-r--r--os/pc/ether8003.c271
-rw-r--r--os/pc/ether8139.c765
-rw-r--r--os/pc/ether82543gc.c1367
-rw-r--r--os/pc/ether82557.c1327
-rw-r--r--os/pc/ether83815.c1119
-rw-r--r--os/pc/ether8390.c812
-rw-r--r--os/pc/ether8390.h74
-rw-r--r--os/pc/etherdp83820.c1246
-rw-r--r--os/pc/etherec2t.c174
-rw-r--r--os/pc/etherelnk3.c2134
-rw-r--r--os/pc/etherga620.c1275
-rw-r--r--os/pc/etherga620fw.h4858
-rw-r--r--os/pc/etherif.h39
-rw-r--r--os/pc/etherigbe.c1989
-rw-r--r--os/pc/etherrhine.c734
-rw-r--r--os/pc/ethersmc.c781
-rw-r--r--os/pc/ethervt6102.c1025
-rw-r--r--os/pc/etherwavelan.c197
-rw-r--r--os/pc/flashif.h82
-rw-r--r--os/pc/flashzpc.c371
-rw-r--r--os/pc/floppy.h183
-rw-r--r--os/pc/fns.h165
-rw-r--r--os/pc/fpi.h61
-rw-r--r--os/pc/fpi387.c742
-rw-r--r--os/pc/fpsave.s9
-rw-r--r--os/pc/i8250.c328
-rw-r--r--os/pc/i8253.c314
-rw-r--r--os/pc/i8259.c199
-rw-r--r--os/pc/io.h371
-rw-r--r--os/pc/kbd.c477
-rw-r--r--os/pc/l.s953
-rw-r--r--os/pc/main.c468
-rw-r--r--os/pc/mem.h144
-rw-r--r--os/pc/memory.c588
-rw-r--r--os/pc/mkfile83
-rw-r--r--os/pc/mmu.c343
-rw-r--r--os/pc/mouse.c84
-rw-r--r--os/pc/mp.c815
-rw-r--r--os/pc/mp.h225
-rw-r--r--os/pc/pc139
-rw-r--r--os/pc/pc4e148
-rw-r--r--os/pc/pcdisk157
-rw-r--r--os/pc/pci.acid252
-rw-r--r--os/pc/pci.c1340
-rw-r--r--os/pc/pcidb.acid2848
-rw-r--r--os/pc/pcmciamodem.c75
-rw-r--r--os/pc/piix4smbus.c213
-rw-r--r--os/pc/pix156
-rw-r--r--os/pc/ps2mouse.c84
-rw-r--r--os/pc/ptclbsum386.s126
-rw-r--r--os/pc/screen.c410
-rw-r--r--os/pc/screen.h173
-rw-r--r--os/pc/sd53c8xx.c2135
-rw-r--r--os/pc/sd53c8xx.i773
-rw-r--r--os/pc/sd53c8xx.n448
-rw-r--r--os/pc/sdata.c2206
-rw-r--r--os/pc/sdmylex.c1249
-rw-r--r--os/pc/sdscsi.c394
-rw-r--r--os/pc/trap.c571
-rw-r--r--os/pc/tv.h15
-rw-r--r--os/pc/uarti8250.c740
-rw-r--r--os/pc/uartisa.c98
-rw-r--r--os/pc/uartpci.c137
-rw-r--r--os/pc/usb.h160
-rw-r--r--os/pc/usbuhci.c1538
-rw-r--r--os/pc/vga.c241
-rw-r--r--os/pc/vga.h75
-rw-r--r--os/pc/vga3dfx.c258
-rw-r--r--os/pc/vgaark2000pv.c190
-rw-r--r--os/pc/vgabt485.c245
-rw-r--r--os/pc/vgaclgd542x.c291
-rw-r--r--os/pc/vgaclgd546x.c277
-rw-r--r--os/pc/vgact65545.c149
-rw-r--r--os/pc/vgacyber938x.c225
-rw-r--r--os/pc/vgaet4000.c270
-rw-r--r--os/pc/vgahiqvideo.c274
-rw-r--r--os/pc/vgai81x.c282
-rw-r--r--os/pc/vgamach64xx.c1250
-rw-r--r--os/pc/vgamga2164w.c289
-rw-r--r--os/pc/vgamga4xx.c603
-rw-r--r--os/pc/vganeomagic.c541
-rw-r--r--os/pc/vganvidia.c373
-rw-r--r--os/pc/vgargb524.c236
-rw-r--r--os/pc/vgas3.c620
-rw-r--r--os/pc/vgasavage.c571
-rw-r--r--os/pc/vgat2r4.c586
-rw-r--r--os/pc/vgatvp3020.c216
-rw-r--r--os/pc/vgatvp3026.c189
-rw-r--r--os/pc/vgavmware.c386
-rw-r--r--os/pc/vgax.c102
-rw-r--r--os/pc/wavelan.c1268
-rw-r--r--os/pc/wavelan.h327
-rw-r--r--os/pc/x86break.c138
-rw-r--r--os/pc/zoran.h907
128 files changed, 0 insertions, 74524 deletions
diff --git a/os/pc/NOTICE b/os/pc/NOTICE
deleted file mode 100644
index 37a147c1..00000000
--- a/os/pc/NOTICE
+++ /dev/null
@@ -1,10 +0,0 @@
-Most of these files are adapted from Plan 9
- Copyright © 2002 Lucent Technologies Inc
- Copyright © 2021 Plan 9 Foundation
-This software was originally authored by employees of Bell Laboratories,
-a unit of Nokia Corporation.
-
-devbench.c, fpi387.c, and flashzpc.c are
- Copyright © 1999-2005 Vita Nuova Holdings Ltd
-
-All of them are covered by the MIT licence (see /NOTICE).
diff --git a/os/pc/apbootstrap.h b/os/pc/apbootstrap.h
deleted file mode 100644
index 61aca70d..00000000
--- a/os/pc/apbootstrap.h
+++ /dev/null
@@ -1,15 +0,0 @@
-uchar apbootstrap[]={
-0xea,0x14,0x10,0x00,0x00,0x90,0x90,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x8c,0xc8,0x8e,0xd8,0x0f,0x01,0x16,0xac,0x10,0x0f,0x20,0xc0,
-0x83,0xc8,0x01,0x0f,0x22,0xc0,0xeb,0x00,0xb8,0x08,0x00,0x8e,0xd8,0x8e,0xc0,0x8e,
-0xe0,0x8e,0xe8,0x8e,0xd0,0x66,0xea,0x3d,0x10,0x00,0x00,0x10,0x00,0x8b,0x0d,0x0c,
-0x10,0x00,0x00,0x8b,0x91,0x00,0x08,0x00,0x00,0x89,0x11,0x0f,0x22,0xd9,0x0f,0x20,
-0xc2,0x81,0xca,0x00,0x00,0x01,0x80,0x81,0xe2,0xf5,0xff,0xff,0x9f,0xb8,0x67,0x10,
-0x00,0x80,0x0f,0x22,0xc2,0xff,0xe0,0x89,0xc8,0x0d,0x00,0x00,0x00,0x80,0xc7,0x00,
-0x00,0x00,0x00,0x00,0x0f,0x22,0xd9,0xbc,0xfc,0x5f,0x00,0x80,0x31,0xc0,0x50,0x9d,
-0x8b,0x05,0x10,0x10,0x00,0x80,0x89,0x04,0x24,0x8b,0x05,0x08,0x10,0x00,0x80,0xff,
-0xd0,0xf4,0xeb,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,
-0x00,0x92,0xcf,0x00,0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00,0x17,0x00,0x94,0x10,
-0x00,0x00,
-
-};
diff --git a/os/pc/apbootstrap.s b/os/pc/apbootstrap.s
deleted file mode 100644
index 3887d71d..00000000
--- a/os/pc/apbootstrap.s
+++ /dev/null
@@ -1,110 +0,0 @@
-#include "mem.h"
-
-#define NOP BYTE $0x90 /* NOP */
-#define LGDT(gdtptr) BYTE $0x0F; /* LGDT */ \
- BYTE $0x01; BYTE $0x16; \
- WORD $gdtptr
-#define FARJUMP16(s, o) BYTE $0xEA; /* far jump to ptr16:16 */ \
- WORD $o; WORD $s; \
- NOP; NOP; NOP
-#define FARJUMP32(s, o) BYTE $0x66; /* far jump to ptr32:16 */ \
- BYTE $0xEA; LONG $o; WORD $s
-
-#define DELAY BYTE $0xEB; /* JMP .+2 */ \
- BYTE $0x00
-#define INVD BYTE $0x0F; BYTE $0x08
-#define WBINVD BYTE $0x0F; BYTE $0x09
-
-/*
- * Macros for calculating offsets within the page directory base
- * and page tables. Note that these are assembler-specific hence
- * the '<<2'.
- */
-#define PDO(a) (((((a))>>22) & 0x03FF)<<2)
-#define PTO(a) (((((a))>>12) & 0x03FF)<<2)
-
-/*
- * Start an Application Processor. This must be placed on a 4KB boundary
- * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
- * due to some shortcuts below it's restricted further to within the 1st
- * 64KB. The AP starts in real-mode, with
- * CS selector set to the startup memory address/16;
- * CS base set to startup memory address;
- * CS limit set to 64KB;
- * CPL and IP set to 0.
- */
-TEXT apbootstrap(SB), $0
- FARJUMP16(0, _apbootstrap(SB))
-TEXT _apvector(SB), $0 /* address APBOOTSTRAP+0x08 */
- LONG $0
-TEXT _appdb(SB), $0 /* address APBOOTSTRAP+0x0C */
- LONG $0
-TEXT _apapic(SB), $0 /* address APBOOTSTRAP+0x10 */
- LONG $0
-TEXT _apbootstrap(SB), $0 /* address APBOOTSTRAP+0x14 */
- MOVW CS, AX
- MOVW AX, DS /* initialise DS */
-
- LGDT(gdtptr(SB)) /* load a basic gdt */
-
- MOVL CR0, AX
- ORL $1, AX
- MOVL AX, CR0 /* turn on protected mode */
- DELAY /* JMP .+2 */
-
- BYTE $0xB8; WORD $SELECTOR(1, SELGDT, 0)/* MOVW $SELECTOR(1, SELGDT, 0), AX */
- MOVW AX, DS
- MOVW AX, ES
- MOVW AX, FS
- MOVW AX, GS
- MOVW AX, SS
-
- FARJUMP32(SELECTOR(2, SELGDT, 0), _ap32-KZERO(SB))
-
-/*
- * For Pentiums and higher, the code that enables paging must come from
- * pages that are identity mapped.
- * To this end double map KZERO at virtual 0 and undo the mapping once virtual
- * nirvana has been obtained.
- */
-TEXT _ap32(SB), $0
- MOVL _appdb-KZERO(SB), CX /* physical address of PDB */
- MOVL (PDO(KZERO))(CX), DX /* double-map KZERO at 0 */
- MOVL DX, (PDO(0))(CX)
- MOVL CX, CR3 /* load and flush the mmu */
-
- MOVL CR0, DX
- ORL $0x80010000, DX /* PG|WP */
- ANDL $~0x6000000A, DX /* ~(CD|NW|TS|MP) */
-
- MOVL $_appg(SB), AX
- MOVL DX, CR0 /* turn on paging */
- JMP* AX
-
-TEXT _appg(SB), $0
- MOVL CX, AX /* physical address of PDB */
- ORL $KZERO, AX
- MOVL $0, (PDO(0))(AX) /* undo double-map of KZERO at 0 */
- MOVL CX, CR3 /* load and flush the mmu */
-
- MOVL $(MACHADDR+MACHSIZE-4), SP
-
- MOVL $0, AX
- PUSHL AX
- POPFL
-
- MOVL _apapic(SB), AX
- MOVL AX, (SP)
- MOVL _apvector(SB), AX
- CALL* AX
-_aphalt:
- HLT
- JMP _aphalt
-
-TEXT gdt(SB), $0
- LONG $0x0000; LONG $0
- LONG $0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
- LONG $0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-TEXT gdtptr(SB), $0
- WORD $(3*8-1)
- LONG $gdt-KZERO(SB)
diff --git a/os/pc/apic.c b/os/pc/apic.c
deleted file mode 100644
index ffb24584..00000000
--- a/os/pc/apic.c
+++ /dev/null
@@ -1,378 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "mp.h"
-
-enum { /* Local APIC registers */
- LapicID = 0x0020, /* ID */
- LapicVER = 0x0030, /* Version */
- LapicTPR = 0x0080, /* Task Priority */
- LapicAPR = 0x0090, /* Arbitration Priority */
- LapicPPR = 0x00A0, /* Processor Priority */
- LapicEOI = 0x00B0, /* EOI */
- LapicLDR = 0x00D0, /* Logical Destination */
- LapicDFR = 0x00E0, /* Destination Format */
- LapicSVR = 0x00F0, /* Spurious Interrupt Vector */
- LapicISR = 0x0100, /* Interrupt Status (8 registers) */
- LapicTMR = 0x0180, /* Trigger Mode (8 registers) */
- LapicIRR = 0x0200, /* Interrupt Request (8 registers) */
- LapicESR = 0x0280, /* Error Status */
- LapicICRLO = 0x0300, /* Interrupt Command */
- LapicICRHI = 0x0310, /* Interrupt Command [63:32] */
- LapicTIMER = 0x0320, /* Local Vector Table 0 (TIMER) */
- LapicPCINT = 0x0340, /* Performance COunter LVT */
- LapicLINT0 = 0x0350, /* Local Vector Table 1 (LINT0) */
- LapicLINT1 = 0x0360, /* Local Vector Table 2 (LINT1) */
- LapicERROR = 0x0370, /* Local Vector Table 3 (ERROR) */
- LapicTICR = 0x0380, /* Timer Initial Count */
- LapicTCCR = 0x0390, /* Timer Current Count */
- LapicTDCR = 0x03E0, /* Timer Divide Configuration */
-};
-
-enum { /* LapicSVR */
- LapicENABLE = 0x00000100, /* Unit Enable */
- LapicFOCUS = 0x00000200, /* Focus Processor Checking Disable */
-};
-
-enum { /* LapicICRLO */
- /* [14] IPI Trigger Mode Level (RW) */
- LapicDEASSERT = 0x00000000, /* Deassert level-sensitive interrupt */
- LapicASSERT = 0x00004000, /* Assert level-sensitive interrupt */
-
- /* [17:16] Remote Read Status */
- LapicINVALID = 0x00000000, /* Invalid */
- LapicWAIT = 0x00010000, /* In-Progress */
- LapicVALID = 0x00020000, /* Valid */
-
- /* [19:18] Destination Shorthand */
- LapicFIELD = 0x00000000, /* No shorthand */
- LapicSELF = 0x00040000, /* Self is single destination */
- LapicALLINC = 0x00080000, /* All including self */
- LapicALLEXC = 0x000C0000, /* All Excluding self */
-};
-
-enum { /* LapicESR */
- LapicSENDCS = 0x00000001, /* Send CS Error */
- LapicRCVCS = 0x00000002, /* Receive CS Error */
- LapicSENDACCEPT = 0x00000004, /* Send Accept Error */
- LapicRCVACCEPT = 0x00000008, /* Receive Accept Error */
- LapicSENDVECTOR = 0x00000020, /* Send Illegal Vector */
- LapicRCVVECTOR = 0x00000040, /* Receive Illegal Vector */
- LapicREGISTER = 0x00000080, /* Illegal Register Address */
-};
-
-enum { /* LapicTIMER */
- /* [17] Timer Mode (RW) */
- LapicONESHOT = 0x00000000, /* One-shot */
- LapicPERIODIC = 0x00020000, /* Periodic */
-
- /* [19:18] Timer Base (RW) */
- LapicCLKIN = 0x00000000, /* use CLKIN as input */
- LapicTMBASE = 0x00040000, /* use TMBASE */
- LapicDIVIDER = 0x00080000, /* use output of the divider */
-};
-
-enum { /* LapicTDCR */
- LapicX2 = 0x00000000, /* divide by 2 */
- LapicX4 = 0x00000001, /* divide by 4 */
- LapicX8 = 0x00000002, /* divide by 8 */
- LapicX16 = 0x00000003, /* divide by 16 */
- LapicX32 = 0x00000008, /* divide by 32 */
- LapicX64 = 0x00000009, /* divide by 64 */
- LapicX128 = 0x0000000A, /* divide by 128 */
- LapicX1 = 0x0000000B, /* divide by 1 */
-};
-
-static ulong* lapicbase;
-
-struct
-{
- uvlong hz;
- ulong max;
- ulong min;
- ulong div;
-} lapictimer;
-
-static int
-lapicr(int r)
-{
- return *(lapicbase+(r/sizeof(*lapicbase)));
-}
-
-static void
-lapicw(int r, int data)
-{
- *(lapicbase+(r/sizeof(*lapicbase))) = data;
- data = *(lapicbase+(LapicID/sizeof(*lapicbase)));
- USED(data);
-}
-
-void
-lapiconline(void)
-{
- /*
- * Reload the timer to de-synchronise the processors,
- * then lower the task priority to allow interrupts to be
- * accepted by the APIC.
- */
- microdelay((TK2MS(1)*1000/conf.nmach) * m->machno);
- lapicw(LapicTICR, lapictimer.max);
- lapicw(LapicTIMER, LapicCLKIN|LapicPERIODIC|(VectorPIC+IrqTIMER));
-
- lapicw(LapicTPR, 0);
-}
-
-/*
- * use the i8253 clock to figure out our lapic timer rate.
- */
-static void
-lapictimerinit(void)
-{
- uvlong x, v, hz;
-
- v = m->cpuhz/1000;
- lapicw(LapicTDCR, LapicX1);
- lapicw(LapicTIMER, ApicIMASK|LapicCLKIN|LapicONESHOT|(VectorPIC+IrqTIMER));
-
- if(lapictimer.hz == 0ULL){
- x = fastticks(&hz);
- x += hz/10;
- lapicw(LapicTICR, 0xffffffff);
- do{
- v = fastticks(nil);
- }while(v < x);
-
- lapictimer.hz = (0xffffffffUL-lapicr(LapicTCCR))*10;
- lapictimer.max = lapictimer.hz/HZ;
- lapictimer.min = lapictimer.hz/(100*HZ);
-
- if(lapictimer.hz > hz)
- panic("lapic clock faster than cpu clock");
- lapictimer.div = hz/lapictimer.hz;
- }
-}
-
-void
-lapicinit(Apic* apic)
-{
- ulong r, lvt;
-
- if(lapicbase == 0)
- lapicbase = apic->addr;
-
- lapicw(LapicDFR, 0xFFFFFFFF);
- r = (lapicr(LapicID)>>24) & 0xFF;
- lapicw(LapicLDR, (1<<r)<<24);
- lapicw(LapicTPR, 0xFF);
- lapicw(LapicSVR, LapicENABLE|(VectorPIC+IrqSPURIOUS));
-
- lapictimerinit();
-
- /*
- * Some Pentium revisions have a bug whereby spurious
- * interrupts are generated in the through-local mode.
- */
- switch(m->cpuidax & 0xFFF){
- case 0x526: /* stepping cB1 */
- case 0x52B: /* stepping E0 */
- case 0x52C: /* stepping cC0 */
- wrmsr(0x0E, 1<<14); /* TR12 */
- break;
- }
-
- /*
- * Set the local interrupts. It's likely these should just be
- * masked off for SMP mode as some Pentium Pros have problems if
- * LINT[01] are set to ExtINT.
- * Acknowledge any outstanding interrupts.
- lapicw(LapicLINT0, apic->lintr[0]);
- lapicw(LapicLINT1, apic->lintr[1]);
- */
- lapiceoi(0);
-
- lvt = (lapicr(LapicVER)>>16) & 0xFF;
- if(lvt >= 4)
- lapicw(LapicPCINT, ApicIMASK);
- lapicw(LapicERROR, VectorPIC+IrqERROR);
- lapicw(LapicESR, 0);
- lapicr(LapicESR);
-
- /*
- * Issue an INIT Level De-Assert to synchronise arbitration ID's.
- */
- lapicw(LapicICRHI, 0);
- lapicw(LapicICRLO, LapicALLINC|ApicLEVEL|LapicDEASSERT|ApicINIT);
- while(lapicr(LapicICRLO) & ApicDELIVS)
- ;
-
- /*
- * Do not allow acceptance of interrupts until all initialisation
- * for this processor is done. For the bootstrap processor this can be
- * early duing initialisation. For the application processors this should
- * be after the bootstrap processor has lowered priority and is accepting
- * interrupts.
- lapicw(LapicTPR, 0);
- */
-}
-
-void
-lapicstartap(Apic* apic, int v)
-{
- int crhi, i;
-
- crhi = apic->apicno<<24;
- lapicw(LapicICRHI, crhi);
- lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicASSERT|ApicINIT);
- microdelay(200);
- lapicw(LapicICRLO, LapicFIELD|ApicLEVEL|LapicDEASSERT|ApicINIT);
- delay(10);
-
- for(i = 0; i < 2; i++){
- lapicw(LapicICRHI, crhi);
- lapicw(LapicICRLO, LapicFIELD|ApicEDGE|ApicSTARTUP|(v/BY2PG));
- microdelay(200);
- }
-}
-
-void
-lapicerror(Ureg*, void*)
-{
- int esr;
-
- lapicw(LapicESR, 0);
- esr = lapicr(LapicESR);
- switch(m->cpuidax & 0xFFF){
- case 0x526: /* stepping cB1 */
- case 0x52B: /* stepping E0 */
- case 0x52C: /* stepping cC0 */
- return;
- }
- print("cpu%d: lapicerror: 0x%8.8uX\n", m->machno, esr);
-}
-
-void
-lapicspurious(Ureg*, void*)
-{
- print("cpu%d: lapicspurious\n", m->machno);
-}
-
-int
-lapicisr(int v)
-{
- int isr;
-
- isr = lapicr(LapicISR + (v/32));
-
- return isr & (1<<(v%32));
-}
-
-int
-lapiceoi(int v)
-{
- lapicw(LapicEOI, 0);
-
- return v;
-}
-
-void
-lapicicrw(int hi, int lo)
-{
- lapicw(LapicICRHI, hi);
- lapicw(LapicICRLO, lo);
-}
-
-void
-ioapicrdtr(Apic* apic, int sel, int* hi, int* lo)
-{
- ulong *iowin;
-
- iowin = apic->addr+(0x10/sizeof(ulong));
- sel = IoapicRDT + 2*sel;
-
- lock(apic);
- *apic->addr = sel+1;
- if(hi)
- *hi = *iowin;
- *apic->addr = sel;
- if(lo)
- *lo = *iowin;
- unlock(apic);
-}
-
-void
-ioapicrdtw(Apic* apic, int sel, int hi, int lo)
-{
- ulong *iowin;
-
- iowin = apic->addr+(0x10/sizeof(ulong));
- sel = IoapicRDT + 2*sel;
-
- lock(apic);
- *apic->addr = sel+1;
- *iowin = hi;
- *apic->addr = sel;
- *iowin = lo;
- unlock(apic);
-}
-
-void
-ioapicinit(Apic* apic, int apicno)
-{
- int hi, lo, v;
- ulong *iowin;
-
- /*
- * Initialise the I/O APIC.
- * The MultiProcessor Specification says it is the responsibility
- * of the O/S to set the APIC id.
- * Make sure interrupts are all masked off for now.
- */
- iowin = apic->addr+(0x10/sizeof(ulong));
- lock(apic);
- *apic->addr = IoapicVER;
- apic->mre = (*iowin>>16) & 0xFF;
-
- *apic->addr = IoapicID;
- *iowin = apicno<<24;
- unlock(apic);
-
- hi = 0;
- lo = ApicIMASK;
- for(v = 0; v <= apic->mre; v++)
- ioapicrdtw(apic, v, hi, lo);
-}
-
-void
-lapictimerset(uvlong next)
-{
- vlong period;
- int x;
-
- x = splhi();
- lock(&m->apictimerlock);
-
- period = lapictimer.max;
- if(next != 0){
- period = next - fastticks(nil);
- period /= lapictimer.div;
-
- if(period < lapictimer.min)
- period = lapictimer.min;
- else if(period > lapictimer.max - lapictimer.min)
- period = lapictimer.max;
- }
- lapicw(LapicTICR, period);
-
- unlock(&m->apictimerlock);
- splx(x);
-}
-
-void
-lapicclock(Ureg *u, void*)
-{
- timerintr(u, 0);
-}
diff --git a/os/pc/apm.c b/os/pc/apm.c
deleted file mode 100644
index 2ea18b4d..00000000
--- a/os/pc/apm.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Interface to Advanced Power Management 1.2 BIOS
- *
- * This is, in many ways, a giant hack, and when things settle down
- * a bit and standardize, hopefully we can write a driver that deals
- * more directly with the hardware and thus might be a bit cleaner.
- *
- * ACPI might be the answer, but at the moment this is simpler
- * and more widespread.
- */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-
-extern int apmfarcall(ushort, ulong, Ureg*); /* apmjump.s */
-
-static int
-getreg(ulong *reg, ISAConf *isa, char *name)
-{
- int i;
- int nl;
-
- nl = strlen(name);
- for(i=0; i<isa->nopt; i++){
- if(cistrncmp(isa->opt[i], name, nl)==0 && isa->opt[i][nl] == '='){
- *reg = strtoul(isa->opt[i]+nl+1, nil, 16);
- return 0;
- }
- }
- return -1;
-}
-
-/*
- * Segment descriptors look like this.
- *
- * d1: [base 31:24] [gran] [is32bit] [0] [unused] [limit 19:16]
- [present] [privlev] [type 3:0] [base 23:16]
- * d0: [base 15:00] [limit 15:00]
- *
- * gran is 0 for 1-byte granularity, 1 for 4k granularity
- * type is 0 for system segment, 1 for code/data.
- *
- * clearly we know way too much about the memory unit.
- * however, knowing this much about the memory unit
- * means that the memory unit need not know anything
- * about us.
- *
- * what a crock.
- */
-static void
-setgdt(int sel, ulong base, ulong limit, int flag)
-{
- if(sel < 0 || sel >= NGDT)
- panic("setgdt");
-
- base = (ulong)KADDR(base);
- m->gdt[sel].d0 = (base<<16) | (limit&0xFFFF);
- m->gdt[sel].d1 = (base&0xFF000000) | (limit&0x000F0000) |
- ((base>>16)&0xFF) | SEGP | SEGPL(0) | flag;
-}
-
-static ulong ax, cx, dx, di, ebx, esi;
-static Ureg apmu;
-static long
-apmread(Chan*, void *a, long n, vlong off)
-{
- if(off < 0)
- error("badarg");
-
- if(n+off > sizeof apmu)
- n = sizeof apmu - off;
- if(n <= 0)
- return 0;
- memmove(a, (char*)&apmu+off, n);
- return n;
-}
-
-static long
-apmwrite(Chan*, void *a, long n, vlong off)
-{
- int s;
- if(off || n != sizeof apmu)
- error("write a Ureg");
-
- memmove(&apmu, a, sizeof apmu);
- s = splhi();
- apmfarcall(APMCSEL, ebx, &apmu);
- splx(s);
- return n;
-}
-
-void
-apmlink(void)
-{
- ISAConf isa;
- char *s;
-
- if(isaconfig("apm", 0, &isa) == 0)
- return;
-
- /*
- * APM info passed from boot loader.
- * Now we need to set up the GDT entries for APM.
- *
- * AX = 32-bit code segment base address
- * EBX = 32-bit code segment offset
- * CX = 16-bit code segment base address
- * DX = 32-bit data segment base address
- * ESI = <16-bit code segment length> <32-bit code segment length> (hi then lo)
- * DI = 32-bit data segment length
- */
-
- if(getreg(&ax, &isa, s="ax") < 0
- || getreg(&ebx, &isa, s="ebx") < 0
- || getreg(&cx, &isa, s="cx") < 0
- || getreg(&dx, &isa, s="dx") < 0
- || getreg(&esi, &isa, s="esi") < 0
- || getreg(&di, &isa, s="di") < 0){
- print("apm: missing register %s\n", s);
- return;
- }
-
- /*
- * The NEC Versa SX bios does not report the correct 16-bit code
- * segment length when loaded directly from mbr -> 9load (as compared
- * with going through ld.com). We'll make both code segments 64k-1 bytes.
- */
- esi = 0xFFFFFFFF;
-
- /*
- * We are required by the BIOS to set up three consecutive segments,
- * one for the APM 32-bit code, one for the APM 16-bit code, and
- * one for the APM data. The BIOS handler uses the code segment it
- * get called with to determine the other two segment selector.
- */
- setgdt(APMCSEG, ax<<4, ((esi&0xFFFF)-1)&0xFFFF, SEGEXEC|SEGR|SEGD);
- setgdt(APMCSEG16, cx<<4, ((esi>>16)-1)&0xFFFF, SEGEXEC|SEGR);
- setgdt(APMDSEG, dx<<4, (di-1)&0xFFFF, SEGDATA|SEGW|SEGD);
-
- addarchfile("apm", 0660, apmread, apmwrite);
-
-print("apm0: configured cbase %.8lux off %.8lux\n", ax<<4, ebx);
-
- return;
-}
-
diff --git a/os/pc/apmjump.s b/os/pc/apmjump.s
deleted file mode 100644
index 6dbd19d0..00000000
--- a/os/pc/apmjump.s
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Far call, absolute indirect.
- * The argument is the offset.
- * We use a global structure for the jump params,
- * so this is *not* reentrant or thread safe.
- */
-
-#include "mem.h"
-
-#define SSOVERRIDE BYTE $0x36
-#define CSOVERRIDE BYTE $0x2E
-#define RETF BYTE $0xCB
-
-GLOBL apmjumpstruct+0(SB), $8
-
-TEXT fortytwo(SB), $0
- MOVL $42, AX
- RETF
-
-TEXT getcs(SB), $0
- PUSHL CS
- POPL AX
- RET
-
-TEXT apmfarcall(SB), $0
- /*
- * We call push and pop ourselves.
- * As soon as we do the first push or pop,
- * we can't use FP anymore.
- */
- MOVL off+4(FP), BX
- MOVL seg+0(FP), CX
- MOVL BX, apmjumpstruct+0(SB)
- MOVL CX, apmjumpstruct+4(SB)
-
- /* load necessary registers from Ureg */
- MOVL ureg+8(FP), DI
- MOVL 28(DI), AX
- MOVL 16(DI), BX
- MOVL 24(DI), CX
- MOVL 20(DI), DX
-
- /* save registers, segments */
- PUSHL DS
- PUSHL ES
- PUSHL FS
- PUSHL GS
- PUSHL BP
- PUSHL DI
-
- /*
- * paranoia: zero the segments, since it's the
- * BIOS's responsibility to initialize them.
- * (trick picked up from Linux driver).
- PUSHL DX
- XORL DX, DX
- PUSHL DX
- POPL DS
- PUSHL DX
- POPL ES
- PUSHL DX
- POPL FS
- PUSHL DX
- POPL GS
- POPL DX
- */
-
- PUSHL $APMDSEG
- POPL DS
-
- /*
- * The actual call.
- */
- CSOVERRIDE; BYTE $0xFF; BYTE $0x1D
- LONG $apmjumpstruct+0(SB)
-
- /* restore segments, registers */
- POPL DI
- POPL BP
- POPL GS
- POPL FS
- POPL ES
- POPL DS
-
- PUSHFL
- POPL 64(DI)
-
- /* store interesting registers back in Ureg */
- MOVL AX, 28(DI)
- MOVL BX, 16(DI)
- MOVL CX, 24(DI)
- MOVL DX, 20(DI)
- MOVL SI, 4(DI)
-
- PUSHFL
- POPL AX
- ANDL $1, AX /* carry flag */
- RET
diff --git a/os/pc/archmp.c b/os/pc/archmp.c
deleted file mode 100644
index fbbda091..00000000
--- a/os/pc/archmp.c
+++ /dev/null
@@ -1,138 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "mp.h"
-
-#define cpuserver 1
-
-_MP_ *_mp_;
-
-static _MP_*
-mpscan(uchar *addr, int len)
-{
- uchar *e, *p, sum;
- int i;
-
- e = addr+len;
- for(p = addr; p < e; p += sizeof(_MP_)){
- if(memcmp(p, "_MP_", 4))
- continue;
- sum = 0;
- for(i = 0; i < sizeof(_MP_); i++)
- sum += p[i];
- if(sum == 0)
- return (_MP_*)p;
- }
- return 0;
-}
-
-static _MP_*
-mpsearch(void)
-{
- uchar *bda;
- ulong p;
- _MP_ *mp;
-
- /*
- * Search for the MP Floating Pointer Structure:
- * 1) in the first KB of the EBDA;
- * 2) in the last KB of system base memory;
- * 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
- */
- bda = KADDR(0x400);
- if((p = (bda[0x0F]<<8)|bda[0x0E])){
- if(mp = mpscan(KADDR(p), 1024))
- return mp;
- }
- else{
- p = ((bda[0x14]<<8)|bda[0x13])*1024;
- if(mp = mpscan(KADDR(p-1024), 1024))
- return mp;
- }
- return mpscan(KADDR(0xF0000), 0x10000);
-}
-
-static int identify(void);
-
-PCArch archmp = {
-.id= "_MP_",
-.ident= identify,
-.reset= mpshutdown,
-.intrinit= mpinit,
-.intrenable= mpintrenable,
-.fastclock= i8253read,
-.timerset= lapictimerset,
-};
-
-static int
-identify(void)
-{
- PCMP *pcmp;
- uchar *p, sum;
- ulong length;
-
- if(getconf("*nomp"))
- return 1;
-
- /*
- * Search for an MP configuration table. For now,
- * don't accept the default configurations (physaddr == 0).
- * Check for correct signature, calculate the checksum and,
- * if correct, check the version.
- * To do: check extended table checksum.
- */
- if((_mp_ = mpsearch()) == 0 || _mp_->physaddr == 0)
- return 1;
-
- pcmp = KADDR(_mp_->physaddr);
- if(memcmp(pcmp, "PCMP", 4))
- return 1;
-
- length = pcmp->length;
- sum = 0;
- for(p = (uchar*)pcmp; length; length--)
- sum += *p++;
-
- if(sum || (pcmp->version != 1 && pcmp->version != 4))
- return 1;
-
- if(cpuserver && m->havetsc)
- archmp.fastclock = tscticks;
- return 0;
-}
-
-Lock mpsynclock;
-
-void
-syncclock(void)
-{
- uvlong x;
-
- if(arch->fastclock != tscticks)
- return;
-
- if(m->machno == 0){
- wrmsr(0x10, 0);
- m->tscticks = 0;
- } else {
- x = MACHP(0)->tscticks;
- while(x == MACHP(0)->tscticks)
- ;
- wrmsr(0x10, MACHP(0)->tscticks);
- cycles(&m->tscticks);
- }
-}
-
-uvlong
-tscticks(uvlong *hz)
-{
- if(hz != nil)
- *hz = m->cpuhz;
-
- cycles(&m->tscticks); /* Uses the rdtsc instruction */
- return m->tscticks;
-}
diff --git a/os/pc/audio.h b/os/pc/audio.h
deleted file mode 100644
index d06c7bcc..00000000
--- a/os/pc/audio.h
+++ /dev/null
@@ -1,15 +0,0 @@
-enum
-{
- Bufsize = 1024, /* 5.8 ms each, must be power of two */
- Nbuf = 128, /* .74 seconds total */
- Dma = 6,
- IrqAUDIO = 7,
- SBswab = 0,
-};
-
-#define seteisadma(a, b) dmainit(a, Bufsize);
-#define CACHELINESZ 8
-#define UNCACHED(type, v) (type*)((ulong)(v))
-
-#define Int0vec
-#define setvec(v, f, a) intrenable(v, f, a, BUSUNKNOWN, "audio")
diff --git a/os/pc/cga.c b/os/pc/cga.c
deleted file mode 100644
index 6365d44c..00000000
--- a/os/pc/cga.c
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-enum {
- Black,
- Blue,
- Green,
- Cyan,
- Red,
- Magenta,
- Brown,
- Grey,
-
- Bright = 0x08,
- Blinking = 0x80,
-
- Yellow = Bright|Brown,
- White = Bright|Grey,
-};
-
-enum {
- Width = 80*2,
- Height = 25,
-
- Attr = (Black<<4)|Grey, /* high nibble background
- * low foreground
- */
-};
-
-#define CGASCREENBASE ((uchar*)KADDR(0xB8000))
-
-static int cgapos;
-static Lock cgascreenlock;
-
-static uchar
-cgaregr(int index)
-{
- outb(0x3D4, index);
- return inb(0x3D4+1) & 0xFF;
-}
-
-static void
-cgaregw(int index, int data)
-{
- outb(0x3D4, index);
- outb(0x3D4+1, data);
-}
-
-static void
-movecursor(void)
-{
- cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
- cgaregw(0x0F, cgapos/2 & 0xFF);
- CGASCREENBASE[cgapos+1] = Attr;
-}
-
-static void
-cgascreenputc(int c)
-{
- int i;
- uchar *p;
-
- if(c == '\n'){
- cgapos = cgapos/Width;
- cgapos = (cgapos+1)*Width;
- }
- else if(c == '\t'){
- i = 8 - ((cgapos/2)&7);
- while(i-->0)
- cgascreenputc(' ');
- }
- else if(c == '\b'){
- if(cgapos >= 2)
- cgapos -= 2;
- cgascreenputc(' ');
- cgapos -= 2;
- }
- else{
- CGASCREENBASE[cgapos++] = c;
- CGASCREENBASE[cgapos++] = Attr;
- }
- if(cgapos >= Width*Height){
- memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
- p = &CGASCREENBASE[Width*(Height-1)];
- for(i=0; i<Width/2; i++){
- *p++ = ' ';
- *p++ = Attr;
- }
- cgapos = Width*(Height-1);
- }
- movecursor();
-}
-
-static void
-cgascreenputs(char* s, int n)
-{
- if(!islo()){
- /*
- * Don't deadlock trying to
- * print in an interrupt.
- */
- if(!canlock(&cgascreenlock))
- return;
- }
- else
- lock(&cgascreenlock);
-
- while(n-- > 0)
- cgascreenputc(*s++);
-
- unlock(&cgascreenlock);
-}
-
-void
-screeninit(void)
-{
-
- cgapos = cgaregr(0x0E)<<8;
- cgapos |= cgaregr(0x0F);
- cgapos *= 2;
-
- screenputs = cgascreenputs;
-}
diff --git a/os/pc/cgamemscr.c b/os/pc/cgamemscr.c
deleted file mode 100644
index 7509614a..00000000
--- a/os/pc/cgamemscr.c
+++ /dev/null
@@ -1,203 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#include <draw.h>
-#include <memdraw.h>
-#include <memlayer.h>
-
-enum {
- Width = 160,
- Height = 25,
-
- Attr = 7, /* white on black */
-};
-
-#define CGASCREENBASE ((uchar*)KADDR(0xB8000))
-
-static int cgapos;
-static int screeninitdone;
-static Lock cgascreenlock;
-void (*vgascreenputc)(char*);
-
-static uchar
-cgaregr(int index)
-{
- outb(0x3D4, index);
- return inb(0x3D4+1) & 0xFF;
-}
-
-static void
-cgaregw(int index, int data)
-{
- outb(0x3D4, index);
- outb(0x3D4+1, data);
-}
-
-static void
-movecursor(void)
-{
- cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
- cgaregw(0x0F, cgapos/2 & 0xFF);
- CGASCREENBASE[cgapos+1] = Attr;
-}
-
-static void
-cgascreenputc(int c)
-{
- int i;
-
- if(c == '\n'){
- cgapos = cgapos/Width;
- cgapos = (cgapos+1)*Width;
- }
- else if(c == '\t'){
- i = 8 - ((cgapos/2)&7);
- while(i-->0)
- cgascreenputc(' ');
- }
- else if(c == '\b'){
- if(cgapos >= 2)
- cgapos -= 2;
- cgascreenputc(' ');
- cgapos -= 2;
- }
- else{
- CGASCREENBASE[cgapos++] = c;
- CGASCREENBASE[cgapos++] = Attr;
- }
- if(cgapos >= Width*Height){
- memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
- memset(&CGASCREENBASE[Width*(Height-1)], 0, Width);
- cgapos = Width*(Height-1);
- }
- movecursor();
-}
-
-void
-screeninit(void)
-{
- memimageinit();
- cgapos = cgaregr(0x0E)<<8;
- cgapos |= cgaregr(0x0F);
- cgapos *= 2;
- screeninitdone = 1;
-}
-
-void
-cgascreenputs(char* s, int n)
-{
- int i;
- Rune r;
- char buf[4];
-
- if(!islo()){
- if(!canlock(&cgascreenlock))
- return;
- }
- else
- lock(&cgascreenlock);
-
- if(vgascreenputc == nil){
- while(n-- > 0)
- cgascreenputc(*s++);
- unlock(&cgascreenlock);
- return;
- }
-
- while(n > 0) {
- i = chartorune(&r, s);
- if(i == 0){
- s++;
- --n;
- continue;
- }
- memmove(buf, s, i);
- buf[i] = 0;
- n -= i;
- s += i;
- vgascreenputc(buf);
- }
-
- unlock(&cgascreenlock);
-}
-
-void
-cursorenable(void)
-{
-}
-
-void
-cursordisable(void)
-{
-}
-
-typedef struct Drawcursor Drawcursor;
-
-
-
-void
-cursorupdate(Rectangle r)
-{
- USED(r);
-}
-
-void
-drawcursor(Drawcursor *c)
-{
- USED(c);
-}
-
-uchar*
-attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen)
-{
- static Rectangle screenr = {0, 0, 0, 0};
- static uchar *bdata;
- if (bdata == nil)
- if ((bdata = malloc(1)) == nil)
- return nil;
- *r = screenr;
- *chan = RGB24;
- *d = chantodepth(RGB24);
- *width = 0;
- *softscreen = 0;
- return bdata;
-}
-
-void
-flushmemscreen(Rectangle r)
-{
- USED(r);
-}
-
-void
-blankscreen(int i)
-{
- USED(i);
-}
-
-void
-getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
-{
- USED(p);
- USED(pr);
- USED(pg);
- USED(pb);
-
-}
-
-int
-setcolor(ulong p, ulong r, ulong g, ulong b)
-{
- USED(p);
- USED(r);
- USED(g);
- USED(b);
- return ~0;
-}
-
-void (*screenputs)(char*, int) = cgascreenputs;
diff --git a/os/pc/crystal.h b/os/pc/crystal.h
deleted file mode 100644
index 63152c8f..00000000
--- a/os/pc/crystal.h
+++ /dev/null
@@ -1,1118 +0,0 @@
-/*
- * Micro code for the crystal musicam decoder on the Boffin MPEG decoder
- */
-static
-uchar crystal[] =
-{
- 0x10,0x10,0x06,0x00,0x00,0x00,0x00,0x00,0x03,0xa0,0x00,0x1a,0x9f,0x00,0x39,0x5f,
- 0x00,0xfe,0x9f,0x02,0x84,0x1f,0x03,0x35,0xbf,0x12,0x4e,0x1f,0x24,0xa3,0xc0,0xed,
- 0xb1,0xe1,0x03,0x35,0xbf,0xfd,0x7b,0xe1,0x00,0xfe,0x9f,0xff,0xc6,0xa1,0x00,0x1a,
- 0x9f,0xff,0xfc,0x60,0xff,0xff,0xe0,0x00,0x03,0x40,0x00,0x19,0xff,0x00,0x32,0x1f,
- 0x01,0x01,0xe0,0x02,0x56,0x7f,0x03,0x7b,0xbf,0x11,0x66,0xff,0x24,0x9d,0xff,0xec,
- 0xcb,0x00,0x02,0xe8,0xdf,0xfd,0x4e,0x61,0x00,0xf9,0xff,0xff,0xbf,0x20,0x00,0x1b,
- 0x3f,0xff,0xfc,0x21,0xff,0xff,0xe0,0x00,0x03,0x00,0x00,0x19,0x3f,0x00,0x2b,0x60,
- 0x01,0x03,0xff,0x02,0x29,0x20,0x03,0xba,0xff,0x10,0x7f,0xdf,0x24,0x8c,0xff,0xeb,
- 0xe5,0x01,0x02,0x95,0x00,0xfd,0x21,0x20,0x00,0xf3,0xff,0xff,0xb7,0x61,0x00,0x1b,
- 0xbf,0xff,0xfb,0xa0,0xff,0xff,0xe0,0x00,0x02,0xa0,0x00,0x18,0x80,0x00,0x24,0xc0,
- 0x01,0x04,0xe0,0x01,0xfb,0xe0,0x03,0xf3,0x7f,0x0f,0x99,0x5f,0x24,0x70,0xc0,0xeb,
- 0x00,0x41,0x02,0x3a,0x20,0xfc,0xf4,0x61,0x00,0xec,0xa0,0xff,0xaf,0x60,0x00,0x1c,
- 0x20,0xff,0xfb,0x40,0xff,0xff,0xe0,0x00,0x02,0x60,0x00,0x17,0xc0,0x00,0x1e,0x80,
- 0x01,0x04,0x9f,0x01,0xcf,0x1f,0x04,0x25,0x80,0x0e,0xb3,0xff,0x24,0x49,0x20,0xea,
- 0x1d,0x60,0x01,0xd7,0xff,0xfc,0xc8,0x61,0x00,0xe3,0xc0,0xff,0xa7,0x21,0x00,0x1c,
- 0x5f,0xff,0xfa,0xe1,0xff,0xff,0xe0,0x00,0x02,0x1f,0x00,0x16,0xdf,0x00,0x18,0x9f,
- 0x01,0x03,0x5f,0x01,0xa2,0xdf,0x04,0x50,0xff,0x0d,0xd0,0x20,0x24,0x16,0x7f,0xe9,
- 0x3c,0xe0,0x01,0x6e,0xe0,0xfc,0x9d,0x21,0x00,0xd9,0x5f,0xff,0x9e,0xa0,0x00,0x1c,
- 0x80,0xff,0xfa,0x60,0xff,0xff,0xe0,0x00,0x02,0x00,0x00,0x16,0x00,0x00,0x13,0x20,
- 0x01,0x01,0x1f,0x01,0x77,0x7f,0x04,0x76,0x5f,0x0c,0xee,0x40,0x23,0xd8,0xdf,0xe8,
- 0x5f,0x40,0x00,0xfe,0x9f,0xfc,0x73,0x21,0x00,0xcd,0x7f,0xff,0x96,0x01,0x00,0x1c,
- 0x80,0xff,0xf9,0xe0,0xff,0xff,0xc0,0x00,0x01,0xbf,0x00,0x15,0x1f,0x00,0x0d,0xe0,
- 0x00,0xfd,0xff,0x01,0x4c,0xdf,0x04,0x95,0xa0,0x0c,0x0e,0xbf,0x23,0x90,0x5f,0xe7,
- 0x84,0xe1,0x00,0x87,0x40,0xfc,0x4a,0x60,0x00,0xbf,0xdf,0xff,0x8d,0x21,0x00,0x1c,
- 0x5f,0xff,0xf9,0x60,0xff,0xff,0xc0,0x00,0x01,0x9f,0x00,0x14,0x1f,0x00,0x09,0x00,
- 0x00,0xfa,0x20,0x01,0x23,0x40,0x04,0xaf,0x00,0x0b,0x32,0x1f,0x23,0x3d,0x20,0xe6,
- 0xae,0x61,0x00,0x08,0xbf,0xfc,0x23,0x41,0x00,0xb0,0xc0,0xff,0x84,0x20,0x00,0x1c,
- 0x00,0xff,0xf8,0xc0,0xff,0xff,0xc0,0x00,0x01,0x60,0x00,0x13,0x40,0x00,0x04,0x7f,
- 0x00,0xf5,0x3f,0x00,0xfa,0xc0,0x04,0xc2,0xbf,0x0a,0x58,0x9f,0x22,0xdf,0x80,0xe5,
- 0xdc,0x40,0xff,0x83,0x41,0xfb,0xfd,0xe1,0x00,0xa0,0x00,0xff,0x7b,0x00,0x00,0x1b,
- 0x9f,0xff,0xf8,0x20,0xff,0xff,0xc0,0x00,0x01,0x40,0x00,0x12,0x60,0x00,0x00,0x40,
- 0x00,0xef,0xdf,0x00,0xd3,0x7f,0x04,0xd0,0xe0,0x09,0x82,0xbf,0x22,0x77,0xc0,0xe5,
- 0x0e,0xc0,0xfe,0xf6,0xc1,0xfb,0xda,0xa0,0x00,0x8d,0x5f,0xff,0x71,0xe1,0x00,0x1a,
- 0xe0,0xff,0xf7,0x80,0xff,0xff,0xa1,0x00,0x01,0x1f,0x00,0x11,0x60,0xff,0xfc,0x60,
- 0x00,0xe9,0xc0,0x00,0xad,0x7f,0x04,0xd9,0xdf,0x08,0xb0,0xe0,0x22,0x05,0xdf,0xe4,
- 0x46,0xc1,0xfe,0x63,0x80,0xfb,0xb9,0xa1,0x00,0x79,0x3f,0xff,0x68,0xc0,0x00,0x19,
- 0xff,0xff,0xf6,0xe0,0xff,0xff,0xa1,0x00,0x00,0xff,0x00,0x10,0x7f,0xff,0xf8,0xe0,
- 0x00,0xe3,0x20,0x00,0x88,0xdf,0x04,0xdd,0xc0,0x07,0xe3,0x5f,0x21,0x8a,0x7f,0xe3,
- 0x84,0x61,0xfd,0xc9,0x60,0xfb,0x9b,0x40,0x00,0x63,0x40,0xff,0x5f,0xa1,0x00,0x19,
- 0x00,0xff,0xf6,0x21,0xff,0xff,0x81,0x00,0x00,0xe0,0x00,0x0f,0xa0,0xff,0xf5,0xa1,
- 0x00,0xdb,0xe0,0x00,0x65,0xbf,0x04,0xdc,0xdf,0x07,0x1a,0x7f,0x21,0x05,0xa0,0xe2,
- 0xc8,0x40,0xfd,0x28,0xc0,0xfb,0x7f,0xa1,0x00,0x4b,0x9f,0xff,0x56,0x80,0x00,0x17,
- 0x9f,0xff,0xf5,0x61,0xff,0xff,0x81,0x00,0x00,0xe0,0x00,0x0e,0x9f,0xff,0xf2,0xc0,
- 0x00,0xd4,0x40,0x00,0x44,0x1f,0x04,0xd7,0x7f,0x06,0x56,0x7f,0x20,0x77,0xc0,0xe2,
- 0x12,0xe0,0xfc,0x81,0xc0,0xfb,0x67,0x00,0x00,0x32,0x3f,0xff,0x4d,0x80,0x00,0x16,
- 0x20,0xff,0xf4,0xa0,0xff,0xff,0x60,0x00,0x00,0xc0,0x00,0x0d,0xe0,0xff,0xf0,0x21,
- 0x00,0xcc,0x3f,0x00,0x23,0xff,0x04,0xcd,0xc0,0x05,0x97,0xe0,0x1f,0xe1,0x40,0xe1,
- 0x64,0x80,0xfb,0xd4,0x80,0xfb,0x51,0xe1,0x00,0x17,0x20,0xff,0x44,0xc1,0x00,0x14,
- 0x60,0xff,0xf3,0xe0,0xff,0xff,0x60,0x00,0x00,0xa0,0x00,0x0c,0xff,0xff,0xed,0xc1,
- 0x00,0xc3,0xdf,0x00,0x05,0xa0,0x04,0xbf,0xdf,0x04,0xde,0xe0,0x1f,0x42,0x60,0xe0,
- 0xbd,0xa0,0xfb,0x21,0x20,0xfb,0x40,0x21,0xff,0xfa,0x60,0xff,0x3c,0x21,0x00,0x12,
- 0x3f,0xff,0xf3,0x01,0xff,0xff,0x40,0x00,0x00,0xa0,0x00,0x0c,0x20,0xff,0xeb,0xa0,
- 0x00,0xbb,0x3f,0xff,0xe8,0xe0,0x04,0xae,0x1f,0x04,0x2b,0x80,0x1e,0x9b,0x80,0xe0,
- 0x1e,0xc0,0xfa,0x68,0x20,0xfb,0x32,0x40,0xff,0xdc,0x01,0xff,0x33,0xc1,0x00,0x0f,
- 0xdf,0xff,0xf2,0x20,0xff,0xff,0x20,0x00,0x00,0x7f,0x00,0x0b,0x60,0xff,0xe9,0xe0,
- 0x00,0xb2,0x80,0xff,0xcd,0xc1,0x04,0x99,0x00,0x03,0x7e,0x40,0x1d,0xed,0x20,0xdf,
- 0x88,0x40,0xf9,0xa9,0x81,0xfb,0x28,0x81,0xff,0xbb,0xe1,0xff,0x2b,0xc0,0x00,0x0d,
- 0x40,0xff,0xf1,0x61,0xff,0xff,0x20,0x00,0x00,0x7f,0x00,0x0a,0x9f,0xff,0xe8,0x61,
- 0x00,0xa9,0x80,0xff,0xb4,0x61,0x04,0x80,0x5f,0x02,0xd7,0x40,0x1d,0x37,0xc0,0xde,
- 0xfa,0x60,0xf8,0xe5,0x81,0xfb,0x23,0x21,0xff,0x9a,0x41,0xff,0x24,0x20,0x00,0x0a,
- 0x5f,0xff,0xf0,0x60,0xff,0xff,0x01,0x00,0x00,0x5f,0x00,0x09,0xdf,0xff,0xe7,0x00,
- 0x00,0xa0,0x5f,0xff,0x9c,0xc0,0x04,0x64,0xc0,0x02,0x36,0xa0,0x1c,0x7b,0x9f,0xde,
- 0x75,0x81,0xf8,0x1c,0xa1,0xfb,0x22,0x40,0xff,0x77,0x21,0xff,0x1c,0xe0,0x00,0x07,
- 0x20,0xff,0xef,0x81,0xff,0xfe,0xe1,0x00,0x00,0x5f,0x00,0x09,0x20,0xff,0xe6,0x01,
- 0x00,0x97,0x40,0xff,0x86,0xc1,0x04,0x46,0x5f,0x01,0x9c,0x80,0x1b,0xb9,0x3f,0xdd,
- 0xfa,0x21,0xf7,0x4f,0x20,0xfb,0x26,0x21,0xff,0x52,0x81,0xff,0x16,0x40,0x00,0x03,
- 0xa0,0xff,0xee,0xa0,0xff,0xfe,0xc0,0x00,0x00,0x40,0x00,0x08,0x80,0xff,0xe5,0x20,
- 0x00,0x8e,0x1f,0xff,0x72,0xa1,0x04,0x25,0x60,0x01,0x09,0x3f,0x1a,0xf1,0x40,0xdd,
- 0x88,0x40,0xf6,0x7d,0x41,0xfb,0x2f,0x20,0xff,0x2c,0x81,0xff,0x10,0x21,0xff,0xff,
- 0xc0,0xff,0xed,0xa0,0xff,0xfe,0xa0,0x00,0x00,0x40,0x00,0x07,0xe0,0xff,0xe4,0x61,
- 0x00,0x85,0x00,0xff,0x60,0x00,0x04,0x02,0x1f,0x00,0x7c,0xbf,0x1a,0x23,0xc0,0xdd,
- 0x20,0x80,0xf5,0xa7,0x61,0xfb,0x3d,0x41,0xff,0x05,0x40,0xff,0x0a,0xc1,0xff,0xfb,
- 0x81,0xff,0xec,0xc0,0xff,0xfe,0x61,0x00,0x00,0x40,0x00,0x07,0x40,0xff,0xe4,0x00,
- 0x00,0x7b,0xe0,0xff,0x4f,0x40,0x03,0xdc,0xbf,0xff,0xf7,0x41,0x19,0x51,0x9f,0xdc,
- 0xc2,0xe0,0xf4,0xcd,0xe1,0xfb,0x51,0x00,0xfe,0xdc,0xc0,0xff,0x05,0xe0,0xff,0xf7,
- 0x00,0xff,0xeb,0xe1,0xff,0xfe,0x41,0x00,0x00,0x40,0x00,0x06,0xa0,0xff,0xe3,0xa1,
- 0x00,0x72,0xdf,0xff,0x40,0x21,0x03,0xb5,0xa0,0xff,0x78,0xc0,0x18,0x7b,0x1f,0xdc,
- 0x6f,0xa1,0xf3,0xf1,0x41,0xfb,0x6a,0x60,0xfe,0xb3,0x21,0xff,0x02,0x01,0xff,0xf2,
- 0x20,0xff,0xea,0xe1,0xff,0xfe,0x00,0x00,0x00,0x20,0x00,0x06,0x20,0xff,0xe3,0x80,
- 0x00,0x69,0xff,0xff,0x32,0x81,0x03,0x8c,0xdf,0xff,0x01,0x61,0x17,0xa0,0xc0,0xdc,
- 0x27,0x21,0xf3,0x11,0xc0,0xfb,0x89,0xa1,0xfe,0x88,0x81,0xfe,0xfe,0xe1,0xff,0xec,
- 0xe0,0xff,0xea,0x00,0xff,0xfd,0xe1,0x00,0x00,0x20,0x00,0x05,0xa0,0xff,0xe3,0x80,
- 0x00,0x61,0x60,0xff,0x26,0xa1,0x03,0x62,0xdf,0xfe,0x91,0x20,0x16,0xc3,0x20,0xdb,
- 0xe9,0x81,0xf2,0x2f,0xe0,0xfb,0xaf,0x01,0xfe,0x5d,0x21,0xfe,0xfc,0xa1,0xff,0xe7,
- 0x61,0xff,0xe9,0x21,0xff,0xfd,0xa0,0x00,0x00,0x20,0x00,0x05,0x1f,0xff,0xe3,0xa1,
- 0x00,0x58,0xdf,0xff,0x1c,0x40,0x03,0x37,0x9f,0xfe,0x28,0x01,0x15,0xe2,0xa0,0xdb,
- 0xb6,0xe0,0xf1,0x4c,0x01,0xfb,0xda,0x80,0xfe,0x30,0xe1,0xfe,0xfb,0x61,0xff,0xe1,
- 0x80,0xff,0xe8,0x40,0xff,0xfd,0x60,0x00,0x00,0x20,0x00,0x04,0xc0,0xff,0xe3,0xe0,
- 0x00,0x50,0xa0,0xff,0x13,0x60,0x03,0x0b,0x9f,0xfd,0xc5,0xe0,0x14,0xff,0xbf,0xdb,
- 0x8f,0x40,0xf0,0x66,0xa1,0xfc,0x0c,0x81,0xfe,0x04,0x20,0xfe,0xfb,0x20,0xff,0xdb,
- 0x40,0xff,0xe7,0x80,0xff,0xfd,0x00,0x00,0x00,0x20,0x00,0x04,0x60,0xff,0xe4,0x41,
- 0x00,0x48,0x9f,0xff,0x0c,0x01,0x02,0xde,0xe0,0xfd,0x6b,0x00,0x14,0x1a,0xff,0xdb,
- 0x73,0x01,0xef,0x80,0x21,0xfc,0x45,0x01,0xfd,0xd6,0xe0,0xfe,0xfc,0x01,0xff,0xd4,
- 0xa0,0xff,0xe6,0xc1,0xff,0xfc,0xc0,0x00,0x00,0x20,0x00,0x03,0xdf,0xff,0xe4,0xc1,
- 0x00,0x40,0xe0,0xff,0x06,0x01,0x02,0xb1,0x9f,0xfd,0x17,0x21,0x13,0x35,0x00,0xdb,
- 0x62,0x01,0xee,0x99,0x01,0xfc,0x84,0x41,0xfd,0xa9,0x81,0xfe,0xfe,0x20,0xff,0xcd,
- 0xe1,0xff,0xe6,0x01,0x12,0x28,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,
- 0x04,0x00,0x00,0x05,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x08,0x00,0x00,0x09,
- 0x00,0x00,0x0a,0x00,0x00,0x0b,0x00,0x00,0x0c,0x00,0x00,0x0d,0x00,0x00,0x0e,0x00,
- 0x00,0x0f,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,
- 0x03,0x00,0x00,0x04,0x00,0x00,0x05,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x08,
- 0x00,0x00,0x09,0x00,0x00,0x0a,0x00,0x00,0x0b,0x00,0x00,0x0c,0x00,0x00,0x0d,0x00,
- 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x03,0x00,0x00,
- 0x04,0x00,0x00,0x05,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x10,
- 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x00,0x00,0x04,0x00,0x00,0x05,0x00,
- 0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x08,0x00,0x00,0x09,0x00,0x00,0x0a,0x00,0x00,
- 0x0b,0x00,0x00,0x0c,0x00,0x00,0x0d,0x00,0x00,0x0e,0x00,0x00,0x0f,0x00,0x00,0x00,
- 0x00,0x00,0x01,0x00,0x00,0x03,0x00,0x00,0x04,0x00,0x00,0x05,0x00,0x00,0x06,0x00,
- 0x00,0x07,0x12,0x66,0x00,0xbd,0x40,0x00,0x00,0x32,0xcb,0xfd,0x28,0x51,0x45,0x20,
- 0x00,0x00,0x19,0x65,0xfe,0x14,0x28,0xa2,0x10,0x00,0x00,0x0c,0xb2,0xff,0x0a,0x14,
- 0x51,0x08,0x00,0x00,0x06,0x59,0x7f,0x05,0x0a,0x28,0x04,0x00,0x00,0x03,0x2c,0xbf,
- 0x02,0x85,0x14,0x02,0x00,0x00,0x01,0x96,0x5f,0x01,0x42,0x8a,0x01,0x00,0x00,0x00,
- 0xcb,0x2f,0x00,0xa1,0x45,0x00,0x80,0x00,0x00,0x65,0x97,0x00,0x50,0xa2,0x00,0x40,
- 0x00,0x00,0x32,0xcb,0x00,0x28,0x51,0x00,0x20,0x00,0x00,0x19,0x65,0x00,0x14,0x28,
- 0x00,0x10,0x00,0x00,0x0c,0xb2,0x00,0x0a,0x14,0x00,0x08,0x00,0x00,0x06,0x59,0x00,
- 0x05,0x0a,0x00,0x04,0x00,0x00,0x03,0x2c,0x00,0x02,0x85,0x00,0x02,0x00,0x00,0x01,
- 0x96,0x00,0x01,0x42,0x00,0x01,0x00,0x00,0x00,0xcb,0x00,0x00,0xa1,0x00,0x00,0x80,
- 0x00,0x00,0x65,0x00,0x00,0x50,0x00,0x00,0x40,0x00,0x00,0x32,0x00,0x00,0x28,0x00,
- 0x00,0x1f,0x00,0x00,0x19,0x00,0x00,0x14,0x00,0x00,0x0f,0x00,0x00,0x0c,0x00,0x00,
- 0x0a,0x00,0x00,0x08,0x00,0x00,0x06,0x00,0x00,0x05,0x00,0x00,0x03,0x00,0x00,0x03,
- 0x00,0x00,0x02,0x12,0x10,0x00,0x48,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x04,
- 0x00,0x00,0x08,0x00,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x00,0x80,0x00,
- 0x01,0x00,0x00,0x02,0x00,0x00,0x04,0x00,0x00,0x08,0x00,0x00,0x10,0x00,0x00,0x20,
- 0x00,0x00,0x40,0x00,0x00,0x80,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x04,0x00,0x00,
- 0x08,0x00,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x00,0x80,0x00,0x00,0x12,
- 0xa5,0x00,0x33,0xff,0xff,0xfb,0xff,0xff,0xf9,0x00,0x00,0x03,0xff,0xff,0xf6,0x00,
- 0x00,0x04,0x00,0x00,0x05,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x08,0x00,0x00,
- 0x09,0x00,0x00,0x0a,0x00,0x00,0x0b,0x00,0x00,0x0c,0x00,0x00,0x0d,0x00,0x00,0x0e,
- 0x00,0x00,0x0f,0x00,0x00,0x10,0x12,0xb6,0x00,0x7e,0x00,0x00,0x04,0x00,0x00,0x04,
- 0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,
- 0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x03,0x00,0x00,
- 0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,
- 0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,
- 0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,
- 0x02,0x00,0x00,0x02,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x03,0x00,0x00,0x03,
- 0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,
- 0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x12,0xe0,0x00,0x0c,0x00,0x00,0x19,0x00,
- 0x00,0x1c,0x00,0x00,0x06,0x00,0x00,0x0a,0x12,0xe4,0x00,0x0c,0x00,0x00,0x03,0x00,
- 0x00,0x07,0x00,0x00,0x0b,0x00,0x00,0x0f,0x12,0xe8,0x00,0x0c,0x00,0x02,0xb6,0x00,
- 0x02,0xb6,0x00,0x02,0xd4,0x00,0x02,0xd4,0x12,0xec,0x00,0x0c,0x00,0x02,0x28,0x00,
- 0x02,0x28,0x00,0x02,0x50,0x00,0x02,0x50,0x12,0xf0,0x00,0x33,0x00,0x00,0x03,0x00,
- 0x00,0x05,0x00,0x00,0x07,0x00,0x00,0x09,0x00,0x00,0x0f,0x00,0x00,0x1f,0x00,0x00,
- 0x3f,0x00,0x00,0x7f,0x00,0x00,0xff,0x00,0x01,0xff,0x00,0x03,0xff,0x00,0x07,0xff,
- 0x00,0x0f,0xff,0x00,0x1f,0xff,0x00,0x3f,0xff,0x00,0x7f,0xff,0x00,0xff,0xff,0x13,
- 0x01,0x00,0x2a,0x00,0x01,0x40,0x00,0x01,0xe0,0x00,0x02,0x30,0x00,0x02,0x80,0x00,
- 0x03,0x20,0x00,0x03,0xc0,0x00,0x04,0x60,0x00,0x05,0x00,0x00,0x06,0x40,0x00,0x07,
- 0x80,0x00,0x08,0xc0,0x00,0x0a,0x00,0x00,0x0c,0x80,0x00,0x0f,0x00,0x13,0x0f,0x00,
- 0x09,0x00,0x01,0xb9,0x00,0x01,0xe0,0x00,0x01,0x40,0x13,0x12,0x00,0x0c,0x00,0x00,
- 0x58,0x00,0x00,0x5e,0x00,0x00,0x1a,0x00,0x00,0x26,0x13,0x16,0x00,0x6f,0x16,0xa0,
- 0x9e,0xe9,0x5f,0x62,0x1d,0x90,0x6b,0xe2,0x6f,0x95,0x0c,0x3e,0xf1,0xf3,0xc1,0x0f,
- 0x1f,0x62,0x97,0xe0,0x9d,0x69,0x1a,0x9b,0x66,0x11,0xc7,0x3b,0xee,0x38,0xc5,0x06,
- 0x3e,0x2e,0x1f,0xd8,0x8d,0x1e,0x9f,0x41,0x1c,0x38,0xb2,0x18,0xbc,0x80,0x14,0x4c,
- 0xf3,0x0f,0x15,0xae,0x09,0x4a,0x03,0x03,0x22,0xf4,0x01,0x91,0xf6,0x17,0xb5,0xdf,
- 0x0d,0xae,0x88,0x1e,0x21,0x21,0x07,0xc6,0x7e,0x1b,0x72,0x83,0x13,0x0f,0xf7,0x1f,
- 0xa7,0x55,0x1f,0xf6,0x21,0x15,0x7d,0x69,0x1c,0xed,0x7a,0x0a,0xc7,0xcd,0x1f,0x0a,
- 0x7e,0x10,0x73,0x87,0x19,0xb3,0xe0,0x04,0xb2,0x04,0x00,0x00,0x00,0x1d,0x40,0x05,
- 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x1f,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x01,0x5f,0x00,0x00,0x01,0x00,0x00,0x03,0x00,
- 0x00,0x07,0x00,0x00,0x0f,0x00,0x00,0x1f,0x00,0x00,0x3f,0x00,0x00,0x7f,0x00,0x00,
- 0xff,0x00,0x01,0xff,0x00,0x03,0xff,0x00,0x07,0xff,0x00,0x0f,0xff,0x00,0x1f,0xff,
- 0x00,0x3f,0xff,0x00,0x7f,0xff,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
- 0x00,0x10,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,
- 0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,
- 0x00,0x0d,0x40,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x05,0xc0,0x00,0x05,0xc0,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
- 0x02,0x00,0x00,0x00,0x00,0x05,0xe0,0x00,0x05,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0xc0,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x06,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x04,0x80,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x04,0xa0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x60,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xe0,0x00,0x60,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x05,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x40,0x00,0x60,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x60,0x00,0x60,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x07,0xc0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x05,0xc0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xe0,0x00,0x30,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x05,0x40,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x05,0x80,0x00,0x66,0x2a,0xaa,0xaa,0x33,0x33,0x33,0x24,0x92,0x49,0x38,0xe3,0x8e,
- 0x22,0x22,0x22,0x21,0x08,0x42,0x20,0x82,0x08,0x20,0x40,0x81,0x20,0x20,0x20,0x20,
- 0x10,0x08,0x20,0x08,0x02,0x20,0x04,0x00,0x20,0x02,0x00,0x20,0x01,0x00,0x20,0x00,
- 0x80,0x20,0x00,0x40,0x20,0x00,0x20,0x10,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,
- 0x10,0x00,0x00,0x04,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x80,0x00,0x00,
- 0x40,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x02,
- 0x00,0x00,0x00,0xff,0x00,0x00,0x80,0x00,0x00,0x40,0x04,0x78,0x00,0x18,0x01,0xe8,
- 0x0d,0x03,0x6c,0x16,0x02,0x40,0x0a,0x00,0x10,0x03,0xa8,0x00,0x00,0x00,0xcc,0x00,
- 0x30,0x00,0x00,0x00,0x00,0x02,0x10,0x00,0x00,0x1b,0xcf,0x83,0x40,0x00,0x00,0x00,
- 0xc7,0x8b,0x17,0x70,0x41,0xc1,0xc7,0x8c,0x26,0xc7,0x8c,0x26,0xc7,0x8b,0x36,0xc7,
- 0x8b,0xf2,0xc7,0x8c,0x52,0x13,0x40,0x1b,0xea,0x97,0x80,0xc0,0x00,0x04,0x00,0x97,
- 0x80,0xc8,0x00,0x04,0x00,0x70,0x78,0xcf,0x70,0x7b,0xcd,0x0f,0xd7,0xc2,0x00,0x00,
- 0x01,0xc9,0x83,0x46,0x70,0x02,0xec,0x97,0x80,0xdc,0x00,0x00,0x05,0x97,0x80,0xe0,
- 0x00,0x07,0xbf,0xd7,0x02,0x8f,0x70,0x7f,0xd7,0x70,0x7c,0xc7,0x70,0x7d,0xcb,0x70,
- 0x7e,0xd5,0x97,0x80,0x4c,0x00,0x06,0x00,0x97,0x80,0x4d,0x00,0x0d,0x40,0x70,0x50,
- 0x51,0x70,0x10,0x52,0x70,0x10,0x55,0x70,0x5a,0x5b,0x70,0x5a,0x5c,0x70,0x4e,0x62,
- 0x70,0x10,0x3e,0x0f,0xcd,0xcd,0xff,0xdf,0xff,0x0f,0x4b,0x4b,0xff,0xff,0xf7,0x70,
- 0x10,0x46,0xd5,0x03,0x3a,0x70,0x10,0xc2,0xd4,0x40,0x00,0xd1,0x80,0x00,0xd5,0x80,
- 0x00,0x70,0x10,0xd4,0xc7,0x8a,0x47,0x70,0x00,0x1e,0x70,0x10,0x1b,0xc7,0x89,0xb0,
- 0x23,0x10,0xc2,0xc9,0x83,0x70,0xcf,0x83,0x5a,0x27,0x1b,0x1b,0x00,0x00,0x01,0x37,
- 0x1b,0xc2,0x00,0x00,0x0c,0xc9,0x83,0x6c,0x70,0x10,0x34,0xc7,0x89,0xb0,0x0b,0x00,
- 0x20,0xc9,0x03,0x6a,0xc7,0x89,0xb0,0x0b,0x00,0xc2,0xc9,0x03,0x6a,0xc7,0x89,0xb0,
- 0x0b,0x00,0xc2,0xc9,0x83,0x7c,0x97,0x80,0x21,0x00,0x00,0x02,0x70,0x00,0x1e,0xc7,
- 0x89,0xb0,0x0b,0x00,0x22,0x70,0x12,0x1e,0xc7,0x89,0xb0,0x0b,0x0f,0x61,0x47,0x61,
- 0x23,0x00,0x10,0x00,0x70,0x24,0x6b,0x47,0x61,0xc2,0x00,0x40,0x00,0x0b,0x01,0x24,
- 0x47,0x61,0xc2,0x00,0x80,0x00,0x0b,0x00,0x25,0x47,0x61,0xc2,0x01,0x00,0x00,0x0b,
- 0x00,0x26,0x47,0x61,0xc2,0x04,0x00,0x00,0x0b,0x01,0x27,0x47,0x61,0xc2,0x10,0x00,
- 0x00,0x0b,0x01,0x28,0x47,0x61,0xc2,0x20,0x00,0x00,0x0b,0x00,0x29,0x47,0x61,0xc2,
- 0x40,0x00,0x00,0x0b,0x00,0x2a,0x0f,0x61,0x2b,0x00,0x00,0x03,0x27,0x24,0xc2,0x00,
- 0x03,0x0f,0xd1,0x40,0x00,0x90,0x00,0x1f,0x4f,0x1f,0x1f,0x00,0x10,0x00,0x27,0x23,
- 0xc2,0x00,0x03,0x00,0xd1,0x40,0x00,0x90,0x00,0x30,0x4f,0x30,0x30,0x00,0x00,0x90,
- 0x40,0x10,0xc2,0x70,0x30,0xc2,0xd6,0x00,0x17,0x7b,0x1f,0xc2,0x58,0x10,0x3d,0x47,
- 0x3d,0x3d,0x00,0x20,0x00,0x4f,0x3d,0x3d,0x00,0x00,0x08,0x4f,0x25,0x25,0x00,0x00,
- 0x08,0x70,0x25,0xc2,0x23,0x3d,0x3d,0x37,0x3d,0x3e,0x00,0x00,0x20,0xca,0x03,0x6a,
- 0x27,0x3e,0xc2,0x00,0x35,0xe0,0xca,0x83,0x6a,0x27,0x23,0xc2,0x00,0x00,0x00,0xc9,
- 0x03,0xeb,0x37,0x27,0xc2,0x00,0x00,0x03,0xc9,0x03,0xcc,0x37,0x23,0x1f,0x00,0x00,
- 0x06,0x37,0x1f,0xc2,0x00,0x00,0x00,0xcb,0x83,0xd9,0xcf,0x83,0xd1,0x37,0x23,0x1f,
- 0x00,0x00,0x02,0x37,0x1f,0xc2,0x00,0x00,0x00,0xcb,0x83,0xd9,0x37,0x24,0xc2,0x00,
- 0x00,0x02,0xc9,0x03,0xd7,0x97,0x80,0x2d,0x00,0x00,0x02,0xcf,0x83,0xef,0x70,0x01,
- 0x2d,0xcf,0x83,0xef,0x37,0x27,0xc2,0x00,0x00,0x03,0xc9,0x03,0xe3,0x37,0x23,0x1f,
- 0x00,0x00,0x0a,0xcb,0x83,0xee,0x37,0x24,0xc2,0x00,0x00,0x01,0xc9,0x03,0xee,0xcf,
- 0x83,0xe9,0x37,0x23,0xc2,0x00,0x00,0x06,0xcb,0x83,0xee,0x37,0x24,0xc2,0x00,0x00,
- 0x01,0xc9,0x03,0xee,0x70,0x00,0x2d,0xcf,0x83,0xef,0x37,0x24,0xc2,0x00,0x00,0x01,
- 0xc9,0x83,0xe9,0x70,0x10,0x2d,0x27,0x22,0xc2,0x00,0x00,0x00,0xc9,0x83,0xf5,0x70,
- 0x12,0x1e,0xc7,0x89,0xb0,0x0b,0x0f,0x2c,0x27,0x62,0x62,0x00,0x00,0x00,0xc9,0x03,
- 0xfb,0x27,0x62,0x62,0xff,0xff,0xff,0xcb,0x83,0x66,0x37,0x27,0xc2,0x00,0x00,0x03,
- 0xc9,0x84,0x01,0x70,0x00,0x2e,0x70,0x00,0x2f,0xcf,0x84,0x0a,0x97,0x80,0x2e,0x00,
- 0x00,0x02,0x37,0x27,0xc2,0x00,0x00,0x01,0xc9,0x84,0x08,0x70,0x01,0x2f,0xcf,0x84,
- 0x0a,0x97,0x80,0x2f,0x00,0x00,0x02,0x70,0x1d,0x37,0x70,0x3e,0x38,0x70,0x1c,0x39,
- 0x70,0x5b,0x5c,0x27,0x2d,0xc2,0x00,0x03,0x12,0xd1,0x40,0x00,0x90,0x00,0x5d,0x37,
- 0x27,0xc2,0x00,0x00,0x03,0xc9,0x04,0x17,0x4f,0x5d,0x5d,0x00,0x00,0x02,0x70,0x2e,
- 0x32,0x27,0x2d,0xc2,0x00,0x02,0xe8,0xd1,0x40,0x00,0x90,0x00,0x30,0x97,0x80,0xd8,
- 0x00,0x04,0x80,0x27,0x28,0xc2,0x00,0x02,0xe4,0xd5,0x40,0x00,0x94,0x00,0x31,0x94,
- 0x00,0xc2,0xd6,0x40,0x00,0xc7,0x89,0x85,0x70,0x2f,0x32,0x27,0x2d,0xc2,0x00,0x02,
- 0xe0,0xd1,0x40,0x00,0x30,0x31,0xc2,0xd6,0x40,0x00,0xc7,0x89,0x85,0x70,0x2e,0x32,
- 0x97,0x80,0xf0,0x00,0x04,0x80,0x97,0x80,0xd8,0x00,0x04,0xa0,0x97,0x80,0x1e,0x00,
- 0x00,0x02,0x27,0x28,0xc2,0x00,0x02,0xe4,0xd5,0x40,0x00,0x94,0x00,0x31,0x94,0x00,
- 0xc2,0xd6,0x40,0x00,0xc7,0x89,0x61,0x70,0x2f,0x32,0x27,0x2d,0xc2,0x00,0x02,0xe0,
- 0xd1,0x40,0x00,0x30,0x31,0xc2,0xd6,0x40,0x00,0xc7,0x89,0x61,0x27,0x64,0xc2,0x00,
- 0x00,0x00,0xc9,0x84,0x6d,0x27,0x22,0xc2,0x00,0x00,0x00,0xc9,0x84,0x6d,0x70,0x37,
- 0x1d,0x70,0x38,0x3e,0x70,0x39,0x1c,0x97,0x80,0x63,0x00,0xff,0xff,0x0f,0x61,0xc2,
- 0x00,0xff,0x00,0xc7,0x8a,0x19,0x4f,0x61,0x5f,0x00,0x01,0x00,0x0f,0x5f,0xc2,0x00,
- 0xff,0x00,0xc7,0x8a,0x19,0x70,0x11,0x1e,0x27,0x5d,0x5d,0xff,0xff,0xf8,0xca,0x84,
- 0x5a,0xc7,0x8a,0x15,0xcf,0x84,0x55,0x70,0x00,0x1e,0x27,0x5d,0xc2,0x00,0x00,0x08,
- 0xc9,0x04,0x61,0x23,0x14,0xc2,0xd6,0x40,0x00,0xc7,0x8a,0x3a,0x0f,0x63,0x63,0x00,
- 0xff,0xff,0x70,0x2c,0xc2,0x33,0x63,0xc2,0xc9,0x04,0x6d,0x0f,0x4b,0x4b,0xff,0xff,
- 0xf7,0x17,0x4b,0x4b,0x00,0x00,0x07,0x27,0x59,0x59,0x00,0x00,0x01,0xcf,0x83,0x66,
- 0x70,0x5c,0x5b,0x70,0x24,0xc2,0x33,0x6b,0xc2,0xc9,0x83,0x5a,0x27,0x24,0xc2,0x00,
- 0x04,0x74,0xcf,0xc0,0x00,0xcf,0x84,0x78,0xcf,0x84,0x7c,0xcf,0x84,0x80,0xcf,0x83,
- 0x5a,0x70,0x79,0xcf,0x0f,0xcd,0xcd,0xff,0xfb,0xff,0xcf,0x84,0x83,0x70,0x78,0xcf,
- 0x0f,0xcd,0xcd,0xff,0xfb,0xff,0xcf,0x84,0x83,0x70,0x7a,0xcf,0x17,0xcd,0xcd,0x00,
- 0x04,0x00,0x0f,0xcd,0xc2,0x00,0x20,0x00,0xc9,0x84,0x8d,0x27,0x57,0xc2,0x00,0x00,
- 0x00,0xc9,0x84,0x8d,0x0f,0x4b,0x4b,0xff,0xff,0xfb,0x17,0x4b,0x4b,0x00,0x00,0x0b,
- 0x70,0x2e,0x32,0x97,0x80,0xf0,0x00,0x04,0x80,0x97,0x80,0xd8,0x00,0x04,0xa0,0x97,
- 0x80,0xe8,0x00,0x07,0xc0,0x97,0x80,0x1e,0x00,0x00,0x06,0x27,0x28,0xc2,0x00,0x02,
- 0xe4,0xd5,0x40,0x00,0x94,0x00,0x31,0x94,0x00,0xc2,0xd6,0x40,0x00,0xc7,0x89,0x06,
- 0x70,0x2f,0x32,0x27,0x2d,0xc2,0x00,0x02,0xe0,0xd1,0x40,0x00,0x30,0x31,0xc2,0xd6,
- 0x40,0x00,0xc7,0x89,0x06,0x70,0x2e,0x32,0x70,0x10,0x1b,0x97,0x80,0xf0,0x00,0x04,
- 0x80,0x27,0x28,0xc2,0x00,0x02,0xe4,0xd5,0x40,0x00,0x94,0x00,0x31,0x94,0x00,0xc2,
- 0xd6,0x40,0x00,0xc7,0x88,0xba,0x70,0x2f,0x32,0x27,0x2d,0xc2,0x00,0x02,0xe0,0xd1,
- 0x40,0x00,0x30,0x31,0xc2,0xd6,0x40,0x00,0xc7,0x88,0xba,0x70,0x2e,0x32,0x70,0x10,
- 0x1b,0x97,0x80,0xf0,0x00,0x04,0x80,0x27,0x28,0xc2,0x00,0x02,0xe4,0xd5,0x40,0x00,
- 0x94,0x00,0x31,0x94,0x00,0xc2,0xd6,0x40,0x00,0xc7,0x86,0xbd,0x70,0x2f,0x32,0x27,
- 0x2d,0xc2,0x00,0x02,0xe0,0xd1,0x40,0x00,0x30,0x31,0xc2,0x90,0x00,0x31,0xd6,0x40,
- 0x00,0xc7,0x86,0xbd,0x37,0x31,0xc2,0x00,0x00,0x1d,0xd6,0x40,0x00,0xc7,0x88,0x74,
- 0x97,0x80,0x1f,0x00,0x00,0x06,0x37,0x27,0xc2,0x00,0x00,0x03,0xc9,0x84,0xd5,0x97,
- 0x80,0x30,0x00,0x00,0x02,0xcf,0x84,0xd6,0x70,0x00,0x30,0x27,0x1f,0xc2,0x00,0x04,
- 0xd9,0xcf,0xc0,0x00,0xcf,0x85,0x18,0xcf,0x85,0x13,0xcf,0x85,0x01,0xcf,0x84,0xfc,
- 0xcf,0x84,0xea,0xcf,0x84,0xe5,0xcf,0x84,0xe0,0x97,0x80,0x37,0x00,0x04,0xc0,0x97,
- 0x80,0x1a,0x00,0x00,0x00,0xcf,0x85,0x34,0x97,0x80,0x37,0x00,0x05,0x20,0x97,0x80,
- 0x1a,0x00,0x02,0x00,0xcf,0x85,0x34,0x22,0x14,0x16,0x0f,0x16,0x16,0x00,0x00,0x0f,
- 0x27,0x17,0x17,0x00,0x00,0x01,0x27,0x19,0x19,0x00,0x00,0x01,0x0f,0x19,0x19,0x00,
- 0x00,0x0f,0x97,0x80,0x37,0x00,0x04,0xe0,0x97,0x80,0x1a,0x00,0x00,0x00,0x27,0x4f,
- 0x4f,0x00,0x00,0x00,0xc9,0x05,0x34,0x70,0x10,0x4f,0xcf,0x85,0x34,0x97,0x80,0x37,
- 0x00,0x05,0x40,0x97,0x80,0x1a,0x00,0x02,0x00,0xcf,0x85,0x34,0x22,0x14,0x16,0x0f,
- 0x16,0x16,0x00,0x00,0x0f,0x27,0x17,0x17,0x00,0x00,0x01,0x27,0x19,0x19,0x00,0x00,
- 0x01,0x0f,0x19,0x19,0x00,0x00,0x0f,0x97,0x80,0x37,0x00,0x05,0x00,0x97,0x80,0x1a,
- 0x00,0x00,0x00,0x27,0x4f,0x4f,0x00,0x00,0x00,0xc9,0x05,0x34,0x70,0x10,0x4f,0xcf,
- 0x85,0x34,0x97,0x80,0x37,0x00,0x05,0x60,0x97,0x80,0x1a,0x00,0x02,0x00,0xcf,0x85,
- 0x34,0x22,0x14,0x16,0x0f,0x16,0x16,0x00,0x00,0x0f,0x27,0x17,0x17,0x00,0x00,0x01,
- 0x27,0x19,0x19,0x00,0x00,0x01,0x0f,0x19,0x19,0x00,0x00,0x0f,0x27,0x4f,0x4f,0x00,
- 0x00,0x00,0xc9,0x05,0x25,0x70,0x10,0x4f,0x97,0x80,0xf0,0x00,0x04,0xc0,0x97,0x80,
- 0xd0,0x00,0x05,0x20,0xd5,0x03,0x3a,0xd1,0x80,0x00,0xd6,0x00,0x02,0xc7,0x8a,0x9f,
- 0xd1,0x80,0x04,0x27,0x34,0x34,0x00,0x00,0x01,0x37,0x34,0xc2,0x00,0x00,0x0c,0xc9,
- 0x84,0xb6,0xcf,0x83,0x66,0x70,0x37,0xf0,0x27,0x37,0xd8,0x00,0x00,0x1f,0xd6,0x00,
- 0x07,0xc7,0x8c,0x5a,0x70,0x37,0xf0,0x27,0x37,0xd8,0x00,0x00,0x0f,0xd6,0x00,0x03,
- 0xc7,0x8c,0x5a,0x27,0x37,0xf0,0x00,0x00,0x1b,0x27,0x37,0xd8,0x00,0x00,0x14,0xd1,
- 0x03,0x16,0xd5,0x03,0x16,0xc7,0x8c,0x61,0xc7,0x8c,0x61,0xc7,0x8c,0x61,0xc7,0x8c,
- 0x61,0x70,0x37,0xf0,0x27,0x37,0xd8,0x00,0x00,0x07,0xd6,0x00,0x01,0xc7,0x8c,0x5a,
- 0x27,0x37,0xf0,0x00,0x00,0x0d,0x27,0x37,0xd8,0x00,0x00,0x0a,0xd6,0x00,0x01,0xc7,
- 0x8c,0x61,0x27,0x37,0xf0,0x00,0x00,0x10,0x27,0x37,0xd8,0x00,0x00,0x17,0xd6,0x00,
- 0x01,0xc7,0x8c,0x5a,0x27,0x37,0xf0,0x00,0x00,0x1c,0x27,0x37,0xd8,0x00,0x00,0x1b,
- 0xd6,0x00,0x01,0xc7,0x8c,0x5a,0x70,0x37,0xf0,0x27,0x37,0xd8,0x00,0x00,0x03,0xc7,
- 0x8c,0x5a,0x27,0x37,0xf0,0x00,0x00,0x06,0x27,0x37,0xd8,0x00,0x00,0x05,0xc7,0x8c,
- 0x61,0x27,0x37,0xf0,0x00,0x00,0x08,0x27,0x37,0xd8,0x00,0x00,0x0b,0xc7,0x8c,0x5a,
- 0x27,0x37,0xf0,0x00,0x00,0x0e,0x27,0x37,0xd8,0x00,0x00,0x0d,0xc7,0x8c,0x5a,0x27,
- 0x37,0xf0,0x00,0x00,0x1d,0x27,0x37,0xd8,0x00,0x00,0x12,0xd1,0x03,0x1a,0xd5,0x03,
- 0x18,0xd6,0x00,0x01,0xc7,0x8c,0x61,0xd1,0x03,0x19,0xd5,0x03,0x1a,0xd6,0x00,0x01,
- 0xc7,0x8c,0x61,0x70,0x37,0xf0,0x27,0x37,0xd8,0x00,0x00,0x01,0xd1,0x03,0x16,0xd5,
- 0x03,0x16,0xc7,0x8c,0x61,0x27,0x37,0xf0,0x00,0x00,0x03,0x27,0x37,0xd8,0x00,0x00,
- 0x02,0xd1,0x03,0x1a,0xd5,0x03,0x18,0xc7,0x8c,0x6e,0x27,0x37,0xf0,0x00,0x00,0x04,
- 0x27,0x37,0xd8,0x00,0x00,0x07,0xc7,0x8c,0x7b,0x27,0x37,0xf0,0x00,0x00,0x0e,0x27,
- 0x37,0xd8,0x00,0x00,0x09,0xd1,0x03,0x1a,0xd5,0x03,0x18,0xc7,0x8c,0x61,0xd1,0x03,
- 0x19,0xd5,0x03,0x1a,0xc7,0x8c,0x61,0x27,0x37,0xf0,0x00,0x00,0x10,0x27,0x37,0xd8,
- 0x00,0x00,0x13,0xc7,0x8c,0x5a,0x27,0x37,0xf0,0x00,0x00,0x16,0x27,0x37,0xd8,0x00,
- 0x00,0x15,0xc7,0x8c,0x5a,0x27,0x37,0xf0,0x00,0x00,0x18,0x27,0x37,0xd8,0x00,0x00,
- 0x1b,0xc7,0x8c,0x5a,0x27,0x37,0xf0,0x00,0x00,0x1e,0x27,0x37,0xd8,0x00,0x00,0x1d,
- 0xc7,0x8c,0x5a,0x27,0x37,0xf0,0x00,0x00,0x07,0x27,0x37,0xd8,0x00,0x00,0x04,0xd1,
- 0x03,0x21,0xd5,0x03,0x1c,0xc7,0x8c,0x6e,0xd1,0x03,0x1e,0xd5,0x03,0x1f,0xc7,0x8c,
- 0x6e,0x27,0x37,0xf0,0x00,0x00,0x08,0x27,0x37,0xd8,0x00,0x00,0x0b,0xc7,0x8c,0x7b,
- 0x27,0x37,0xf0,0x00,0x00,0x0c,0x27,0x37,0xd8,0x00,0x00,0x0f,0xc7,0x8c,0x7b,0x27,
- 0x37,0xf0,0x00,0x00,0x1e,0x27,0x37,0xd8,0x00,0x00,0x11,0xd1,0x03,0x21,0xd5,0x03,
- 0x1c,0xc7,0x8c,0x61,0xd1,0x03,0x1d,0xd5,0x03,0x21,0xc7,0x8c,0x61,0x27,0x37,0xf0,
- 0x00,0x00,0x1a,0x27,0x37,0xd8,0x00,0x00,0x15,0xd1,0x03,0x1e,0xd5,0x03,0x1f,0xc7,
- 0x8c,0x61,0xd1,0x03,0x20,0xd5,0x03,0x1e,0xc7,0x8c,0x61,0x27,0x37,0xf0,0x00,0x00,
- 0x0f,0x27,0x37,0xd8,0x00,0x00,0x08,0xd1,0x03,0x29,0xd5,0x03,0x22,0xc7,0x8c,0x6e,
- 0xd1,0x03,0x25,0xd5,0x03,0x26,0xc7,0x8c,0x6e,0xd1,0x03,0x27,0xd5,0x03,0x24,0xc7,
- 0x8c,0x6e,0xd1,0x03,0x23,0xd5,0x03,0x28,0xc7,0x8c,0x6e,0x27,0x37,0xf0,0x00,0x00,
- 0x10,0x27,0x37,0xd8,0x00,0x00,0x13,0xc7,0x8c,0x7b,0x27,0x37,0xf0,0x00,0x00,0x14,
- 0x27,0x37,0xd8,0x00,0x00,0x17,0xc7,0x8c,0x7b,0x27,0x37,0xf0,0x00,0x00,0x18,0x27,
- 0x37,0xd8,0x00,0x00,0x1b,0xc7,0x8c,0x7b,0x27,0x37,0xf0,0x00,0x00,0x1c,0x27,0x37,
- 0xd8,0x00,0x00,0x1f,0xc7,0x8c,0x7b,0xd1,0x80,0x00,0xd5,0x80,0x00,0x70,0x37,0xf0,
- 0x97,0x80,0xd0,0x00,0x04,0xa0,0x97,0x80,0xd4,0x00,0x00,0x05,0x47,0xb2,0xc2,0x2d,
- 0x41,0x3c,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0x96,0xd6,0x00,0x0e,0x70,0xb2,
- 0x96,0x27,0x37,0xd8,0x00,0x00,0x1f,0xd1,0x03,0x2a,0xd5,0x03,0x32,0xd6,0x00,0x07,
- 0xc7,0x8c,0x82,0xd1,0x03,0x31,0xd5,0x03,0x39,0x97,0x00,0xc2,0x13,0x12,0xc2,0xd7,
- 0x40,0x00,0xd6,0x00,0x07,0xc7,0x8c,0x88,0x97,0x00,0xc2,0x1b,0x12,0xc2,0xd7,0x40,
- 0x00,0x97,0x80,0xd4,0x00,0x00,0x09,0x97,0x80,0xd0,0x00,0x04,0xa0,0x70,0x1a,0xc2,
- 0x23,0x19,0xf0,0xc7,0x8b,0x07,0x0f,0x17,0x17,0x00,0x00,0x01,0xc9,0x86,0x27,0x97,
- 0x80,0xd0,0x00,0x04,0xbf,0xd6,0x00,0x1e,0xc7,0x8b,0x03,0xcf,0x86,0x29,0xd6,0x00,
- 0x1e,0xc7,0x8b,0x07,0x70,0x37,0xe8,0xd1,0x80,0x04,0xd5,0x80,0x01,0x0f,0x17,0x17,
- 0x00,0x00,0x01,0xc9,0x86,0x44,0x27,0x16,0xc2,0x00,0x00,0x00,0xd1,0x40,0x00,0x27,
- 0x1a,0xf0,0x00,0x01,0x20,0xd6,0x00,0x0f,0xc7,0x86,0x5e,0x27,0x16,0xc2,0x00,0x01,
- 0x10,0xd1,0x40,0x00,0x27,0x1a,0xf0,0x00,0x00,0x01,0xc7,0x86,0x99,0x27,0x16,0xc2,
- 0x00,0x01,0x10,0xd1,0x40,0x00,0x27,0x1a,0xf0,0x00,0x00,0x10,0xd6,0x00,0x0e,0xc7,
- 0x86,0x89,0xcf,0x86,0x57,0x27,0x16,0xc2,0x00,0x00,0x00,0xd1,0x40,0x00,0x27,0x1a,
- 0xf0,0x00,0x01,0x00,0xd6,0x00,0x0f,0xc7,0x86,0x74,0x27,0x16,0xc2,0x00,0x01,0x10,
- 0xd1,0x40,0x00,0x70,0x1a,0xf0,0xc7,0x86,0xab,0x27,0x16,0xc2,0x00,0x01,0x10,0xd1,
- 0x40,0x00,0x27,0x1a,0xf0,0x00,0x02,0x10,0xd6,0x00,0x0e,0xc7,0x86,0x90,0x27,0x1a,
- 0xc2,0x00,0x00,0x00,0xc9,0x06,0x5b,0xcf,0x86,0x5b,0x70,0x1f,0xc2,0x33,0x30,0x1f,
- 0xcf,0x84,0xd6,0x22,0x12,0xc2,0xd1,0x40,0x00,0x27,0xf0,0xf0,0xff,0xff,0xe0,0x41,
- 0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,
- 0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,
- 0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x86,
- 0x00,0xaa,0xdf,0x80,0x0a,0x22,0x12,0xc2,0xd1,0x40,0x00,0x40,0x10,0xc2,0x61,0xb2,
- 0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,
- 0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,
- 0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x61,0xb2,0xc2,0x51,0xb2,0xc2,0x86,0x00,
- 0xaa,0xdf,0x80,0x0a,0x22,0x12,0xc2,0xd1,0x40,0x00,0x40,0x10,0xc2,0xd6,0x00,0x0f,
- 0x61,0xb2,0xc2,0x86,0x00,0xaa,0xdf,0x80,0x0a,0x22,0x12,0xc2,0xd1,0x40,0x00,0x27,
- 0xf0,0xf0,0xff,0xff,0xe0,0x40,0x10,0xc2,0xd6,0x00,0x0f,0x61,0xb2,0xc2,0x86,0x00,
- 0xaa,0xdf,0x80,0x0a,0x41,0x10,0xc2,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x61,0xb2,0xc2,
- 0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x61,
- 0xb2,0xc2,0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,
- 0x39,0x60,0xb2,0xc2,0x86,0x00,0xaa,0xdf,0x80,0x0a,0x40,0x10,0xc2,0x61,0xb2,0xc2,
- 0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x61,
- 0xb2,0xc2,0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x61,0xb2,0xc2,0x61,0xb2,
- 0x39,0x61,0xb2,0xc2,0x61,0xb2,0x39,0x60,0xb2,0xc2,0x86,0x00,0xaa,0xdf,0x80,0x0a,
- 0x0f,0xb0,0x1f,0x00,0x0f,0xff,0xc9,0x06,0xdf,0x27,0x1b,0xc2,0x00,0x07,0xc0,0x23,
- 0x1b,0xe8,0x37,0x34,0xc2,0x00,0x00,0x03,0xca,0x06,0xd1,0x37,0x34,0xc2,0x00,0x00,
- 0x07,0xca,0x06,0xd8,0x47,0xa8,0xc2,0x00,0x01,0x00,0x0b,0x05,0x18,0x27,0x18,0xc2,
- 0x00,0x02,0x66,0xd1,0x40,0x00,0x20,0x10,0x18,0xcf,0x86,0xdf,0x0f,0xa8,0x18,0x00,
- 0x00,0x3f,0x27,0x18,0xc2,0x00,0x02,0x66,0xd1,0x40,0x00,0x20,0x10,0x18,0xcf,0x86,
- 0xdf,0x47,0xa8,0xc2,0x01,0x00,0x00,0x0b,0x05,0x18,0x27,0x18,0xc2,0x00,0x02,0x66,
- 0xd1,0x40,0x00,0x20,0x10,0x18,0x0f,0xb0,0xc2,0xff,0xf0,0x00,0xc9,0x07,0x01,0x27,
- 0x1b,0xc2,0x00,0x07,0xc1,0x23,0x1b,0xe8,0x37,0x34,0xc2,0x00,0x00,0x03,0xca,0x06,
- 0xf3,0x37,0x34,0xc2,0x00,0x00,0x07,0xca,0x06,0xfa,0x47,0xa8,0xc2,0x00,0x01,0x00,
- 0x0b,0x05,0x36,0x27,0x36,0xc2,0x00,0x02,0x66,0xd1,0x40,0x00,0x20,0x10,0x36,0xcf,
- 0x87,0x01,0x0f,0xa8,0x36,0x00,0x00,0x3f,0x27,0x36,0xc2,0x00,0x02,0x66,0xd1,0x40,
- 0x00,0x20,0x10,0x36,0xcf,0x87,0x01,0x47,0xa8,0xc2,0x01,0x00,0x00,0x0b,0x05,0x36,
- 0x27,0x36,0xc2,0x00,0x02,0x66,0xd1,0x40,0x00,0x20,0x10,0x36,0x0f,0xb0,0x1f,0x00,
- 0x0f,0xff,0xc9,0x08,0x23,0x27,0x1b,0x37,0x00,0x04,0xc0,0x27,0x1b,0x38,0x00,0x04,
- 0xe0,0x27,0x1b,0x39,0x00,0x05,0x00,0x27,0x1f,0xc2,0x00,0x02,0xa4,0xd1,0x40,0x00,
- 0x20,0x10,0x1e,0xca,0x87,0x31,0x70,0x37,0xe8,0xc7,0x89,0xb0,0xc7,0x88,0xaa,0x57,
- 0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,0x23,0x10,0x3a,0x43,0x18,0xc2,0x57,0x11,
- 0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0x70,0x38,0xe8,0xc7,0x89,0xb0,0xc7,0x88,0xaa,
- 0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,0x23,0x10,0x3b,0x43,0x18,0xc2,0x57,
- 0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0x70,0x39,0xe8,0xc7,0x89,0xb0,0xc7,0x88,
- 0xaa,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,0x23,0x10,0x3c,0x43,0x18,0xc2,
- 0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0xcf,0x88,0x2c,0x37,0x1e,0x1e,0x00,
- 0x00,0x00,0x27,0x1e,0xd8,0x00,0x03,0xff,0x70,0x37,0xe8,0xc7,0x89,0xb0,0x0b,0x98,
- 0xa8,0x37,0x1f,0xc2,0x00,0x00,0x04,0xc9,0x07,0x89,0x37,0x1f,0xc2,0x00,0x00,0x02,
- 0xc9,0x07,0xd6,0x27,0x10,0x35,0x00,0x00,0x30,0x40,0x10,0xc2,0x70,0xa8,0xc2,0xd6,
- 0x00,0x05,0x7b,0x35,0xc2,0x5f,0x10,0x30,0x00,0x00,0x00,0x4f,0x30,0x30,0x00,0x00,
- 0x02,0x47,0x30,0x30,0x40,0x00,0x00,0x47,0x35,0xc2,0xf0,0x00,0x00,0x4b,0x30,0x35,
- 0x70,0xa8,0xc2,0x23,0x35,0xa8,0xc7,0x88,0x9f,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,
- 0x00,0xc2,0x23,0x10,0x3a,0x43,0x18,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,
- 0xa8,0x70,0x38,0xe8,0x70,0x30,0xa8,0x27,0x10,0x35,0x00,0x00,0x18,0x40,0x10,0xc2,
- 0x70,0x30,0xc2,0xd6,0x00,0x03,0x7b,0x35,0xc2,0x5f,0x10,0x30,0x00,0x00,0x00,0x47,
- 0x35,0xc2,0xe0,0x00,0x00,0x4b,0x30,0x35,0x70,0xa8,0xc2,0x23,0x35,0xa8,0xc7,0x88,
- 0x9f,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,0x23,0x10,0x3b,0x43,0x18,0xc2,
- 0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0x70,0x39,0xe8,0x70,0x30,0xa8,0x27,
- 0x10,0x35,0x00,0x00,0x0c,0x40,0x10,0xc2,0x70,0x30,0xc2,0xd6,0x00,0x02,0x7b,0x35,
- 0xc2,0x5f,0x10,0x30,0x00,0x00,0x00,0x47,0x35,0xc2,0xc0,0x00,0x00,0x4b,0x30,0x35,
- 0x70,0xa8,0xc2,0x23,0x35,0xa8,0xc7,0x88,0x9f,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,
- 0x00,0xc2,0x23,0x10,0x3c,0x43,0x18,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,
- 0xa8,0xcf,0x88,0x2c,0x27,0x10,0x35,0x00,0x04,0x80,0x40,0x10,0xc2,0x70,0xa8,0xc2,
- 0xd6,0x00,0x0a,0x7b,0x35,0xc2,0x5f,0x10,0x30,0x00,0x00,0x00,0x47,0x30,0x30,0x20,
- 0x00,0x00,0x47,0x35,0xc2,0xfe,0x00,0x00,0x4b,0x30,0x35,0x70,0xa8,0xc2,0x23,0x35,
- 0xa8,0xc7,0x88,0x94,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,0x23,0x10,0x3a,
- 0x43,0x18,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0x70,0x38,0xe8,0x70,
- 0x30,0xa8,0x27,0x10,0x35,0x00,0x00,0x90,0x40,0x10,0xc2,0x70,0x30,0xc2,0xd6,0x00,
- 0x07,0x7b,0x35,0xc2,0x5f,0x10,0x30,0x00,0x00,0x00,0x47,0x30,0x30,0x20,0x00,0x00,
- 0x47,0x35,0xc2,0xf0,0x00,0x00,0x4b,0x30,0x35,0x70,0xa8,0xc2,0x23,0x35,0xa8,0xc7,
- 0x88,0x94,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,0x23,0x10,0x3b,0x43,0x18,
- 0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0x70,0x39,0xe8,0x70,0x30,0xa8,
- 0x27,0x10,0x35,0x00,0x00,0x12,0x40,0x10,0xc2,0x70,0x30,0xc2,0xd6,0x00,0x05,0x7b,
- 0x35,0xc2,0x5f,0x10,0x30,0x00,0x00,0x00,0x47,0x30,0x30,0x08,0x00,0x00,0x47,0x35,
- 0xc2,0x80,0x00,0x00,0x4b,0x30,0x35,0x70,0xa8,0xc2,0x23,0x35,0xa8,0xc7,0x88,0x94,
- 0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,0x23,0x10,0x3c,0x43,0x18,0xc2,0x57,
- 0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0xcf,0x88,0x2c,0x27,0x10,0x35,0x00,0x00,
- 0xa0,0x40,0x10,0xc2,0x70,0xa8,0xc2,0xd6,0x00,0x07,0x7b,0x35,0xc2,0x5f,0x10,0x30,
- 0x00,0x00,0x00,0x47,0x30,0x30,0x40,0x00,0x00,0x47,0x35,0xc2,0xf8,0x00,0x00,0x4b,
- 0x30,0x35,0x70,0xa8,0xc2,0x23,0x35,0xa8,0xc7,0x88,0x89,0x57,0x11,0xc2,0x02,0x00,
- 0x00,0x86,0x00,0xc2,0x23,0x10,0x3a,0x43,0x18,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,
- 0x86,0x00,0xa8,0x70,0x38,0xe8,0x70,0x30,0xa8,0x27,0x10,0x35,0x00,0x00,0x28,0x40,
- 0x10,0xc2,0x70,0x30,0xc2,0xd6,0x00,0x05,0x7b,0x35,0xc2,0x5f,0x10,0x30,0x00,0x00,
- 0x00,0x47,0x30,0x30,0x40,0x00,0x00,0x47,0x35,0xc2,0xe0,0x00,0x00,0x4b,0x30,0x35,
- 0x70,0xa8,0xc2,0x23,0x35,0xa8,0xc7,0x88,0x89,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,
- 0x00,0xc2,0x23,0x10,0x3b,0x43,0x18,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,
- 0xa8,0x70,0x39,0xe8,0x70,0x30,0xa8,0x27,0x10,0x35,0x00,0x00,0x0a,0x40,0x10,0xc2,
- 0x70,0x30,0xc2,0xd6,0x00,0x03,0x7b,0x35,0xc2,0x5f,0x10,0x30,0x00,0x00,0x00,0x47,
- 0x30,0x30,0x40,0x00,0x00,0x47,0x35,0xc2,0x80,0x00,0x00,0x4b,0x30,0x35,0x70,0xa8,
- 0xc2,0x23,0x35,0xa8,0xc7,0x88,0x89,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xc2,
- 0x23,0x10,0x3c,0x43,0x18,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0xcf,
- 0x88,0x2c,0x27,0x1b,0xe8,0x00,0x04,0xc0,0x70,0x10,0xa8,0x27,0x1b,0xe8,0x00,0x04,
- 0xe0,0x70,0x10,0xa8,0x27,0x1b,0xe8,0x00,0x05,0x00,0x70,0x10,0xa8,0x37,0x32,0xc2,
- 0x00,0x00,0x02,0xc9,0x88,0x44,0x0f,0xe8,0xc2,0x00,0x00,0x20,0xc9,0x88,0x3f,0x27,
- 0x1b,0x37,0x00,0x05,0x20,0x27,0x1b,0x38,0x00,0x05,0x40,0x27,0x1b,0x39,0x00,0x05,
- 0x60,0x70,0x36,0x18,0x0f,0xb0,0x1f,0xff,0xf0,0x00,0x47,0x1f,0x1f,0x00,0x10,0x00,
- 0xc9,0x87,0x0a,0xcf,0x88,0x66,0x27,0xf0,0xf0,0x00,0x00,0x01,0x27,0x1b,0x1b,0x00,
- 0x00,0x01,0xdf,0x80,0x0a,0x37,0x32,0xc2,0x00,0x00,0x03,0xc9,0x88,0x66,0x0f,0xb0,
- 0x1f,0xff,0xf0,0x00,0x47,0x1f,0x1f,0x00,0x10,0x00,0xc9,0x08,0x66,0x70,0x3a,0xc2,
- 0x27,0x1b,0xe8,0x00,0x05,0x20,0x43,0x36,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,
- 0x00,0xa8,0x70,0x3b,0xc2,0x27,0x1b,0xe8,0x00,0x05,0x40,0x43,0x36,0xc2,0x57,0x11,
- 0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0x70,0x3c,0xc2,0x27,0x1b,0xe8,0x00,0x05,0x60,
- 0x43,0x36,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xa8,0x27,0x1b,0x1b,0x00,
- 0x00,0x01,0x27,0xf0,0xf0,0x00,0x00,0x01,0xdf,0x80,0x0a,0x27,0x1b,0xe8,0x00,0x05,
- 0x20,0x70,0x10,0xa8,0x27,0x1b,0xe8,0x00,0x05,0x40,0x70,0x10,0xa8,0x27,0x1b,0xe8,
- 0x00,0x05,0x60,0x70,0x10,0xa8,0x27,0x1b,0x1b,0x00,0x00,0x01,0x27,0xf0,0xf0,0x00,
- 0x00,0x01,0xdf,0x80,0x0a,0x27,0x1b,0xe8,0x00,0x04,0xc0,0x70,0x10,0xa8,0x27,0x1b,
- 0xe8,0x00,0x04,0xe0,0x70,0x10,0xa8,0x27,0x1b,0xe8,0x00,0x05,0x00,0x70,0x10,0xa8,
- 0x27,0x1b,0xe8,0x00,0x05,0x20,0x70,0x10,0xa8,0x27,0x1b,0xe8,0x00,0x05,0x40,0x70,
- 0x10,0xa8,0x27,0x1b,0xe8,0x00,0x05,0x60,0x70,0x10,0xa8,0x27,0x1b,0x1b,0x00,0x00,
- 0x01,0xdf,0x80,0x0a,0x27,0xa8,0xa8,0xff,0xff,0xfc,0x4f,0xa8,0xc2,0x08,0x00,0x00,
- 0x27,0x1f,0xf8,0x00,0x05,0x90,0x23,0xb8,0xc2,0x27,0x1f,0xf8,0x00,0x05,0x7f,0x43,
- 0xb8,0xc2,0xdf,0x80,0x0a,0x27,0xa8,0xa8,0xff,0xff,0xf8,0x4f,0xa8,0xc2,0x04,0x00,
- 0x00,0x27,0x1f,0xf8,0x00,0x05,0x90,0x23,0xb8,0xc2,0x27,0x1f,0xf8,0x00,0x05,0x7f,
- 0x43,0xb8,0xc2,0xdf,0x80,0x0a,0x27,0xa8,0xa8,0xff,0xff,0xfe,0x4f,0xa8,0xc2,0x10,
- 0x00,0x00,0x27,0x1f,0xf8,0x00,0x05,0x90,0x23,0xb8,0xc2,0x27,0x1f,0xf8,0x00,0x05,
- 0x7f,0x43,0xb8,0xc2,0xdf,0x80,0x0a,0x93,0x00,0xa8,0x37,0x1e,0xc2,0x00,0x02,0x28,
- 0xd1,0x40,0x00,0x48,0xa8,0xa8,0x1f,0xa8,0xa8,0x80,0x00,0x00,0x47,0xa8,0xc2,0x40,
- 0x00,0x00,0x27,0x1f,0xf8,0x00,0x05,0x90,0x23,0xb8,0xc2,0x27,0x1f,0xf8,0x00,0x05,
- 0x7f,0x43,0xb8,0xc2,0xdf,0x80,0x0a,0x37,0x32,0xc2,0x00,0x00,0x01,0xc9,0x88,0xc6,
- 0x0f,0xb0,0x30,0x00,0x0f,0xff,0x70,0x10,0xb0,0xc9,0x08,0xdb,0xc7,0x88,0xdf,0x20,
- 0x00,0xb2,0x27,0x1b,0x1b,0x00,0x00,0x01,0xdf,0x80,0x0a,0x70,0xb0,0x1f,0x70,0x10,
- 0xb0,0x0f,0x1f,0x30,0x00,0x0f,0xff,0xc9,0x08,0xcd,0xc7,0x88,0xdf,0x20,0x00,0xb0,
- 0x0f,0x1f,0x30,0xff,0xf0,0x00,0xc9,0x08,0xdb,0x47,0x30,0x30,0x00,0x10,0x00,0xc7,
- 0x88,0xdf,0x20,0x00,0x1f,0x47,0x1f,0xc2,0x00,0x10,0x00,0x5f,0xb0,0xb2,0x00,0x00,
- 0x01,0x27,0x1b,0x1b,0x00,0x00,0x01,0xdf,0x80,0x0a,0x70,0xb0,0xb2,0x27,0x1b,0x1b,
- 0x00,0x00,0x01,0xdf,0x80,0x0a,0x37,0x2d,0xc2,0x00,0x00,0x01,0xca,0x88,0xfb,0x37,
- 0x1b,0xc2,0x00,0x00,0x02,0xca,0x08,0xf7,0x37,0x1b,0xc2,0x00,0x00,0x0a,0xca,0x08,
- 0xf3,0x37,0x1b,0xc2,0x00,0x00,0x16,0xca,0x08,0xef,0x27,0x30,0xc2,0x00,0x02,0x4c,
- 0xd1,0x40,0x00,0xdf,0x80,0x0a,0x27,0x30,0xc2,0x00,0x02,0x45,0xd1,0x40,0x00,0xdf,
- 0x80,0x0a,0x27,0x30,0xc2,0x00,0x02,0x36,0xd1,0x40,0x00,0xdf,0x80,0x0a,0x27,0x30,
- 0xc2,0x00,0x02,0x27,0xd1,0x40,0x00,0xdf,0x80,0x0a,0x37,0x1b,0xc2,0x00,0x00,0x01,
- 0xca,0x09,0x02,0x27,0x30,0xc2,0x00,0x02,0x5e,0xd1,0x40,0x00,0xdf,0x80,0x0a,0x27,
- 0x30,0xc2,0x00,0x02,0x4f,0xd1,0x40,0x00,0xdf,0x80,0x0a,0x37,0x32,0xc2,0x00,0x00,
- 0x01,0xc9,0x89,0x13,0x0f,0xb2,0xc2,0x00,0x0f,0xff,0xc9,0x09,0x2b,0x0f,0x98,0x30,
- 0x00,0x0f,0xff,0x27,0x30,0xc2,0x00,0x09,0x2f,0xc7,0xc0,0x00,0xcf,0x89,0x2b,0xdf,
- 0x80,0x0a,0x70,0xb2,0x1f,0x0f,0x1f,0xc2,0x00,0x0f,0xff,0xc9,0x09,0x1c,0x0f,0x98,
- 0x30,0x00,0x0f,0xff,0x27,0x30,0xc2,0x00,0x09,0x2f,0xc7,0xc0,0x00,0x0f,0x1f,0xc2,
- 0xff,0xf0,0x00,0xc9,0x09,0x2b,0x27,0xe8,0xe8,0x00,0x00,0x01,0x0f,0x9a,0x30,0xff,
- 0xf0,0x00,0x47,0x30,0x30,0x00,0x10,0x00,0x27,0x30,0xc2,0x00,0x09,0x2f,0xc7,0xc0,
- 0x00,0x27,0xe8,0xe8,0x00,0x00,0x01,0xdf,0x80,0x0a,0x27,0xe8,0xe8,0x00,0x00,0x02,
- 0x70,0x98,0x9a,0xdf,0x80,0x0a,0xcf,0x89,0x52,0xcf,0x89,0x47,0xcf,0x89,0x3e,0xcf,
- 0x89,0x33,0xc7,0x89,0xb0,0x0b,0x05,0x30,0xc7,0x89,0xb0,0x0b,0x05,0xa8,0x47,0x30,
- 0xc2,0x00,0x00,0x01,0x57,0xa8,0xc2,0x00,0x01,0x00,0x5f,0xa8,0xa8,0x01,0x00,0x00,
- 0xdf,0x80,0x0a,0xc7,0x89,0xb0,0x0b,0x05,0xa8,0x47,0xa8,0xc2,0x00,0x00,0x01,0x57,
- 0xa8,0xc2,0x00,0x01,0x00,0x5f,0xa8,0xa8,0x01,0x00,0x00,0xdf,0x80,0x0a,0xc7,0x89,
- 0xb0,0x0b,0x05,0x30,0xc7,0x89,0xb0,0x0b,0x05,0xa8,0x47,0x30,0xc2,0x00,0x00,0x01,
- 0x57,0x30,0xc2,0x00,0x01,0x00,0x5f,0xa8,0xa8,0x01,0x00,0x00,0xdf,0x80,0x0a,0xc7,
- 0x89,0xb0,0x0b,0x05,0x30,0xc7,0x89,0xb0,0x0b,0x05,0xa8,0x47,0x30,0xc2,0x00,0x00,
- 0x01,0x5f,0xa8,0x30,0x00,0x01,0x00,0xc7,0x89,0xb0,0x0b,0x05,0xa8,0x47,0x30,0xc2,
- 0x00,0x00,0x01,0x5f,0xa8,0xa8,0x01,0x00,0x00,0xdf,0x80,0x0a,0x37,0x32,0xc2,0x00,
- 0x00,0x01,0xc9,0x89,0x6c,0x0f,0xb2,0xc2,0x00,0x0f,0xff,0xc9,0x09,0x83,0xc7,0x89,
- 0xd8,0x0b,0x01,0x9a,0x27,0x5d,0x5d,0x00,0x00,0x02,0xdf,0x80,0x0a,0x70,0xb2,0x1f,
- 0x70,0x10,0x98,0x0f,0x1f,0xc2,0x00,0x0f,0xff,0xc9,0x09,0x75,0xc7,0x89,0xd8,0x0b,
- 0x01,0x98,0x27,0x5d,0x5d,0x00,0x00,0x02,0x0f,0x1f,0xc2,0xff,0xf0,0x00,0xc9,0x09,
- 0x81,0xc7,0x89,0xd8,0x0b,0x01,0x1f,0x47,0x1f,0xc2,0x00,0x10,0x00,0x5f,0x98,0x9a,
- 0x00,0x00,0x01,0x27,0x5d,0x5d,0x00,0x00,0x02,0xdf,0x80,0x0a,0x70,0x98,0x9a,0xdf,
- 0x80,0x0a,0x70,0x10,0x9a,0xdf,0x80,0x0a,0x37,0x32,0xc2,0x00,0x00,0x02,0xc9,0x09,
- 0x94,0x37,0x32,0xc2,0x00,0x00,0x03,0xc9,0x09,0xa3,0x70,0x30,0xc2,0xd1,0x40,0x00,
- 0x21,0x10,0x1e,0x22,0x10,0x30,0x27,0x1e,0xf0,0x00,0x03,0xff,0xc7,0x89,0xd8,0x0b,
- 0xb0,0x9a,0xdf,0x80,0x0a,0x70,0x30,0xc2,0xd1,0x40,0x00,0x21,0x10,0x1e,0x22,0x10,
- 0x30,0x27,0x1e,0xf0,0x00,0x03,0xff,0xc7,0x89,0xd8,0x0b,0xb0,0x98,0xc7,0x89,0xd8,
- 0x0b,0xb0,0x1f,0x47,0x1f,0xc2,0x00,0x10,0x00,0x5f,0x98,0x9a,0x00,0x00,0x01,0xdf,
- 0x80,0x0a,0x70,0x30,0xc2,0xd1,0x40,0x00,0x21,0x10,0x1e,0x22,0x10,0x30,0x27,0x1e,
- 0xf0,0x00,0x03,0xff,0xc7,0x89,0xd8,0x0b,0xb0,0x98,0x47,0x98,0xc2,0x00,0x10,0x00,
- 0x5f,0x98,0x9a,0x00,0x00,0x01,0xdf,0x80,0x0a,0x70,0x1e,0xc2,0x23,0x3e,0x3e,0x27,
- 0x1e,0xc2,0x00,0x02,0x10,0xd1,0x40,0x00,0x70,0x1d,0xc2,0x33,0x1e,0x1d,0xca,0x09,
- 0xd4,0x37,0x1d,0xd0,0x00,0x03,0xff,0x37,0x1d,0xc2,0x00,0x02,0x10,0xd5,0x40,0x00,
- 0x40,0x1c,0x1c,0x70,0x5b,0xc2,0xd1,0x40,0x00,0x32,0x5a,0xc2,0xc9,0x89,0xc4,0xc7,
- 0x8a,0x0d,0xcf,0x89,0xc0,0xc7,0x8a,0x00,0x90,0x00,0x33,0x22,0x00,0x5b,0x37,0x5b,
- 0xc2,0x00,0x0f,0xff,0xca,0x09,0xcc,0x97,0x80,0x5b,0x00,0x0f,0x00,0x44,0x33,0xc2,
- 0x0b,0x90,0xc2,0x13,0x1c,0xc2,0x27,0x1d,0x1d,0x00,0x00,0x18,0x5f,0x10,0x1c,0x00,
- 0x00,0x00,0xdf,0x80,0x0a,0x40,0x1c,0xc2,0x5f,0x10,0x1c,0x00,0x00,0x00,0xdf,0x80,
- 0x0a,0x70,0x1e,0xc2,0x23,0x3e,0x3e,0x27,0x1e,0xc2,0x00,0x02,0x10,0xd1,0x40,0x00,
- 0x70,0x1d,0xc2,0x33,0x1e,0x1d,0xca,0x09,0xfc,0x37,0x1d,0xd0,0x00,0x03,0xff,0x37,
- 0x1d,0xc2,0x00,0x02,0x10,0xd5,0x40,0x00,0x40,0x1c,0x1c,0x70,0x5c,0xc2,0xd1,0x40,
- 0x00,0x32,0x5a,0xc2,0xc9,0x89,0xec,0xc7,0x8a,0x0d,0xcf,0x89,0xe8,0xc7,0x8a,0x00,
- 0x90,0x00,0x33,0x22,0x00,0x5c,0x37,0x5c,0xc2,0x00,0x0f,0xff,0xca,0x09,0xf4,0x97,
- 0x80,0x5c,0x00,0x0f,0x00,0x44,0x33,0xc2,0x0b,0x90,0xc2,0x13,0x1c,0xc2,0x27,0x1d,
- 0x1d,0x00,0x00,0x18,0x5f,0x10,0x1c,0x00,0x00,0x00,0xdf,0x80,0x0a,0x40,0x1c,0xc2,
- 0x5f,0x10,0x1c,0x00,0x00,0x00,0xdf,0x80,0x0a,0x4b,0x6c,0xc2,0xd9,0x00,0x02,0xcb,
- 0x8a,0x04,0x23,0x6e,0xc2,0x33,0x6d,0xc2,0xdb,0x80,0x02,0x0f,0x73,0x73,0x00,0xff,
- 0xff,0x17,0x73,0x58,0x0e,0x00,0x00,0xc7,0x8b,0x0b,0x70,0x10,0x6c,0xdf,0x80,0x0a,
- 0x27,0x6c,0x6c,0x00,0x00,0x00,0xd9,0x00,0x02,0x97,0x80,0x58,0x0e,0x00,0x00,0xc7,
- 0x8b,0x0b,0x70,0x10,0x6c,0xdf,0x80,0x0a,0xc7,0x89,0xb0,0x0b,0x07,0x5e,0x4f,0x5e,
- 0xc2,0x00,0x01,0x00,0x1b,0x63,0x5e,0x0f,0x5e,0x5e,0x00,0xff,0x00,0x47,0x5e,0x60,
- 0x04,0x00,0x00,0x47,0x5e,0xc2,0x02,0x00,0x00,0x1b,0x60,0x60,0x47,0x5e,0x5e,0x01,
- 0x00,0x00,0x70,0x5e,0xc2,0x80,0x00,0xc2,0x1b,0x5e,0x5f,0x80,0x00,0xc2,0x1b,0x5f,
- 0x5f,0x80,0x00,0xc2,0x1b,0x5f,0x5f,0x80,0x00,0xc2,0x1b,0x5f,0x5f,0x80,0x00,0xc2,
- 0x1b,0x5f,0x5f,0x80,0x00,0xc2,0x1b,0x5f,0x5f,0x80,0x00,0xc2,0x1b,0x5f,0xc2,0x0b,
- 0x00,0x5f,0xc9,0x0a,0x36,0x1f,0x60,0x60,0x00,0x80,0x03,0x4f,0x63,0xc2,0x00,0x01,
- 0x00,0x1b,0x60,0x63,0xdf,0x80,0x0a,0xc7,0x89,0xb0,0x0b,0x00,0x5e,0x40,0x10,0xc2,
- 0x70,0x63,0xc2,0x82,0x00,0x63,0x47,0x63,0xc2,0x00,0x01,0x00,0x0b,0x00,0xc2,0x1b,
- 0x5e,0xc2,0xc9,0x0a,0x46,0x1f,0x63,0x63,0x00,0x80,0x05,0xdf,0x80,0x0a,0x70,0x66,
- 0xc2,0x23,0x3e,0xc2,0xcb,0x8a,0x67,0x27,0x66,0xc2,0x00,0x02,0x10,0xd1,0x40,0x00,
- 0x48,0x68,0x68,0x70,0x66,0x1e,0xc7,0x89,0xb0,0x27,0x66,0xd8,0x00,0x03,0xff,0x0b,
- 0x98,0xc2,0x13,0x68,0x68,0xc7,0x8a,0x74,0x70,0x11,0x66,0x70,0x11,0x1e,0x37,0x3e,
- 0xc2,0xff,0xff,0xf8,0xca,0x8a,0x5e,0xc7,0x89,0xb0,0x0b,0x07,0x68,0xc7,0x8a,0x74,
- 0xcf,0x8a,0x57,0x37,0x3e,0x1e,0x00,0x00,0x00,0x37,0x1e,0x66,0x00,0x00,0x08,0xc7,
- 0x89,0xb0,0x27,0x1e,0xd8,0x00,0x03,0xff,0x0b,0x98,0x68,0xdf,0x80,0x0a,0x93,0x00,
- 0x66,0x37,0x3e,0x1e,0x00,0x00,0x00,0x27,0x1e,0xc2,0x00,0x02,0x10,0xd1,0x40,0x00,
- 0x48,0x68,0x68,0xc7,0x89,0xb0,0x27,0x1e,0xd8,0x00,0x03,0xff,0x0b,0x98,0xc2,0x13,
- 0x68,0x68,0xdf,0x80,0x0a,0x70,0x69,0xd8,0x37,0x67,0xc2,0x00,0x00,0x02,0xca,0x83,
- 0x5a,0x27,0x67,0xc2,0x00,0x0a,0x7b,0xcf,0xc0,0x00,0xcf,0x8a,0x7e,0xcf,0x8a,0x94,
- 0xcf,0x8a,0x9a,0x97,0x80,0x67,0x00,0x00,0x02,0x70,0x9a,0xc2,0x0f,0xd8,0xd8,0x00,
- 0x00,0x0f,0x27,0xd8,0xc2,0x00,0x05,0xe0,0x33,0x6a,0xc2,0xc9,0x8a,0x8c,0x70,0x9a,
- 0xc2,0x0f,0xd8,0xd8,0x00,0x00,0x0f,0x27,0xd8,0x6a,0x00,0x05,0xe0,0x70,0x69,0xd8,
- 0x70,0x68,0xc2,0x13,0x98,0x9a,0x0f,0xd8,0xd8,0x00,0x00,0x0f,0x27,0xd8,0x69,0x00,
- 0x05,0xe0,0xdf,0x80,0x0a,0x97,0x80,0x67,0x00,0x00,0x00,0x4f,0x68,0xc2,0x00,0x01,
- 0x00,0x13,0x98,0x98,0xdf,0x80,0x0a,0x97,0x80,0x67,0x00,0x00,0x01,0x4f,0x68,0x98,
- 0x01,0x00,0x00,0xdf,0x80,0x0a,0x70,0x4c,0xc2,0x33,0xe0,0x31,0xcb,0x0a,0xa4,0x27,
- 0x31,0x31,0xff,0xfe,0x40,0x27,0x31,0x31,0x00,0x00,0x20,0xca,0x8a,0xa8,0xcf,0x8a,
- 0x9f,0xc7,0x8a,0xc1,0x70,0x4c,0xf8,0x70,0x46,0xc2,0xd6,0x00,0x1f,0x43,0xb2,0xba,
- 0x70,0xf8,0x4c,0x70,0x4d,0xc2,0xd1,0x40,0x00,0xd6,0x00,0x1f,0xc7,0x8a,0xbe,0x91,
- 0x00,0x4d,0x37,0x4c,0xc2,0x00,0x07,0xc0,0xc9,0x8a,0xb8,0x97,0x80,0x4c,0x00,0x06,
- 0x00,0x37,0x4d,0xc2,0x00,0x0f,0x00,0xc9,0x8a,0xbd,0x97,0x80,0x4d,0x00,0x0d,0x40,
- 0xdf,0x80,0x0a,0x44,0x92,0xc2,0xd0,0xc0,0x00,0xdf,0x80,0x0a,0x0f,0x4b,0xc2,0x00,
- 0x00,0x04,0xc9,0x0a,0xcf,0x70,0x10,0x47,0x70,0x10,0x48,0x27,0x46,0x46,0x00,0x00,
- 0x00,0xc9,0x8a,0xcf,0x24,0x10,0xc2,0xc9,0x8a,0xcf,0x0f,0xcd,0xcd,0xff,0xdf,0xff,
- 0x0f,0x4b,0x4b,0xff,0xff,0xfb,0x0f,0x4b,0xc2,0x00,0x00,0x08,0xc9,0x0a,0xdb,0x0f,
- 0xd7,0xc2,0x00,0x00,0x01,0xc9,0x8a,0xdb,0x70,0x49,0x47,0x70,0x4a,0x48,0x17,0xcd,
- 0xcd,0x00,0x20,0x00,0x0f,0x4b,0x4b,0xff,0xff,0xf7,0x0f,0x4b,0xc2,0x00,0x00,0x01,
- 0xc9,0x0a,0xee,0x70,0x47,0xc2,0x33,0x46,0xc2,0xcb,0x8a,0xe6,0x23,0x0b,0xc2,0xca,
- 0x0a,0xeb,0x27,0x46,0x46,0xff,0xf0,0x00,0xcf,0x8a,0xee,0x33,0x0b,0xc2,0xcb,0x0a,
- 0xeb,0x27,0x46,0x46,0x00,0x0f,0xff,0xcf,0x8a,0xee,0x0f,0x4b,0x4b,0xff,0xff,0xfe,
- 0x70,0x47,0x46,0x0f,0x4b,0xc2,0x00,0x00,0x02,0xc9,0x0b,0x02,0xd5,0x03,0x3a,0x34,
- 0x48,0xc2,0xca,0x8a,0xf9,0x33,0x0b,0xc2,0xcb,0x0a,0xfe,0x24,0x15,0xc2,0xd4,0x40,
- 0x00,0xcf,0x8b,0x02,0x23,0x0b,0xc2,0xca,0x0a,0xfe,0x24,0x0b,0xc2,0xd4,0x40,0x00,
- 0xcf,0x8b,0x02,0x0f,0x4b,0x4b,0xff,0xff,0xfd,0x70,0x48,0xc2,0xd4,0x40,0x00,0xdf,
- 0x80,0x0a,0x70,0x93,0xb0,0x27,0xf0,0xf0,0x00,0x00,0x10,0xdf,0x80,0x0a,0x70,0x92,
- 0xb0,0x27,0xf0,0xf0,0x00,0x00,0x10,0xdf,0x80,0x0a,0x70,0xd8,0x6f,0x70,0x51,0xd8,
- 0x70,0x58,0x9a,0x70,0xd8,0x51,0x0f,0xcb,0xd8,0x00,0x20,0x00,0xd9,0x00,0x02,0x47,
- 0x58,0xc9,0x00,0x01,0x00,0x70,0x00,0x52,0x70,0x6f,0xd8,0xdf,0x80,0x0a,0x93,0x00,
- 0x43,0x91,0x00,0x45,0x70,0xa2,0xc2,0x37,0xe0,0xc2,0x00,0x07,0xc0,0xcb,0x8b,0x1f,
- 0x97,0x80,0xe0,0x00,0x06,0x00,0x27,0xe0,0xc2,0x00,0x07,0x40,0xd1,0x40,0x00,0x32,
- 0x4d,0xc2,0xc9,0x0b,0x2b,0x48,0x11,0x41,0x4f,0xa0,0xc1,0x00,0x00,0x08,0x70,0x45,
- 0xc2,0xd1,0x40,0x00,0x70,0x43,0xc2,0xdf,0xc0,0x0b,0x70,0xa3,0xc2,0x37,0xe0,0xc2,
- 0x00,0x06,0x00,0xcb,0x0b,0x31,0x97,0x80,0xe0,0x00,0x07,0xbf,0x70,0x00,0x4f,0x70,
- 0x45,0xc2,0xd1,0x40,0x00,0x70,0x43,0xc2,0xdf,0xc0,0x0b,0x93,0x00,0x43,0x5b,0x10,
- 0x44,0x70,0xd8,0x45,0x27,0x55,0xc2,0x00,0x0b,0x3c,0xcf,0xc0,0x00,0xcf,0x8b,0x42,
- 0xcf,0x8b,0x47,0xcf,0x8b,0x4e,0xcf,0x8b,0x55,0xcf,0x8b,0x5a,0xcf,0x8b,0x61,0x4f,
- 0xc9,0x53,0x01,0x00,0x00,0x27,0x55,0x55,0x00,0x00,0x01,0xcf,0x8b,0xed,0x4f,0x53,
- 0xc2,0x00,0x00,0x01,0x5f,0xc9,0x53,0x00,0x01,0x00,0x27,0x55,0x55,0x00,0x00,0x01,
- 0xcf,0x8b,0xed,0x4f,0x53,0xc2,0x00,0x00,0x01,0x5f,0xc9,0x53,0x00,0x00,0x01,0x27,
- 0x55,0x55,0x00,0x00,0x01,0xcf,0x8b,0xed,0x4f,0xc9,0x54,0x01,0x00,0x00,0x27,0x55,
- 0x55,0x00,0x00,0x01,0xcf,0x8b,0xed,0x4f,0x54,0xc2,0x00,0x00,0x01,0x5f,0xc9,0x54,
- 0x00,0x01,0x00,0x27,0x55,0x55,0x00,0x00,0x01,0xcf,0x8b,0xed,0x4f,0x54,0xc2,0x00,
- 0x00,0x01,0x5f,0xc9,0x54,0x00,0x00,0x01,0x70,0x53,0xc2,0x33,0x54,0xc2,0xc9,0x8b,
- 0xe2,0x0f,0x53,0x56,0x7f,0x00,0x00,0x37,0x56,0xc2,0x10,0x00,0x00,0xcb,0x0b,0xe2,
- 0x97,0x80,0xc2,0x00,0x0b,0x72,0x57,0x53,0xc2,0x00,0x01,0x00,0xcf,0xc0,0x00,0xcf,
- 0x8b,0x82,0xcf,0x8b,0x88,0xcf,0x8b,0x90,0xcf,0x8b,0xa0,0xcf,0x8b,0xa8,0xcf,0x8b,
- 0xae,0xcf,0x8b,0xb0,0xcf,0x8b,0xb4,0xcf,0x8b,0xb7,0xcf,0x8b,0xbd,0xcf,0x8b,0xce,
- 0xcf,0x8b,0xd0,0xcf,0x8b,0xd3,0xcf,0x8b,0xd7,0xcf,0x8b,0xe2,0xcf,0x8b,0xe0,0x17,
- 0x4b,0x4b,0x00,0x00,0x01,0x4f,0x53,0x47,0x00,0x00,0x80,0x70,0x47,0x49,0xcf,0x8b,
- 0xec,0x17,0x4b,0x4b,0x00,0x00,0x02,0x0f,0x53,0x48,0x00,0xff,0xff,0x4f,0x48,0x48,
- 0x00,0x00,0x80,0x70,0x48,0x4a,0xcf,0x8b,0xec,0x0f,0x53,0xc2,0x00,0x00,0x01,0xc9,
- 0x8b,0x9a,0x27,0x57,0xc2,0x00,0x00,0x00,0xc9,0x0b,0x9f,0x17,0x4b,0x4b,0x00,0x00,
- 0x0b,0x70,0x10,0x57,0xcf,0x8b,0x9f,0x17,0x4b,0x4b,0x00,0x00,0x07,0x70,0x00,0x57,
- 0x70,0x10,0x47,0x70,0x10,0x48,0xcf,0x8b,0xec,0x0f,0x53,0xd8,0x00,0xff,0xff,0x27,
- 0xd8,0xd8,0x00,0x04,0x20,0x17,0x98,0x58,0x03,0x00,0x00,0xc7,0x8b,0x0b,0xcf,0x8b,
- 0xec,0x0f,0x59,0x59,0x00,0xff,0xff,0x17,0x59,0x58,0x04,0x00,0x00,0xc7,0x8b,0x0b,
- 0xcf,0x8b,0xec,0x70,0x10,0x59,0xcf,0x8b,0xec,0x0f,0x53,0xc2,0x00,0x00,0x01,0x93,
- 0x00,0x64,0xcf,0x8b,0xec,0x0f,0x53,0x4e,0x00,0xff,0xff,0xcf,0x8b,0xec,0x0f,0xd7,
- 0x56,0x00,0x00,0x01,0x17,0x56,0x58,0x08,0x00,0x00,0xc7,0x8b,0x0b,0xcf,0x8b,0xec,
- 0x70,0x69,0xc2,0x33,0x6a,0x56,0xca,0x0b,0xc2,0x27,0x56,0x56,0x00,0x00,0x10,0x17,
- 0x56,0x58,0x09,0x00,0x00,0xc7,0x8b,0x0b,0x27,0x56,0xc2,0xff,0xff,0xff,0x70,0xf0,
- 0x56,0x70,0x6a,0xf0,0xd6,0x40,0x00,0xc7,0x8c,0x23,0x70,0xf0,0x6a,0x70,0x56,0xf0,
- 0xcf,0x8b,0xec,0xd7,0x01,0x00,0xcf,0x8b,0xec,0x0f,0x53,0x6d,0x00,0xff,0xff,0xcf,
- 0x8b,0xec,0x0f,0x53,0xc2,0x00,0x00,0x01,0x4b,0x14,0x6c,0xcf,0x8b,0xec,0x70,0x5a,
- 0xc2,0x33,0x5b,0xc2,0xca,0x0b,0xdb,0x23,0x6e,0xc2,0x0b,0x0f,0x56,0x17,0x56,0x58,
- 0x0d,0x00,0x00,0xc7,0x8b,0x0b,0xcf,0x8b,0xec,0x70,0x10,0x55,0xd7,0x00,0x20,0x40,
- 0x10,0xc2,0x4f,0x53,0x53,0x00,0x01,0x00,0x70,0x53,0xc2,0x57,0x54,0x53,0x00,0x01,
- 0x00,0x5b,0x10,0x54,0x27,0x55,0x55,0xff,0xff,0xff,0xcf,0x8b,0xed,0x70,0x10,0x55,
- 0x70,0x45,0xd8,0x47,0x44,0xc2,0x00,0x00,0x01,0x70,0x43,0xc2,0xdf,0xc0,0x0b,0x93,
- 0x00,0x43,0x5b,0x10,0x44,0x70,0xd8,0x45,0x27,0x52,0xc2,0x00,0x00,0x00,0xc9,0x8b,
- 0xfb,0x70,0x51,0xc2,0x33,0x50,0xc2,0xc9,0x0c,0x01,0x27,0x52,0xc2,0x00,0x0b,0xfe,
- 0xcf,0xc0,0x00,0xcf,0x8c,0x06,0xcf,0x8c,0x10,0xcf,0x8c,0x1a,0x70,0x45,0xd8,0x47,
- 0x44,0xc2,0x00,0x00,0x01,0x70,0x43,0xc2,0xdf,0xc0,0x0b,0x70,0x50,0xd8,0x47,0x98,
- 0xc9,0x00,0x01,0x00,0x27,0x52,0x52,0x00,0x00,0x01,0x70,0x45,0xd8,0x47,0x44,0xc2,
- 0x00,0x00,0x01,0x70,0x43,0xc2,0xdf,0xc0,0x0b,0x70,0x50,0xd8,0x47,0x98,0xc9,0x01,
- 0x00,0x00,0x27,0x52,0x52,0x00,0x00,0x01,0x70,0x45,0xd8,0x47,0x44,0xc2,0x00,0x00,
- 0x01,0x70,0x43,0xc2,0xdf,0xc0,0x0b,0x70,0x50,0xd8,0x70,0x9a,0xc9,0x70,0xd8,0x50,
- 0x70,0x10,0x52,0x70,0x45,0xd8,0x47,0x44,0xc2,0x00,0x00,0x01,0x70,0x43,0xc2,0xdf,
- 0xc0,0x0b,0x70,0xb2,0x58,0xc7,0x8b,0x0b,0xdf,0x80,0x0a,0x95,0x00,0x45,0x93,0x00,
- 0x43,0x5b,0x10,0x44,0x70,0x5a,0xc2,0xd5,0x40,0x00,0x27,0x72,0xc2,0x00,0x0c,0x2e,
- 0xcf,0xc0,0x00,0xcf,0x8c,0x31,0xcf,0x8c,0x38,0xcf,0x8c,0x41,0x0f,0xc5,0x70,0x00,
- 0xff,0xff,0x4f,0x70,0x70,0x00,0x01,0x00,0x27,0x72,0x72,0x00,0x00,0x01,0xcf,0x8c,
- 0x4c,0x0f,0xc5,0x71,0x00,0xff,0xff,0x47,0x71,0xc2,0x01,0x00,0x00,0x13,0x70,0xc2,
- 0x5b,0x10,0x70,0x27,0x72,0x72,0x00,0x00,0x01,0xcf,0x8c,0x45,0x0f,0xc5,0xc2,0x00,
- 0xff,0xff,0x13,0x70,0xc2,0x70,0x10,0x72,0xd4,0x40,0x00,0x26,0x00,0x5a,0x37,0x5a,
- 0xc2,0x00,0x0f,0xff,0xca,0x0c,0x4c,0x97,0x80,0x5a,0x00,0x0f,0x00,0x70,0x45,0xc2,
- 0xd5,0x40,0x00,0x47,0x44,0xc2,0x00,0x00,0x01,0x70,0x43,0xc2,0xdf,0xc0,0x0b,0x70,
- 0xd8,0x45,0x0f,0xd7,0xc2,0x00,0x00,0x01,0xc9,0x0c,0x58,0x0f,0xcd,0xcd,0xff,0xdf,
- 0xff,0x70,0x45,0xd8,0xdf,0xc0,0x0b,0x70,0xb0,0xc2,0x23,0x98,0xb2,0x33,0x98,0x9b,
- 0x70,0xb0,0xc2,0x23,0x98,0xb2,0x33,0x98,0x9b,0xdf,0x80,0x0a,0x70,0xb0,0x38,0x70,
- 0x98,0x39,0x40,0x38,0xc2,0x64,0x39,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,
- 0x9a,0x44,0x38,0xc2,0x50,0x39,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xb3,
- 0xdf,0x80,0x0a,0x70,0xb0,0x38,0x70,0x98,0x39,0x40,0x38,0xc2,0x64,0x39,0xc2,0x57,
- 0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0xb3,0x44,0x38,0xc2,0x50,0x39,0xc2,0x57,0x11,
- 0xc2,0x02,0x00,0x00,0x86,0x00,0x9a,0xdf,0x80,0x0a,0x70,0xb2,0xc2,0x23,0xb3,0xb2,
- 0x33,0xb0,0xb0,0x70,0x9b,0xc2,0x23,0x9a,0x9b,0x33,0x98,0x98,0xdf,0x80,0x0a,0x41,
- 0xb2,0xc2,0x55,0x9b,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0x96,0xdf,0x80,
- 0x0a,0x41,0xb2,0xc2,0x65,0x9b,0xc2,0x57,0x11,0xc2,0x02,0x00,0x00,0x86,0x00,0x96,
- 0xdf,0x80,0x0a,0xff,0xff,0x30,0xdf,0xde
-};
diff --git a/os/pc/dat.h b/os/pc/dat.h
deleted file mode 100644
index 78a0e4a8..00000000
--- a/os/pc/dat.h
+++ /dev/null
@@ -1,258 +0,0 @@
-typedef struct Conf Conf;
-typedef struct FPU FPU;
-typedef struct FPenv FPenv;
-typedef ulong Instr;
-typedef struct ISAConf ISAConf;
-typedef struct Label Label;
-typedef struct Lock Lock;
-typedef struct MMU MMU;
-typedef struct Mach Mach;
-typedef struct Notsave Notsave;
-typedef struct PCArch PCArch;
-typedef struct Pcidev Pcidev;
-typedef struct PCMmap PCMmap;
-typedef struct PCMslot PCMslot;
-typedef struct Page Page;
-typedef struct PMMU PMMU;
-typedef struct Segdesc Segdesc;
-typedef struct Ureg Ureg;
-typedef struct Vctl Vctl;
-
-#pragma incomplete Ureg
-#pragma incomplete Vctl
-
-
-struct Lock
-{
- ulong key;
- ulong sr;
- ulong pc;
- ulong pri;
-};
-
-struct Label
-{
- ulong sp;
- ulong pc;
-};
-
-/*
- * FPenv.status
- */
-enum
-{
- FPINIT,
- FPACTIVE,
- FPINACTIVE,
-};
-
-/*
- * This structure must agree with FPsave and FPrestore asm routines
- */
-struct FPenv
-{
- ushort control;
- ushort r1;
- ushort status;
- ushort r2;
- ushort tag;
- ushort r3;
- ulong pc;
- ushort selector;
- ushort r4;
- ulong operand;
- ushort oselector;
- ushort r5;
-};
-
-/*
- * This structure must agree with fpsave and fprestore asm routines
- */
-struct FPU
-{
- FPenv env;
- uchar regs[80]; /* floating point registers */
-};
-
-struct Conf
-{
- ulong nmach; /* processors */
- ulong nproc; /* processes */
- ulong monitor; /* has monitor? */
- ulong npage0; /* total physical pages of memory */
- ulong npage1; /* total physical pages of memory */
- ulong npage; /* total physical pages of memory */
- ulong base0; /* base of bank 0 */
- ulong base1; /* base of bank 1 */
- ulong copymode; /* 0 is copy on write, 1 is copy on reference */
- ulong ialloc; /* max interrupt time allocation in bytes */
- ulong pipeqsize; /* size in bytes of pipe queues */
- int nuart; /* number of uart devices */
-};
-
-#include "../port/portdat.h"
-
-typedef struct {
- ulong link; /* link (old TSS selector) */
- ulong esp0; /* privilege level 0 stack pointer */
- ulong ss0; /* privilege level 0 stack selector */
- ulong esp1; /* privilege level 1 stack pointer */
- ulong ss1; /* privilege level 1 stack selector */
- ulong esp2; /* privilege level 2 stack pointer */
- ulong ss2; /* privilege level 2 stack selector */
- ulong cr3; /* page directory base register */
- ulong eip; /* instruction pointer */
- ulong eflags; /* flags register */
- ulong eax; /* general registers */
- ulong ecx;
- ulong edx;
- ulong ebx;
- ulong esp;
- ulong ebp;
- ulong esi;
- ulong edi;
- ulong es; /* segment selectors */
- ulong cs;
- ulong ss;
- ulong ds;
- ulong fs;
- ulong gs;
- ulong ldt; /* selector for task's LDT */
- ulong iomap; /* I/O map base address + T-bit */
-} Tss;
-
-struct Segdesc
-{
- ulong d0;
- ulong d1;
-};
-
-struct Mach
-{
- int machno; /* physical id of processor (KNOWN TO ASSEMBLY) */
- ulong splpc; /* pc of last caller to splhi */
-
- ulong* pdb; /* page directory base for this processor (va) */
- Tss* tss; /* tss for this processor */
- Segdesc *gdt; /* gdt for this processor */
-
- Proc* externup; /* extern register Proc *up */
-
- ulong ticks; /* of the clock since boot time */
- Proc* proc; /* current process on this processor */
- Label sched; /* scheduler wakeup */
- Lock alarmlock; /* access to alarm list */
- void* alarm; /* alarms bound to this clock */
- int inclockintr;
-
- int nrdy;
- int ilockdepth;
-
- int loopconst;
-
- Lock apictimerlock;
- int cpumhz;
- uvlong cyclefreq; /* Frequency of user readable cycle counter */
- uvlong cpuhz;
- int cpuidax;
- int cpuiddx;
- char cpuidid[16];
- char* cpuidtype;
- int havetsc;
- int havepge;
- uvlong tscticks;
- uvlong tscoff;
- int intr;
- ulong spuriousintr;
- int lastintr;
-
- vlong mtrrcap;
- vlong mtrrdef;
- vlong mtrrfix[11];
- vlong mtrrvar[32]; /* 256 max. */
-
- int stack[1];
-};
-
-struct
-{
- Lock;
- int machs; /* bitmap of active CPUs */
- int exiting; /* shutdown */
- int ispanic; /* shutdown in response to a panic */
- int thunderbirdsarego; /* lets the added processors continue to schedinit */
-}active;
-
-
-/*
- * routines for things outside the PC model, like power management
- */
-struct PCArch
-{
- char* id;
- int (*ident)(void); /* this should be in the model */
- void (*reset)(void); /* this should be in the model */
- int (*serialpower)(int); /* 1 == on, 0 == off */
- int (*modempower)(int); /* 1 == on, 0 == off */
-
- void (*intrinit)(void);
- int (*intrenable)(Vctl*);
- int (*intrvecno)(int);
- int (*intrdisable)(int);
-
- void (*clockenable)(void);
- uvlong (*fastclock)(uvlong*);
- void (*timerset)(uvlong);
-};
-
-/*
- * a parsed plan9.ini line
- */
-#define NISAOPT 8
-
-struct ISAConf {
- char *type;
- ulong port;
- int irq;
- ulong dma;
- ulong mem;
- ulong size;
- ulong freq;
-
- int nopt;
- char *opt[NISAOPT];
-};
-
-extern PCArch *arch; /* PC architecture */
-
-/*
- * Each processor sees its own Mach structure at address MACHADDR.
- * However, the Mach structures must also be available via the per-processor
- * MMU information array machp, mainly for disambiguation and access to
- * the clock which is only maintained by the bootstrap processor (0).
- */
-Mach* machp[MAXMACH];
-
-#define MACHP(n) (machp[n])
-
-extern Mach *m;
-//extern Proc *up;
-#define up (((Mach*)MACHADDR)->externup)
-
-extern int swcursor;
-
-/*
- * hardware info about a device
- */
-typedef struct {
- ulong port;
- int size;
-} Devport;
-
-struct DevConf
-{
- ulong intnum; /* interrupt number */
- char *type; /* card type, malloced */
- int nports; /* Number of ports */
- Devport *ports; /* The ports themselves */
-};
diff --git a/os/pc/devarch.c b/os/pc/devarch.c
deleted file mode 100644
index 6a7b52fe..00000000
--- a/os/pc/devarch.c
+++ /dev/null
@@ -1,940 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-typedef struct IOMap IOMap;
-struct IOMap
-{
- IOMap *next;
- int reserved;
- char tag[13];
- ulong start;
- ulong end;
-};
-
-static struct
-{
- Lock;
- IOMap *m;
- IOMap *free;
- IOMap maps[32]; // some initial free maps
-
- QLock ql; // lock for reading map
-} iomap;
-
-enum {
- Qdir = 0,
- Qioalloc = 1,
- Qiob,
- Qiow,
- Qiol,
- Qbase,
-
- Qmax = 16,
-};
-
-typedef long Rdwrfn(Chan*, void*, long, vlong);
-
-static Rdwrfn *readfn[Qmax];
-static Rdwrfn *writefn[Qmax];
-
-static Dirtab archdir[Qmax] = {
- ".", { Qdir, 0, QTDIR }, 0, 0555,
- "ioalloc", { Qioalloc, 0 }, 0, 0444,
- "iob", { Qiob, 0 }, 0, 0660,
- "iow", { Qiow, 0 }, 0, 0660,
- "iol", { Qiol, 0 }, 0, 0660,
-};
-Lock archwlock; /* the lock is only for changing archdir */
-int narchdir = Qbase;
-int (*_pcmspecial)(char*, ISAConf*);
-void (*_pcmspecialclose)(int);
-
-static int doi8253set = 1;
-
-/*
- * Add a file to the #P listing. Once added, you can't delete it.
- * You can't add a file with the same name as one already there,
- * and you get a pointer to the Dirtab entry so you can do things
- * like change the Qid version. Changing the Qid path is disallowed.
- */
-Dirtab*
-addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
-{
- int i;
- Dirtab d;
- Dirtab *dp;
-
- memset(&d, 0, sizeof d);
- strcpy(d.name, name);
- d.perm = perm;
-
- lock(&archwlock);
- if(narchdir >= Qmax){
- unlock(&archwlock);
- return nil;
- }
-
- for(i=0; i<narchdir; i++)
- if(strcmp(archdir[i].name, name) == 0){
- unlock(&archwlock);
- return nil;
- }
-
- d.qid.path = narchdir;
- archdir[narchdir] = d;
- readfn[narchdir] = rdfn;
- writefn[narchdir] = wrfn;
- dp = &archdir[narchdir++];
- unlock(&archwlock);
-
- return dp;
-}
-
-void
-ioinit(void)
-{
- char *excluded;
- int i;
-
- for(i = 0; i < nelem(iomap.maps)-1; i++)
- iomap.maps[i].next = &iomap.maps[i+1];
- iomap.maps[i].next = nil;
- iomap.free = iomap.maps;
-
- /*
- * This is necessary to make the IBM X20 boot.
- * Have not tracked down the reason.
- */
- ioalloc(0x0fff, 1, 0, "dummy"); // i82557 is at 0x1000, the dummy
- // entry is needed for swappable devs.
-
- if ((excluded = getconf("ioexclude")) != nil) {
- char *s;
-
- s = excluded;
- while (s && *s != '\0' && *s != '\n') {
- char *ends;
- int io_s, io_e;
-
- io_s = (int)strtol(s, &ends, 0);
- if (ends == nil || ends == s || *ends != '-') {
- print("ioinit: cannot parse option string\n");
- break;
- }
- s = ++ends;
-
- io_e = (int)strtol(s, &ends, 0);
- if (ends && *ends == ',')
- *ends++ = '\0';
- s = ends;
-
- ioalloc(io_s, io_e - io_s + 1, 0, "pre-allocated");
- }
- }
-
-}
-
-// Reserve a range to be ioalloced later.
-// This is in particular useful for exchangable cards, such
-// as pcmcia and cardbus cards.
-int
-ioreserve(int, int size, int align, char *tag)
-{
- IOMap *m, **l;
- int i, port;
-
- lock(&iomap);
- // find a free port above 0x400 and below 0x1000
- port = 0x400;
- for(l = &iomap.m; *l; l = &(*l)->next){
- m = *l;
- if (m->start < 0x400) continue;
- i = m->start - port;
- if(i > size)
- break;
- if(align > 0)
- port = ((port+align-1)/align)*align;
- else
- port = m->end;
- }
- if(*l == nil){
- unlock(&iomap);
- return -1;
- }
- m = iomap.free;
- if(m == nil){
- print("ioalloc: out of maps");
- unlock(&iomap);
- return port;
- }
- iomap.free = m->next;
- m->next = *l;
- m->start = port;
- m->end = port + size;
- m->reserved = 1;
- strncpy(m->tag, tag, sizeof(m->tag));
- m->tag[sizeof(m->tag)-1] = 0;
- *l = m;
-
- archdir[0].qid.vers++;
-
- unlock(&iomap);
- return m->start;
-}
-
-//
-// alloc some io port space and remember who it was
-// alloced to. if port < 0, find a free region.
-//
-int
-ioalloc(int port, int size, int align, char *tag)
-{
- IOMap *m, **l;
- int i;
-
- lock(&iomap);
- if(port < 0){
- // find a free port above 0x400 and below 0x1000
- port = 0x400;
- for(l = &iomap.m; *l; l = &(*l)->next){
- m = *l;
- if (m->start < 0x400) continue;
- i = m->start - port;
- if(i > size)
- break;
- if(align > 0)
- port = ((port+align-1)/align)*align;
- else
- port = m->end;
- }
- if(*l == nil){
- unlock(&iomap);
- return -1;
- }
- } else {
- // Only 64KB I/O space on the x86.
- if((port+size) > 0x10000){
- unlock(&iomap);
- return -1;
- }
- // see if the space clashes with previously allocated ports
- for(l = &iomap.m; *l; l = &(*l)->next){
- m = *l;
- if(m->end <= port)
- continue;
- if(m->reserved && m->start == port && m->end == port + size) {
- m->reserved = 0;
- unlock(&iomap);
- return m->start;
- }
- if(m->start >= port+size)
- break;
- unlock(&iomap);
- return -1;
- }
- }
- m = iomap.free;
- if(m == nil){
- print("ioalloc: out of maps");
- unlock(&iomap);
- return port;
- }
- iomap.free = m->next;
- m->next = *l;
- m->start = port;
- m->end = port + size;
- strncpy(m->tag, tag, sizeof(m->tag));
- m->tag[sizeof(m->tag)-1] = 0;
- *l = m;
-
- archdir[0].qid.vers++;
-
- unlock(&iomap);
- return m->start;
-}
-
-void
-iofree(int port)
-{
- IOMap *m, **l;
-
- lock(&iomap);
- for(l = &iomap.m; *l; l = &(*l)->next){
- if((*l)->start == port){
- m = *l;
- *l = m->next;
- m->next = iomap.free;
- iomap.free = m;
- break;
- }
- if((*l)->start > port)
- break;
- }
- archdir[0].qid.vers++;
- unlock(&iomap);
-}
-
-int
-iounused(int start, int end)
-{
- IOMap *m;
-
- for(m = iomap.m; m; m = m->next){
- if(start >= m->start && start < m->end
- || start <= m->start && end > m->start)
- return 0;
- }
- return 1;
-}
-
-static void
-checkport(int start, int end)
-{
- /* standard vga regs are OK */
- if(start >= 0x2b0 && end <= 0x2df+1)
- return;
- if(start >= 0x3c0 && end <= 0x3da+1)
- return;
-
- if(iounused(start, end))
- return;
- error(Eperm);
-}
-
-static Chan*
-archattach(char* spec)
-{
- return devattach('P', spec);
-}
-
-Walkqid*
-archwalk(Chan* c, Chan *nc, char** name, int nname)
-{
- return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
-}
-
-static int
-archstat(Chan* c, uchar* dp, int n)
-{
- return devstat(c, dp, n, archdir, narchdir, devgen);
-}
-
-static Chan*
-archopen(Chan* c, int omode)
-{
- return devopen(c, omode, archdir, narchdir, devgen);
-}
-
-static void
-archclose(Chan*)
-{
-}
-
-enum
-{
- Linelen= 31,
-};
-
-static long
-archread(Chan *c, void *a, long n, vlong offset)
-{
- char *buf, *p;
- int port;
- ushort *sp;
- ulong *lp;
- IOMap *m;
- Rdwrfn *fn;
-
- switch((ulong)c->qid.path){
-
- case Qdir:
- return devdirread(c, a, n, archdir, narchdir, devgen);
-
- case Qiob:
- port = offset;
- checkport(offset, offset+n);
- for(p = a; port < offset+n; port++)
- *p++ = inb(port);
- return n;
-
- case Qiow:
- if(n & 1)
- error(Ebadarg);
- checkport(offset, offset+n);
- sp = a;
- for(port = offset; port < offset+n; port += 2)
- *sp++ = ins(port);
- return n;
-
- case Qiol:
- if(n & 3)
- error(Ebadarg);
- checkport(offset, offset+n);
- lp = a;
- for(port = offset; port < offset+n; port += 4)
- *lp++ = inl(port);
- return n;
-
- case Qioalloc:
- break;
-
- default:
- if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
- return fn(c, a, n, offset);
- error(Eperm);
- break;
- }
-
- if((buf = malloc(n)) == nil)
- error(Enomem);
- p = buf;
- n = n/Linelen;
- offset = offset/Linelen;
-
- lock(&iomap);
- for(m = iomap.m; n > 0 && m != nil; m = m->next){
- if(offset-- > 0)
- continue;
- sprint(p, "%8lux %8lux %-12.12s\n", m->start, m->end-1, m->tag);
- p += Linelen;
- n--;
- }
- unlock(&iomap);
-
- n = p - buf;
- memmove(a, buf, n);
- free(buf);
-
- return n;
-}
-
-static long
-archwrite(Chan *c, void *a, long n, vlong offset)
-{
- char *p;
- int port;
- ushort *sp;
- ulong *lp;
- Rdwrfn *fn;
-
- switch((ulong)c->qid.path){
-
- case Qiob:
- p = a;
- checkport(offset, offset+n);
- for(port = offset; port < offset+n; port++)
- outb(port, *p++);
- return n;
-
- case Qiow:
- if(n & 1)
- error(Ebadarg);
- checkport(offset, offset+n);
- sp = a;
- for(port = offset; port < offset+n; port += 2)
- outs(port, *sp++);
- return n;
-
- case Qiol:
- if(n & 3)
- error(Ebadarg);
- checkport(offset, offset+n);
- lp = a;
- for(port = offset; port < offset+n; port += 4)
- outl(port, *lp++);
- return n;
-
- default:
- if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
- return fn(c, a, n, offset);
- error(Eperm);
- break;
- }
- return 0;
-}
-
-Dev archdevtab = {
- 'P',
- "arch",
-
- devreset,
- devinit,
- devshutdown,
- archattach,
- archwalk,
- archstat,
- archopen,
- devcreate,
- archclose,
- archread,
- devbread,
- archwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-/*
- * the following is a generic version of the
- * architecture specific stuff
- */
-
-static int
-unimplemented(int)
-{
- return 0;
-}
-
-static void
-nop(void)
-{
-}
-
-/*
- * On a uniprocessor, you'd think that coherence could be nop,
- * but it can't. We still need a barrier when using coherence() in
- * device drivers.
- *
- * On VMware, it's safe (and a huge win) to set this to nop.
- * Aux/vmware does this via the #P/archctl file.
- */
-void (*coherence)(void) = nop;
-
-PCArch* arch;
-extern PCArch* knownarch[];
-
-PCArch archgeneric = {
-.id= "generic",
-.ident= 0,
-.reset= i8042reset,
-.serialpower= unimplemented,
-.modempower= unimplemented,
-
-.intrinit= i8259init,
-.intrenable= i8259enable,
-.intrvecno= i8259vecno,
-.intrdisable= i8259disable,
-
-.clockenable= i8253enable,
-.fastclock= i8253read,
-.timerset= i8253timerset,
-};
-
-typedef struct X86type X86type;
-struct X86type {
- int family;
- int model;
- int aalcycles;
- char* name;
-};
-
-static X86type x86intel[] =
-{
- { 4, 0, 22, "486DX", }, /* known chips */
- { 4, 1, 22, "486DX50", },
- { 4, 2, 22, "486SX", },
- { 4, 3, 22, "486DX2", },
- { 4, 4, 22, "486SL", },
- { 4, 5, 22, "486SX2", },
- { 4, 7, 22, "DX2WB", }, /* P24D */
- { 4, 8, 22, "DX4", }, /* P24C */
- { 4, 9, 22, "DX4WB", }, /* P24CT */
- { 5, 0, 23, "P5", },
- { 5, 1, 23, "P5", },
- { 5, 2, 23, "P54C", },
- { 5, 3, 23, "P24T", },
- { 5, 4, 23, "P55C MMX", },
- { 5, 7, 23, "P54C VRT", },
- { 6, 1, 16, "PentiumPro", },/* trial and error */
- { 6, 3, 16, "PentiumII", },
- { 6, 5, 16, "PentiumII/Xeon", },
- { 6, 6, 16, "Celeron", },
- { 6, 7, 16, "PentiumIII/Xeon", },
- { 6, 8, 16, "PentiumIII/Xeon", },
- { 6, 0xB, 16, "PentiumIII/Xeon", },
- { 0xF, 1, 16, "P4", }, /* P4 */
- { 0xF, 2, 16, "PentiumIV/Xeon", },
-
- { 3, -1, 32, "386", }, /* family defaults */
- { 4, -1, 22, "486", },
- { 5, -1, 23, "P5", },
- { 6, -1, 16, "P6", },
- { 0xF, -1, 16, "P4", }, /* P4 */
-
- { -1, -1, 16, "unknown", }, /* total default */
-};
-
-/*
- * The AMD processors all implement the CPUID instruction.
- * The later ones also return the processor name via functions
- * 0x80000002, 0x80000003 and 0x80000004 in registers AX, BX, CX
- * and DX:
- * K5 "AMD-K5(tm) Processor"
- * K6 "AMD-K6tm w/ multimedia extensions"
- * K6 3D "AMD-K6(tm) 3D processor"
- * K6 3D+ ?
- */
-static X86type x86amd[] =
-{
- { 5, 0, 23, "AMD-K5", }, /* guesswork */
- { 5, 1, 23, "AMD-K5", }, /* guesswork */
- { 5, 2, 23, "AMD-K5", }, /* guesswork */
- { 5, 3, 23, "AMD-K5", }, /* guesswork */
- { 5, 6, 11, "AMD-K6", }, /* trial and error */
- { 5, 7, 11, "AMD-K6", }, /* trial and error */
- { 5, 8, 11, "AMD-K6-2", }, /* trial and error */
- { 5, 9, 11, "AMD-K6-III", },/* trial and error */
-
- { 6, 1, 11, "AMD-Athlon", },/* trial and error */
- { 6, 2, 11, "AMD-Athlon", },/* trial and error */
-
- { 4, -1, 22, "Am486", }, /* guesswork */
- { 5, -1, 23, "AMD-K5/K6", }, /* guesswork */
- { 6, -1, 11, "AMD-Athlon", },/* guesswork */
- { 0xF, -1, 11, "AMD64", }, /* guesswork */
-
- { -1, -1, 11, "unknown", }, /* total default */
-};
-
-/*
- * WinChip 240MHz
- */
-static X86type x86winchip[] =
-{
- {5, 4, 23, "Winchip",}, /* guesswork */
- {6, 7, 23, "Via C3 Samuel 2 or Ezra",},
- {6, 8, 23, "Via C3 Ezra-T",},
- { -1, -1, 23, "unknown", }, /* total default */
-};
-
-/*
- * SiS 55x
- */
-static X86type x86sis[] =
-{
- {5, 0, 23, "SiS 55x",}, /* guesswork */
- { -1, -1, 23, "unknown", }, /* total default */
-};
-
-static X86type *cputype;
-
-static void simplecycles(uvlong*);
-void (*cycles)(uvlong*) = simplecycles;
-void _cycles(uvlong*); /* in l.s */
-
-static void
-simplecycles(uvlong*x)
-{
- *x = m->ticks;
-}
-
-void
-cpuidprint(void)
-{
- int i;
- char buf[128];
-
- i = sprint(buf, "cpu%d: %dMHz ", m->machno, m->cpumhz);
- if(m->cpuidid[0])
- i += sprint(buf+i, "%12.12s ", m->cpuidid);
- sprint(buf+i, "%s (cpuid: AX 0x%4.4uX DX 0x%4.4uX)\n",
- m->cpuidtype, m->cpuidax, m->cpuiddx);
- print(buf);
-}
-
-/*
- * figure out:
- * - cpu type
- * - whether or not we have a TSC (cycle counter)
- * - whether or not it supports page size extensions
- * (if so turn it on)
- * - whether or not it supports machine check exceptions
- * (if so turn it on)
- * - whether or not it supports the page global flag
- * (if so turn it on)
- */
-int
-cpuidentify(void)
-{
- char *p;
- int family, model, nomce;
- X86type *t, *tab;
- ulong cr4;
- vlong mca, mct;
-
- cpuid(m->cpuidid, &m->cpuidax, &m->cpuiddx);
- if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0)
- tab = x86amd;
- else if(strncmp(m->cpuidid, "CentaurHauls", 12) == 0)
- tab = x86winchip;
- else if(strncmp(m->cpuidid, "SiS SiS SiS ", 12) == 0)
- tab = x86sis;
- else
- tab = x86intel;
-
- family = X86FAMILY(m->cpuidax);
- model = X86MODEL(m->cpuidax);
- for(t=tab; t->name; t++)
- if((t->family == family && t->model == model)
- || (t->family == family && t->model == -1)
- || (t->family == -1))
- break;
-
- m->cpuidtype = t->name;
-
- /*
- * if there is one, set tsc to a known value
- */
- if(m->cpuiddx & 0x10){
- m->havetsc = 1;
- cycles = _cycles;
- if(m->cpuiddx & 0x20)
- wrmsr(0x10, 0);
- }
-
- /*
- * use i8253 to guess our cpu speed
- */
- guesscpuhz(t->aalcycles);
-
- /*
- * If machine check exception, page size extensions or page global bit
- * are supported enable them in CR4 and clear any other set extensions.
- * If machine check was enabled clear out any lingering status.
- */
- if(m->cpuiddx & 0x2088){
- cr4 = 0;
- if(m->cpuiddx & 0x08)
- cr4 |= 0x10; /* page size extensions */
- if(p = getconf("*nomce"))
- nomce = strtoul(p, 0, 0);
- else
- nomce = 0;
- if((m->cpuiddx & 0x80) && !nomce){
- cr4 |= 0x40; /* machine check enable */
- if(family == 5){
- rdmsr(0x00, &mca);
- rdmsr(0x01, &mct);
- }
- }
-
- /*
- * Detect whether the chip supports the global bit
- * in page directory and page table entries. When set
- * in a particular entry, it means ``don't bother removing
- * this from the TLB when CR3 changes.''
- *
- * We flag all kernel pages with this bit. Doing so lessens the
- * overhead of switching processes on bare hardware,
- * even more so on VMware. See mmu.c:/^memglobal.
- *
- * For future reference, should we ever need to do a
- * full TLB flush, it can be accomplished by clearing
- * the PGE bit in CR4, writing to CR3, and then
- * restoring the PGE bit.
- */
- if(m->cpuiddx & 0x2000){
- cr4 |= 0x80; /* page global enable bit */
- m->havepge = 1;
- }
-
- putcr4(cr4);
- if(m->cpuiddx & 0x80)
- rdmsr(0x01, &mct);
- }
-
- cputype = t;
- return t->family;
-}
-
-static long
-cputyperead(Chan*, void *a, long n, vlong offset)
-{
- char str[32];
- ulong mhz;
-
- mhz = (m->cpuhz+999999)/1000000;
-
- snprint(str, sizeof(str), "%s %lud\n", cputype->name, mhz);
- return readstr(offset, a, n, str);
-}
-
-static long
-archctlread(Chan*, void *a, long nn, vlong offset)
-{
- char buf[256];
- int n;
-
- n = snprint(buf, sizeof buf, "cpu %s %lud%s\n",
- cputype->name, (ulong)(m->cpuhz+999999)/1000000,
- m->havepge ? " pge" : "");
- n += snprint(buf+n, sizeof buf-n, "pge %s\n", getcr4()&0x80 ? "on" : "off");
- n += snprint(buf+n, sizeof buf-n, "coherence ");
- if(coherence == mb386)
- n += snprint(buf+n, sizeof buf-n, "mb386\n");
- else if(coherence == mb586)
- n += snprint(buf+n, sizeof buf-n, "mb586\n");
- else if(coherence == nop)
- n += snprint(buf+n, sizeof buf-n, "nop\n");
- else
- n += snprint(buf+n, sizeof buf-n, "0x%p\n", coherence);
- n += snprint(buf+n, sizeof buf-n, "i8253set %s\n", doi8253set ? "on" : "off");
- buf[n] = 0;
- return readstr(offset, a, nn, buf);
-}
-
-enum
-{
- CMpge,
- CMcoherence,
- CMi8253set,
-};
-
-static Cmdtab archctlmsg[] =
-{
- CMpge, "pge", 2,
- CMcoherence, "coherence", 2,
- CMi8253set, "i8253set", 2,
-};
-
-static long
-archctlwrite(Chan*, void *a, long n, vlong)
-{
- Cmdbuf *cb;
- Cmdtab *ct;
-
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
- ct = lookupcmd(cb, archctlmsg, nelem(archctlmsg));
- switch(ct->index){
- case CMpge:
- if(!m->havepge)
- error("processor does not support pge");
- if(strcmp(cb->f[1], "on") == 0)
- putcr4(getcr4() | 0x80);
- else if(strcmp(cb->f[1], "off") == 0)
- putcr4(getcr4() & ~0x80);
- else
- cmderror(cb, "invalid pge ctl");
- break;
- case CMcoherence:
- if(strcmp(cb->f[1], "mb386") == 0)
- coherence = mb386;
- else if(strcmp(cb->f[1], "mb586") == 0){
- if(X86FAMILY(m->cpuidax) < 5)
- error("invalid coherence ctl on this cpu family");
- coherence = mb586;
- }
- else if(strcmp(cb->f[1], "nop") == 0){
- /* only safe on vmware */
- if(conf.nmach > 1)
- error("cannot disable coherence on a multiprocessor");
- coherence = nop;
- }else
- cmderror(cb, "invalid coherence ctl");
- break;
- case CMi8253set:
- if(strcmp(cb->f[1], "on") == 0)
- doi8253set = 1;
- else if(strcmp(cb->f[1], "off") == 0){
- doi8253set = 0;
- (*arch->timerset)(0);
- }else
- cmderror(cb, "invalid i2853set ctl");
- break;
- }
- free(cb);
- poperror();
- return n;
-}
-
-void
-archinit(void)
-{
- PCArch **p;
-
- arch = 0;
- for(p = knownarch; *p; p++){
- if((*p)->ident && (*p)->ident() == 0){
- arch = *p;
- break;
- }
- }
- if(arch == 0)
- arch = &archgeneric;
- else{
- if(arch->id == 0)
- arch->id = archgeneric.id;
- if(arch->reset == 0)
- arch->reset = archgeneric.reset;
- if(arch->serialpower == 0)
- arch->serialpower = archgeneric.serialpower;
- if(arch->modempower == 0)
- arch->modempower = archgeneric.modempower;
- if(arch->intrinit == 0)
- arch->intrinit = archgeneric.intrinit;
- if(arch->intrenable == 0)
- arch->intrenable = archgeneric.intrenable;
- }
-
- /*
- * Decide whether to use copy-on-reference (386 and mp).
- * We get another chance to set it in mpinit() for a
- * multiprocessor.
- */
- if(X86FAMILY(m->cpuidax) == 3)
- conf.copymode = 1;
-
- if(X86FAMILY(m->cpuidax) >= 5)
- coherence = mb586;
-
- addarchfile("cputype", 0444, cputyperead, nil);
- addarchfile("archctl", 0664, archctlread, archctlwrite);
-}
-
-/*
- * call either the pcmcia or pccard device setup
- */
-int
-pcmspecial(char *idstr, ISAConf *isa)
-{
- return (_pcmspecial != nil)? _pcmspecial(idstr, isa): -1;
-}
-
-/*
- * call either the pcmcia or pccard device teardown
- */
-void
-pcmspecialclose(int a)
-{
- if (_pcmspecialclose != nil)
- _pcmspecialclose(a);
-}
-
-/*
- * return value and speed of timer set in arch->clockenable
- */
-uvlong
-fastticks(uvlong *hz)
-{
- return (*arch->fastclock)(hz);
-}
-
-/*
- * set next timer interrupt
- */
-void
-timerset(uvlong x)
-{
- if(doi8253set)
- (*arch->timerset)(x);
-}
diff --git a/os/pc/devds1620.c b/os/pc/devds1620.c
deleted file mode 100644
index b5e6fc83..00000000
--- a/os/pc/devds1620.c
+++ /dev/null
@@ -1,368 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-enum {
- // Ziatech 5512 Digital I/O ASIC register info
- PortSelect = 0xE7,
- Port = 0xE1,
- DQ = 1<<0,
- CLK = 1<<1,
- RST = 1<<2,
- TL = 1<<3,
- TH = 1<<4,
-
- // ds1620 Masks
- Mread = 0xA0,
- Mwrite = 0,
-
- // ds1620 Registers
- Rtemp = 0x0A,
- Rcounter = 0x00,
- Rslope = 0x09,
- Rhi = 0x01,
- Rlo = 0x02,
- Rconfig = 0x0C,
- Cdone = 1<<7, // conversion done
- Cthf = 1<<6, // temp >= Rhi
- Ctlf = 1<<5, // temp <= Rlo
- Cnvb = 1<<4, // e^2 nvram busy (write may take up to 10ms)
- Ccpu = 1<<1, // cpu use (0=clk starts conversion when rst lo)
- C1shot = 1<<0, // perform one conversion then stop
-
- // ds1620 Commands
- Startconv = 0xEE,
- Stopconv = 0x22,
-
- ALOTEMP = 0,
- AHITEMP = 1,
-};
-
-#define send(v) outb(Port, v); delay(1)
-#define recv() (!(inb(Port) & 1))
-
-enum {
- Qdir = 0,
- Qtemp,
- Qalarm,
-};
-
-Dirtab ds1620tab[]={
- "temp", {Qtemp, 0}, 0, 0666,
- "alarm", {Qalarm, 0}, 0, 0444,
-};
-
-typedef struct Temp Temp;
-struct Temp
-{
- Lock;
- int lo;
- int cur;
- int hi;
-
- int alo;
- int ahi;
- int atime;
- Queue *aq;
-};
-
-static Temp t;
-
-static void
-sendreg(int r)
-{
- int d, i;
-
- r = ~r;
- for(i=0;i<8;i++) {
- d = (r >> i) & 1;
- send(CLK|d);
- send(d);
- send(CLK);
- }
-}
-
-static int
-ds1620rdreg(int r, int nb)
-{
- int i, s;
-
- s = splhi();
-
- outb(PortSelect, 0);
- send(RST|CLK);
- sendreg(r|Mread);
- r = 0;
- for(i=0; i < nb; i++) {
- r |= recv() << i;
- delay(1);
- send(0);
- send(CLK);
- }
- send(RST);
-
- splx(s);
- return r;
-}
-
-static void
-ds1620wrreg(int r, int v, int nb)
-{
- int d, i, s;
-
- s = splhi();
-
- outb(PortSelect, 0);
- send(RST|CLK);
- sendreg(r|Mwrite);
- v = ~v;
- for(i=0; i < nb; i++) {
- d = (v >> i) & 1;
- send(CLK|d);
- send(0);
- send(CLK);
- }
- send(RST);
-
- splx(s);
-}
-
-static void
-ds1620cmd(int r)
-{
- int s;
-
- s = splhi();
- outb(PortSelect, 0);
- send(RST|CLK);
- sendreg(r);
- send(RST);
- splx(s);
-}
-
-static char*
-t2s(int t)
-{
- static char s[16];
-
- sprint(s, "%4d.", t>>1);
- if(t&1)
- strcat(s, "5");
- else
- strcat(s, "0");
- return s;
-}
-
-static int
-s2t(char *s)
-{
- int v;
- char *p;
- p = strchr(s, '.');
- if(p != nil)
- *p++ = '\0';
- v = strtoul(s, nil, 0);
- v <<= 1;
- if(p != nil && *p != '\0' && *p >= '5')
- v |= 1;
- return v;
-}
-
-static void
-alarm(int code, Temp *tt)
-{
- char buf[256], *end;
- int s;
-
- s = seconds();
-
- if(s - tt->atime < 60)
- return;
- tt->atime = s;
-
- end = buf;
- end += sprint(buf, "(alarm) %8.8uX %uld temp ", code, seconds());
- switch(code) {
- case ALOTEMP:
- end += sprint(end, "%s below threshold ", t2s(tt->lo));
- end += sprint(end, "%s.\n", t2s(tt->alo));
- break;
- case AHITEMP:
- end += sprint(end, "%s above threshold ", t2s(tt->hi));
- end += sprint(end, "%s.\n", t2s(tt->ahi));
- break;
- }
-
- qproduce(tt->aq, buf, end-buf);
-}
-
-void
-tmon(void *a)
-{
- int r;
- Temp *t;
-
- t = a;
- r = ds1620rdreg(Rtemp, 9);
- lock(t);
- t->lo = t->cur = t->hi = r;
- unlock(t);
- for(;;) {
- tsleep(&up->sleep, return0, nil, 1000);
- r = ds1620rdreg(Rtemp, 9);
- lock(t);
- t->cur = r;
- if(r < t->lo)
- t->lo = r;
- if(r > t->hi)
- t->hi = r;
- if(t->lo < t->alo)
- alarm(ALOTEMP, t);
- if(t->hi > t->ahi)
- alarm(AHITEMP, t);
- unlock(t);
- }
- pexit("", 0);
-}
-
-static void
-ds1620init(void)
-{
- int r;
-
- t.aq = qopen(8*1024, Qmsg, nil, nil);
- if(t.aq == nil)
- error(Enomem);
-
- ds1620wrreg(Rconfig, Ccpu, 8); // continuous sample mode
- ds1620cmd(Startconv);
- r = ds1620rdreg(Rtemp, 9);
- t.alo = ds1620rdreg(Rlo, 9);
- t.ahi = ds1620rdreg(Rhi, 9);
-
- print("#L: temp %s (c) ", t2s(r));
- print("low threshold %s (c) ", t2s(t.alo));
- print("high threshold %s (c)\n", t2s(t.ahi));
-
- kproc("tempmon", tmon, &t, 0);
-}
-
-static Chan*
-ds1620attach(char *spec)
-{
- return devattach('L', spec);
-}
-
-static int
-ds1620walk(Chan *c, char* name)
-{
- return devwalk(c, name, ds1620tab, nelem(ds1620tab), devgen);
-}
-
-static void
-ds1620stat(Chan *c, char* db)
-{
- ds1620tab[1].length = qlen(t.aq);
- devstat(c, db, ds1620tab, nelem(ds1620tab), devgen);
-}
-
-static Chan*
-ds1620open(Chan *c, int omode)
-{
- return devopen(c, omode, ds1620tab, nelem(ds1620tab), devgen);
-}
-
-static void
-ds1620close(Chan*)
-{
-}
-
-static long
-ds1620read(Chan *c, void *a, long n, vlong offset)
-{
- Temp tt;
- char buf[64];
- char *s;
- if(c->qid.path & CHDIR)
- return devdirread(c, a, n, ds1620tab, nelem(ds1620tab), devgen);
- buf[0] = 0;
- switch(c->qid.path) {
- case Qtemp:
- lock(&t);
- tt = t;
- unlock(&t);
- s = buf;
- s+= sprint(s, "%s ", t2s(tt.lo));
- s+= sprint(s, "%s ", t2s(tt.cur));
- s+= sprint(s, "%s ", t2s(tt.hi));
- s+= sprint(s, "%s ", t2s(tt.alo));
- sprint(s, "%s", t2s(tt.ahi));
- return readstr(offset, a, n, buf);
- case Qalarm:
- return qread(t.aq, a, n);
- default:
- error(Egreg);
- return 0;
- }
-}
-
-static long
-ds1620write(Chan *c, void *a, long n, vlong)
-{
- char buf[64];
- char *f[2];
- int lo, hi;
- int nf;
-
- if(c->qid.path & CHDIR)
- error(Eperm);
-
- if(c->qid.path == Qtemp) {
- if(n >= sizeof(buf))
- n = sizeof(buf)-1;
- memmove(buf, a, n);
- buf[n] = '\0';
- nf = getfields(buf, f, 2, 1, " \t");
- if(nf != 2)
- error(Ebadarg);
- lo = s2t(f[0]);
- hi = s2t(f[1]);
- lock(&t);
- t.alo = lo;
- t.ahi = hi;
- t.atime = 0;
- ds1620wrreg(Rlo, lo, 9);
- delay(1);
- ds1620wrreg(Rhi, hi, 9);
- unlock(&t);
- return n;
- } else
- error(Eio);
- return 0;
-
-}
-
-Dev ds1620devtab = {
- 'L',
- "ds1620",
- devreset,
- ds1620init,
- ds1620attach,
- devdetach,
- devclone,
- ds1620walk,
- ds1620stat,
- ds1620open,
- devcreate,
- ds1620close,
- ds1620read,
- devbread,
- ds1620write,
- devbwrite,
- devremove,
- devwstat,
-};
diff --git a/os/pc/devether.c b/os/pc/devether.c
deleted file mode 100644
index 4bdc693c..00000000
--- a/os/pc/devether.c
+++ /dev/null
@@ -1,539 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-static Ether *etherxx[MaxEther];
-
-Chan*
-etherattach(char* spec)
-{
- ulong ctlrno;
- char *p;
- Chan *chan;
-
- ctlrno = 0;
- if(spec && *spec){
- ctlrno = strtoul(spec, &p, 0);
- if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther))
- error(Ebadarg);
- }
- if(etherxx[ctlrno] == 0)
- error(Enodev);
-
- chan = devattach('l', spec);
- chan->dev = ctlrno;
- if(etherxx[ctlrno]->attach)
- etherxx[ctlrno]->attach(etherxx[ctlrno]);
- return chan;
-}
-
-static Walkqid*
-etherwalk(Chan* chan, Chan* nchan, char** name, int nname)
-{
- return netifwalk(etherxx[chan->dev], chan, nchan, name, nname);
-}
-
-static int
-etherstat(Chan* chan, uchar* dp, int n)
-{
- return netifstat(etherxx[chan->dev], chan, dp, n);
-}
-
-static Chan*
-etheropen(Chan* chan, int omode)
-{
- return netifopen(etherxx[chan->dev], chan, omode);
-}
-
-static void
-ethercreate(Chan*, char*, int, ulong)
-{
-}
-
-static void
-etherclose(Chan* chan)
-{
- netifclose(etherxx[chan->dev], chan);
-}
-
-static long
-etherread(Chan* chan, void* buf, long n, vlong off)
-{
- Ether *ether;
- ulong offset = off;
-
- ether = etherxx[chan->dev];
- if((chan->qid.type & QTDIR) == 0 && ether->ifstat){
- /*
- * With some controllers it is necessary to reach
- * into the chip to extract statistics.
- */
- if(NETTYPE(chan->qid.path) == Nifstatqid)
- return ether->ifstat(ether, buf, n, offset);
- else if(NETTYPE(chan->qid.path) == Nstatqid)
- ether->ifstat(ether, buf, 0, offset);
- }
-
- return netifread(ether, chan, buf, n, offset);
-}
-
-static Block*
-etherbread(Chan* chan, long n, ulong offset)
-{
- return netifbread(etherxx[chan->dev], chan, n, offset);
-}
-
-static int
-etherwstat(Chan* chan, uchar* dp, int n)
-{
- return netifwstat(etherxx[chan->dev], chan, dp, n);
-}
-
-static void
-etherrtrace(Netfile* f, Etherpkt* pkt, int len)
-{
- int i, n;
- Block *bp;
-
- if(qwindow(f->in) <= 0)
- return;
- if(len > 58)
- n = 58;
- else
- n = len;
- bp = iallocb(64);
- if(bp == nil)
- return;
- memmove(bp->wp, pkt->d, n);
- i = TK2MS(MACHP(0)->ticks);
- bp->wp[58] = len>>8;
- bp->wp[59] = len;
- bp->wp[60] = i>>24;
- bp->wp[61] = i>>16;
- bp->wp[62] = i>>8;
- bp->wp[63] = i;
- bp->wp += 64;
- qpass(f->in, bp);
-}
-
-Block*
-etheriq(Ether* ether, Block* bp, int fromwire)
-{
- Etherpkt *pkt;
- ushort type;
- int len, multi, tome, fromme;
- Netfile **ep, *f, **fp, *fx;
- Block *xbp;
-
- ether->inpackets++;
-
- pkt = (Etherpkt*)bp->rp;
- len = BLEN(bp);
- type = (pkt->type[0]<<8)|pkt->type[1];
- fx = 0;
- ep = &ether->f[Ntypes];
-
- multi = pkt->d[0] & 1;
- /* check for valid multcast addresses */
- if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){
- if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
- if(fromwire){
- freeb(bp);
- bp = 0;
- }
- return bp;
- }
- }
-
- /* is it for me? */
- tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
- fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
-
- /*
- * Multiplex the packet to all the connections which want it.
- * If the packet is not to be used subsequently (fromwire != 0),
- * attempt to simply pass it into one of the connections, thereby
- * saving a copy of the data (usual case hopefully).
- */
- for(fp = ether->f; fp < ep; fp++){
- if(f = *fp)
- if(f->type == type || f->type < 0)
- if(tome || multi || f->prom){
- /* Don't want to hear bridged packets */
- if(f->bridge && !fromwire && !fromme)
- continue;
- if(!f->headersonly){
- if(fromwire && fx == 0)
- fx = f;
- else if(xbp = iallocb(len)){
- memmove(xbp->wp, pkt, len);
- xbp->wp += len;
- if(qpass(f->in, xbp) < 0)
- ether->soverflows++;
- }
- else
- ether->soverflows++;
- }
- else
- etherrtrace(f, pkt, len);
- }
- }
-
- if(fx){
- if(qpass(fx->in, bp) < 0)
- ether->soverflows++;
- return 0;
- }
- if(fromwire){
- freeb(bp);
- return 0;
- }
-
- return bp;
-}
-
-static int
-etheroq(Ether* ether, Block* bp)
-{
- int len, loopback, s;
- Etherpkt *pkt;
-
- ether->outpackets++;
-
- /*
- * Check if the packet has to be placed back onto the input queue,
- * i.e. if it's a loopback or broadcast packet or the interface is
- * in promiscuous mode.
- * If it's a loopback packet indicate to etheriq that the data isn't
- * needed and return, etheriq will pass-on or free the block.
- * To enable bridging to work, only packets that were originated
- * by this interface are fed back.
- */
- pkt = (Etherpkt*)bp->rp;
- len = BLEN(bp);
- loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
- if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){
- s = splhi();
- etheriq(ether, bp, 0);
- splx(s);
- }
-
- if(!loopback){
- qbwrite(ether->oq, bp);
- if(ether->transmit != nil)
- ether->transmit(ether);
- } else
- freeb(bp);
-
- return len;
-}
-
-static long
-etherwrite(Chan* chan, void* buf, long n, vlong)
-{
- Ether *ether;
- Block *bp;
- int nn, onoff;
- Cmdbuf *cb;
-
- ether = etherxx[chan->dev];
- if(NETTYPE(chan->qid.path) != Ndataqid) {
- nn = netifwrite(ether, chan, buf, n);
- if(nn >= 0)
- return nn;
- cb = parsecmd(buf, n);
- if(strcmp(cb->f[0], "nonblocking") == 0){
- if(cb->nf <= 1)
- onoff = 1;
- else
- onoff = atoi(cb->f[1]);
- qnoblock(ether->oq, onoff);
- free(cb);
- return n;
- }
- free(cb);
- if(ether->ctl!=nil)
- return ether->ctl(ether,buf,n);
-
- error(Ebadctl);
- }
-
- if(n > ether->maxmtu)
- error(Etoobig);
- if(n < ether->minmtu)
- error(Etoosmall);
-
- bp = allocb(n);
- if(waserror()){
- freeb(bp);
- nexterror();
- }
- memmove(bp->rp, buf, n);
- memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
- poperror();
- bp->wp += n;
-
- return etheroq(ether, bp);
-}
-
-static long
-etherbwrite(Chan* chan, Block* bp, ulong)
-{
- Ether *ether;
- long n;
-
- n = BLEN(bp);
- if(NETTYPE(chan->qid.path) != Ndataqid){
- if(waserror()) {
- freeb(bp);
- nexterror();
- }
- n = etherwrite(chan, bp->rp, n, 0);
- poperror();
- freeb(bp);
- return n;
- }
- ether = etherxx[chan->dev];
-
- if(n > ether->maxmtu){
- freeb(bp);
- error(Etoobig);
- }
- if(n < ether->minmtu){
- freeb(bp);
- error(Etoosmall);
- }
-
- return etheroq(ether, bp);
-}
-
-static struct {
- char* type;
- int (*reset)(Ether*);
-} cards[MaxEther+1];
-
-void
-addethercard(char* t, int (*r)(Ether*))
-{
- static int ncard;
-
- if(ncard == MaxEther)
- panic("too many ether cards");
- cards[ncard].type = t;
- cards[ncard].reset = r;
- ncard++;
-}
-
-int
-parseether(uchar *to, char *from)
-{
- char nip[4];
- char *p;
- int i;
-
- p = from;
- for(i = 0; i < Eaddrlen; i++){
- if(*p == 0)
- return -1;
- nip[0] = *p++;
- if(*p == 0)
- return -1;
- nip[1] = *p++;
- nip[2] = 0;
- to[i] = strtoul(nip, 0, 16);
- if(*p == ':')
- p++;
- }
- return 0;
-}
-
-static Ether*
-etherprobe(int cardno, int ctlrno)
-{
- int i;
- Ether *ether;
- char buf[128], name[32];
-
- ether = malloc(sizeof(Ether));
- memset(ether, 0, sizeof(Ether));
- ether->ctlrno = ctlrno;
- ether->tbdf = BUSUNKNOWN;
- ether->mbps = 10;
- ether->minmtu = ETHERMINTU;
- ether->maxmtu = ETHERMAXTU;
-
- if(cardno < 0){
- if(isaconfig("ether", ctlrno, ether) == 0){
- free(ether);
- return nil;
- }
- for(cardno = 0; cards[cardno].type; cardno++){
- if(cistrcmp(cards[cardno].type, ether->type))
- continue;
- for(i = 0; i < ether->nopt; i++){
- if(strncmp(ether->opt[i], "ea=", 3))
- continue;
- if(parseether(ether->ea, &ether->opt[i][3]))
- memset(ether->ea, 0, Eaddrlen);
- }
- break;
- }
- }
-
- if(cardno >= MaxEther || cards[cardno].type == nil){
- free(ether);
- return nil;
- }
- if(cards[cardno].reset(ether) < 0){
- free(ether);
- return nil;
- }
-
- /*
- * IRQ2 doesn't really exist, it's used to gang the interrupt
- * controllers together. A device set to IRQ2 will appear on
- * the second interrupt controller as IRQ9.
- */
- if(ether->irq == 2)
- ether->irq = 9;
- snprint(name, sizeof(name), "ether%d", ctlrno);
-
- /*
- * If ether->irq is <0, it is a hack to indicate no interrupt
- * used by ethersink.
- */
- if(ether->irq >= 0)
- intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name);
-
- i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %d",
- ctlrno, cards[cardno].type, ether->mbps, ether->port, ether->irq);
- if(ether->mem)
- i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
- if(ether->size)
- i += sprint(buf+i, " size 0x%luX", ether->size);
- i += sprint(buf+i, ": %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
- ether->ea[0], ether->ea[1], ether->ea[2],
- ether->ea[3], ether->ea[4], ether->ea[5]);
- sprint(buf+i, "\n");
- print(buf);
-
- if (ether->mbps >= 1000) {
- netifinit(ether, name, Ntypes, 512*1024);
- if(ether->oq == 0)
- ether->oq = qopen(512*1024, Qmsg, 0, 0);
- } else if(ether->mbps >= 100){
- netifinit(ether, name, Ntypes, 256*1024);
- if(ether->oq == 0)
- ether->oq = qopen(256*1024, Qmsg, 0, 0);
- }
- else{
- netifinit(ether, name, Ntypes, 128*1024);
- if(ether->oq == 0)
- ether->oq = qopen(128*1024, Qmsg, 0, 0);
- }
- if(ether->oq == 0)
- panic("etherreset %s", name);
- ether->alen = Eaddrlen;
- memmove(ether->addr, ether->ea, Eaddrlen);
- memset(ether->bcast, 0xFF, Eaddrlen);
-
- return ether;
-}
-
-static void
-etherreset(void)
-{
- Ether *ether;
- int cardno, ctlrno;
-
- for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
- if((ether = etherprobe(-1, ctlrno)) == nil)
- continue;
- etherxx[ctlrno] = ether;
- }
-
- if(getconf("*noetherprobe"))
- return;
-
- cardno = ctlrno = 0;
- while(cards[cardno].type != nil && ctlrno < MaxEther){
- if(etherxx[ctlrno] != nil){
- ctlrno++;
- continue;
- }
- if((ether = etherprobe(cardno, ctlrno)) == nil){
- cardno++;
- continue;
- }
- etherxx[ctlrno] = ether;
- ctlrno++;
- }
-}
-
-static void
-ethershutdown(void)
-{
- Ether *ether;
- int i;
-
- for(i = 0; i < MaxEther; i++){
- ether = etherxx[i];
- if(ether == nil)
- continue;
- if(ether->shutdown == nil) {
- print("#l%d: no shutdown fuction\n", i);
- continue;
- }
- (*ether->shutdown)(ether);
- }
-}
-
-
-#define POLY 0xedb88320
-
-/* really slow 32 bit crc for ethers */
-ulong
-ethercrc(uchar *p, int len)
-{
- int i, j;
- ulong crc, b;
-
- crc = 0xffffffff;
- for(i = 0; i < len; i++){
- b = *p++;
- for(j = 0; j < 8; j++){
- crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0);
- b >>= 1;
- }
- }
- return crc;
-}
-
-Dev etherdevtab = {
- 'l',
- "ether",
-
- etherreset,
- devinit,
- ethershutdown,
- etherattach,
- etherwalk,
- etherstat,
- etheropen,
- ethercreate,
- etherclose,
- etherread,
- etherbread,
- etherwrite,
- etherbwrite,
- devremove,
- etherwstat,
-};
diff --git a/os/pc/devfloppy.c b/os/pc/devfloppy.c
deleted file mode 100644
index 2f29147c..00000000
--- a/os/pc/devfloppy.c
+++ /dev/null
@@ -1,1082 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#include "floppy.h"
-
-/* Intel 82077A (8272A compatible) floppy controller */
-
-/* This module expects the following functions to be defined
- * elsewhere:
- *
- * inb()
- * outb()
- * floppyexec()
- * floppyeject()
- * floppysetup0()
- * floppysetup1()
- * dmainit()
- * dmasetup()
- * dmaend()
- *
- * On DMA systems, floppyexec() should be an empty function;
- * on non-DMA systems, dmaend() should be an empty function;
- * dmasetup() may enforce maximum transfer sizes.
- */
-
-enum {
- /* file types */
- Qdir= 0,
- Qdata= (1<<2),
- Qctl= (2<<2),
- Qmask= (3<<2),
-
- DMAchan= 2, /* floppy dma channel */
-};
-
-#define DPRINT if(floppydebug)print
-int floppydebug = 0;
-
-/*
- * types of drive (from PC equipment byte)
- */
-enum
-{
- Tnone= 0,
- T360kb= 1,
- T1200kb= 2,
- T720kb= 3,
- T1440kb= 4,
-};
-
-FType floppytype[] =
-{
- { "3½HD", T1440kb, 512, 18, 2, 1, 80, 0x1B, 0x54, 0, },
- { "3½DD", T1440kb, 512, 9, 2, 1, 80, 0x1B, 0x54, 2, },
- { "3½DD", T720kb, 512, 9, 2, 1, 80, 0x1B, 0x54, 2, },
- { "5¼HD", T1200kb, 512, 15, 2, 1, 80, 0x2A, 0x50, 0, },
- { "5¼DD", T1200kb, 512, 9, 2, 2, 40, 0x2A, 0x50, 1, },
- { "ATT3B1", T1200kb, 512, 8, 2, 2, 48, 0x2A, 0x50, 1, },
- { "5¼DD", T360kb, 512, 9, 2, 1, 40, 0x2A, 0x50, 2, },
-};
-
-/*
- * bytes per sector encoding for the controller.
- * - index for b2c is is (bytes per sector/128).
- * - index for c2b is code from b2c
- */
-static int b2c[] =
-{
-[1] 0,
-[2] 1,
-[4] 2,
-[8] 3,
-};
-static int c2b[] =
-{
- 128,
- 256,
- 512,
- 1024,
-};
-
-FController fl;
-
-#define MOTORBIT(i) (1<<((i)+4))
-
-/*
- * predeclared
- */
-static int cmddone(void*);
-static void floppyformat(FDrive*, Cmdbuf*);
-static void floppykproc(void*);
-static void floppypos(FDrive*,long);
-static int floppyrecal(FDrive*);
-static int floppyresult(void);
-static void floppyrevive(void);
-static long floppyseek(FDrive*, long);
-static int floppysense(void);
-static void floppywait(int);
-static long floppyxfer(FDrive*, int, void*, long, long);
-
-Dirtab floppydir[]={
- ".", {Qdir, 0, QTDIR}, 0, 0550,
- "fd0disk", {Qdata + 0}, 0, 0660,
- "fd0ctl", {Qctl + 0}, 0, 0660,
- "fd1disk", {Qdata + 1}, 0, 0660,
- "fd1ctl", {Qctl + 1}, 0, 0660,
- "fd2disk", {Qdata + 2}, 0, 0660,
- "fd2ctl", {Qctl + 2}, 0, 0660,
- "fd3disk", {Qdata + 3}, 0, 0660,
- "fd3ctl", {Qctl + 3}, 0, 0660,
-};
-#define NFDIR 2 /* directory entries/drive */
-
-enum
-{
- CMdebug,
- CMnodebug,
- CMeject,
- CMformat,
- CMreset,
-};
-
-static Cmdtab floppyctlmsg[] =
-{
- CMdebug, "debug", 1,
- CMnodebug, "nodebug", 1,
- CMeject, "eject", 1,
- CMformat, "format", 0,
- CMreset, "reset", 1,
-};
-
-static void
-fldump(void)
-{
- DPRINT("sra %ux srb %ux dor %ux msr %ux dir %ux\n", inb(Psra), inb(Psrb),
- inb(Pdor), inb(Pmsr), inb(Pdir));
-}
-
-/*
- * set floppy drive to its default type
- */
-static void
-floppysetdef(FDrive *dp)
-{
- FType *t;
-
- for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++)
- if(dp->dt == t->dt){
- dp->t = t;
- floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
- break;
- }
-}
-
-static void
-floppyreset(void)
-{
- FDrive *dp;
- FType *t;
- ulong maxtsize;
-
- floppysetup0(&fl);
- if(fl.ndrive == 0)
- return;
-
- /*
- * init dependent parameters
- */
- maxtsize = 0;
- for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
- t->cap = t->bytes * t->heads * t->sectors * t->tracks;
- t->bcode = b2c[t->bytes/128];
- t->tsize = t->bytes * t->sectors;
- if(maxtsize < t->tsize)
- maxtsize = t->tsize;
- }
-
- dmainit(DMAchan, maxtsize);
-
- /*
- * allocate the drive storage
- */
- fl.d = xalloc(fl.ndrive*sizeof(FDrive));
- fl.selected = fl.d;
-
- /*
- * stop the motors
- */
- fl.motor = 0;
- delay(10);
- outb(Pdor, fl.motor | Fintena | Fena);
- delay(10);
-
- /*
- * init drives
- */
- for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
- dp->dev = dp - fl.d;
- dp->dt = T1440kb;
- floppysetdef(dp);
- dp->cyl = -1; /* because we don't know */
- dp->cache = (uchar*)xspanalloc(maxtsize, BY2PG, 64*1024);
- dp->ccyl = -1;
- dp->vers = 0;
- }
-
- /*
- * first operation will recalibrate
- */
- fl.confused = 1;
-
- floppysetup1(&fl);
-}
-
-static Chan*
-floppyattach(char *spec)
-{
- static int kstarted;
-
- if(fl.ndrive == 0)
- error(Enodev);
-
- if(kstarted == 0){
- /*
- * watchdog to turn off the motors
- */
- kstarted = 1;
- kproc("floppy", floppykproc, 0, 0);
- }
- return devattach('f', spec);
-}
-
-static Walkqid*
-floppywalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, floppydir, 1+fl.ndrive*NFDIR, devgen);
-}
-
-static int
-floppystat(Chan *c, uchar *dp, int n)
-{
- return devstat(c, dp, n, floppydir, 1+fl.ndrive*NFDIR, devgen);
-}
-
-static Chan*
-floppyopen(Chan *c, int omode)
-{
- return devopen(c, omode, floppydir, 1+fl.ndrive*NFDIR, devgen);
-}
-
-static void
-floppyclose(Chan *)
-{
-}
-
-static void
-islegal(ulong offset, long n, FDrive *dp)
-{
- if(offset % dp->t->bytes)
- error(Ebadarg);
- if(n % dp->t->bytes)
- error(Ebadarg);
-}
-
-/*
- * check if the floppy has been replaced under foot. cause
- * an error if it has.
- *
- * a seek and a read clears the condition. this was determined
- * experimentally, there has to be a better way.
- *
- * if the read fails, cycle through the possible floppy
- * density till one works or we've cycled through all
- * possibilities for this drive.
- */
-static void
-changed(Chan *c, FDrive *dp)
-{
- ulong old;
- FType *start;
-
- /*
- * if floppy has changed or first time through
- */
- if((inb(Pdir)&Fchange) || dp->vers == 0){
- DPRINT("changed\n");
- fldump();
- dp->vers++;
- start = dp->t;
- dp->maxtries = 3; /* limit it when we're probing */
-
- /* floppyon will fail if there's a controller but no drive */
- dp->confused = 1; /* make floppyon recal */
- if(floppyon(dp) < 0)
- error(Eio);
-
- /* seek to the first track */
- floppyseek(dp, dp->t->heads*dp->t->tsize);
- while(waserror()){
- /*
- * if first attempt doesn't reset changed bit, there's
- * no floppy there
- */
- if(inb(Pdir)&Fchange)
- nexterror();
-
- while(++dp->t){
- if(dp->t == &floppytype[nelem(floppytype)])
- dp->t = floppytype;
- if(dp->dt == dp->t->dt)
- break;
- }
- floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
-
- /* floppyon will fail if there's a controller but no drive */
- if(floppyon(dp) < 0)
- error(Eio);
-
- DPRINT("changed: trying %s\n", dp->t->name);
- fldump();
- if(dp->t == start)
- nexterror();
- }
-
- /* if the read succeeds, we've got the density right */
- floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize);
- poperror();
- dp->maxtries = 20;
- }
-
- old = c->qid.vers;
- c->qid.vers = dp->vers;
- if(old && old != dp->vers)
- error(Eio);
-}
-
-static int
-readtrack(FDrive *dp, int cyl, int head)
-{
- int i, nn, sofar;
- ulong pos;
-
- nn = dp->t->tsize;
- if(dp->ccyl==cyl && dp->chead==head)
- return nn;
- pos = (cyl*dp->t->heads+head) * nn;
- for(sofar = 0; sofar < nn; sofar += i){
- dp->ccyl = -1;
- i = floppyxfer(dp, Fread, dp->cache + sofar, pos + sofar, nn - sofar);
- if(i <= 0)
- return -1;
- }
- dp->ccyl = cyl;
- dp->chead = head;
- return nn;
-}
-
-static long
-floppyread(Chan *c, void *a, long n, vlong off)
-{
- FDrive *dp;
- long rv;
- int sec, head, cyl;
- long len;
- uchar *aa;
- ulong offset = off;
-
- if(c->qid.type & QTDIR)
- return devdirread(c, a, n, floppydir, 1+fl.ndrive*NFDIR, devgen);
-
- rv = 0;
- dp = &fl.d[c->qid.path & ~Qmask];
- switch ((int)(c->qid.path & Qmask)) {
- case Qdata:
- islegal(offset, n, dp);
- aa = a;
-
- qlock(&fl);
- if(waserror()){
- qunlock(&fl);
- nexterror();
- }
- floppyon(dp);
- changed(c, dp);
- for(rv = 0; rv < n; rv += len){
- /*
- * all xfers come out of the track cache
- */
- dp->len = n - rv;
- floppypos(dp, offset+rv);
- cyl = dp->tcyl;
- head = dp->thead;
- len = dp->len;
- sec = dp->tsec;
- if(readtrack(dp, cyl, head) < 0)
- break;
- memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
- }
- qunlock(&fl);
- poperror();
-
- break;
- case Qctl:
- return readstr(offset, a, n, dp->t->name);
- default:
- panic("floppyread: bad qid");
- }
-
- return rv;
-}
-
-static long
-floppywrite(Chan *c, void *a, long n, vlong off)
-{
- FDrive *dp;
- long rv, i;
- char *aa = a;
- Cmdbuf *cb;
- Cmdtab *ct;
- ulong offset = off;
-
- rv = 0;
- dp = &fl.d[c->qid.path & ~Qmask];
- switch ((int)(c->qid.path & Qmask)) {
- case Qdata:
- islegal(offset, n, dp);
- qlock(&fl);
- if(waserror()){
- qunlock(&fl);
- nexterror();
- }
- floppyon(dp);
- changed(c, dp);
- for(rv = 0; rv < n; rv += i){
- floppypos(dp, offset+rv);
- if(dp->tcyl == dp->ccyl)
- dp->ccyl = -1;
- i = floppyxfer(dp, Fwrite, aa+rv, offset+rv, n-rv);
- if(i < 0)
- break;
- if(i == 0)
- error(Eio);
- }
- qunlock(&fl);
- poperror();
- break;
- case Qctl:
- rv = n;
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
- qlock(&fl);
- if(waserror()){
- qunlock(&fl);
- nexterror();
- }
- ct = lookupcmd(cb, floppyctlmsg, nelem(floppyctlmsg));
- switch(ct->index){
- case CMeject:
- floppyeject(dp);
- break;
- case CMformat:
- floppyformat(dp, cb);
- break;
- case CMreset:
- fl.confused = 1;
- floppyon(dp);
- break;
- case CMdebug:
- floppydebug = 1;
- break;
- case CMnodebug:
- floppydebug = 0;
- break;
- }
- poperror();
- qunlock(&fl);
- poperror();
- free(cb);
- break;
- default:
- panic("floppywrite: bad qid");
- }
-
- return rv;
-}
-
-static void
-floppykproc(void *)
-{
- FDrive *dp;
-
- while(waserror())
- ;
- for(;;){
- for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
- if((fl.motor&MOTORBIT(dp->dev))
- && TK2SEC(m->ticks - dp->lasttouched) > 5
- && canqlock(&fl)){
- if(TK2SEC(m->ticks - dp->lasttouched) > 5)
- floppyoff(dp);
- qunlock(&fl);
- }
- }
- tsleep(&up->sleep, return0, 0, 1000);
- }
-}
-
-/*
- * start a floppy drive's motor.
- */
-static int
-floppyon(FDrive *dp)
-{
- int alreadyon;
- int tries;
-
- if(fl.confused)
- floppyrevive();
-
- /* start motor and select drive */
- alreadyon = fl.motor & MOTORBIT(dp->dev);
- fl.motor |= MOTORBIT(dp->dev);
- outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
- if(!alreadyon){
- /* wait for drive to spin up */
- tsleep(&up->sleep, return0, 0, 750);
-
- /* clear any pending interrupts */
- floppysense();
- }
-
- /* set transfer rate */
- if(fl.rate != dp->t->rate){
- fl.rate = dp->t->rate;
- outb(Pdsr, fl.rate);
- }
-
- /* get drive to a known cylinder */
- if(dp->confused)
- for(tries = 0; tries < 4; tries++)
- if(floppyrecal(dp) >= 0)
- break;
- dp->lasttouched = m->ticks;
- fl.selected = dp;
-
- /* return -1 if this didn't work */
- if(dp->confused)
- return -1;
- return 0;
-}
-
-/*
- * stop the floppy if it hasn't been used in 5 seconds
- */
-static void
-floppyoff(FDrive *dp)
-{
- fl.motor &= ~MOTORBIT(dp->dev);
- outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
-}
-
-/*
- * send a command to the floppy
- */
-static int
-floppycmd(void)
-{
- int i;
- int tries;
-
- fl.nstat = 0;
- for(i = 0; i < fl.ncmd; i++){
- for(tries = 0; ; tries++){
- if((inb(Pmsr)&(Ffrom|Fready)) == Fready)
- break;
- if(tries > 1000){
- DPRINT("cmd %ux can't be sent (%d)\n", fl.cmd[0], i);
- fldump();
-
- /* empty fifo, might have been a bad command */
- floppyresult();
- return -1;
- }
- microdelay(8); /* for machine independence */
- }
- outb(Pfdata, fl.cmd[i]);
- }
- return 0;
-}
-
-/*
- * get a command result from the floppy
- *
- * when the controller goes ready waiting for a command
- * (instead of sending results), we're done
- *
- */
-static int
-floppyresult(void)
-{
- int i, s;
- int tries;
-
- /* get the result of the operation */
- for(i = 0; i < sizeof(fl.stat); i++){
- /* wait for status byte */
- for(tries = 0; ; tries++){
- s = inb(Pmsr)&(Ffrom|Fready);
- if(s == Fready){
- fl.nstat = i;
- return fl.nstat;
- }
- if(s == (Ffrom|Fready))
- break;
- if(tries > 1000){
- DPRINT("floppyresult: %d stats\n", i);
- fldump();
- fl.confused = 1;
- return -1;
- }
- microdelay(8); /* for machine independence */
- }
- fl.stat[i] = inb(Pfdata);
- }
- fl.nstat = sizeof(fl.stat);
- return fl.nstat;
-}
-
-/*
- * calculate physical address of a logical byte offset into the disk
- *
- * truncate dp->length if it crosses a track boundary
- */
-static void
-floppypos(FDrive *dp, long off)
-{
- int lsec;
- int ltrack;
- int end;
-
- lsec = off/dp->t->bytes;
- ltrack = lsec/dp->t->sectors;
- dp->tcyl = ltrack/dp->t->heads;
- dp->tsec = (lsec % dp->t->sectors) + 1;
- dp->thead = (lsec/dp->t->sectors) % dp->t->heads;
-
- /*
- * can't read across track boundaries.
- * if so, decrement the bytes to be read.
- */
- end = (ltrack+1)*dp->t->sectors*dp->t->bytes;
- if(off+dp->len > end)
- dp->len = end - off;
-}
-
-/*
- * get the interrupt cause from the floppy.
- */
-static int
-floppysense(void)
-{
- fl.ncmd = 0;
- fl.cmd[fl.ncmd++] = Fsense;
- if(floppycmd() < 0)
- return -1;
- if(floppyresult() < 2){
- DPRINT("can't read sense response\n");
- fldump();
- fl.confused = 1;
- return -1;
- }
- return 0;
-}
-
-static int
-cmddone(void *)
-{
- return fl.ncmd == 0;
-}
-
-/*
- * Wait for a floppy interrupt. If none occurs in 5 seconds, we
- * may have missed one. This only happens on some portables which
- * do power management behind our backs. Call the interrupt
- * routine to try to clear any conditions.
- */
-static void
-floppywait(int slow)
-{
- tsleep(&fl.r, cmddone, 0, slow ? 5000 : 1000);
- if(!cmddone(0)){
- floppyintr(0);
- fl.confused = 1;
- }
-}
-
-/*
- * we've lost the floppy position, go to cylinder 0.
- */
-static int
-floppyrecal(FDrive *dp)
-{
- dp->ccyl = -1;
- dp->cyl = -1;
-
- fl.ncmd = 0;
- fl.cmd[fl.ncmd++] = Frecal;
- fl.cmd[fl.ncmd++] = dp->dev;
- if(floppycmd() < 0)
- return -1;
- floppywait(1);
- if(fl.nstat < 2){
- DPRINT("recalibrate: confused %ux\n", inb(Pmsr));
- fl.confused = 1;
- return -1;
- }
- if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
- DPRINT("recalibrate: failed\n");
- dp->confused = 1;
- return -1;
- }
- dp->cyl = fl.stat[1];
- if(dp->cyl != 0){
- DPRINT("recalibrate: wrong cylinder %d\n", dp->cyl);
- dp->cyl = -1;
- dp->confused = 1;
- return -1;
- }
-
- dp->confused = 0;
- return 0;
-}
-
-/*
- * if the controller or a specific drive is in a confused state,
- * reset it and get back to a known state
- */
-static void
-floppyrevive(void)
-{
- FDrive *dp;
-
- /*
- * reset the controller if it's confused
- */
- if(fl.confused){
- DPRINT("floppyrevive in\n");
- fldump();
-
- /* reset controller and turn all motors off */
- splhi();
- fl.ncmd = 1;
- fl.cmd[0] = 0;
- outb(Pdor, 0);
- delay(10);
- outb(Pdor, Fintena|Fena);
- delay(10);
- spllo();
- fl.motor = 0;
- fl.confused = 0;
- floppywait(0);
-
- /* mark all drives in an unknown state */
- for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++)
- dp->confused = 1;
-
- /* set rate to a known value */
- outb(Pdsr, 0);
- fl.rate = 0;
-
- DPRINT("floppyrevive out\n");
- fldump();
- }
-}
-
-/*
- * seek to the target cylinder
- *
- * interrupt, no results
- */
-static long
-floppyseek(FDrive *dp, long off)
-{
- floppypos(dp, off);
- if(dp->cyl == dp->tcyl)
- return dp->tcyl;
- dp->cyl = -1;
-
- fl.ncmd = 0;
- fl.cmd[fl.ncmd++] = Fseek;
- fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
- fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
- if(floppycmd() < 0)
- return -1;
- floppywait(1);
- if(fl.nstat < 2){
- DPRINT("seek: confused\n");
- fl.confused = 1;
- return -1;
- }
- if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
- DPRINT("seek: failed\n");
- dp->confused = 1;
- return -1;
- }
-
- dp->cyl = dp->tcyl;
- return dp->tcyl;
-}
-
-/*
- * read or write to floppy. try up to three times.
- */
-static long
-floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
-{
- long offset;
- int tries;
-
- if(off >= dp->t->cap)
- return 0;
- if(off + n > dp->t->cap)
- n = dp->t->cap - off;
-
- /* retry on error (until it gets ridiculous) */
- tries = 0;
- while(waserror()){
- if(tries++ >= dp->maxtries)
- nexterror();
- DPRINT("floppyxfer: retrying\n");
- }
-
- dp->len = n;
- if(floppyseek(dp, off) < 0){
- DPRINT("xfer: seek failed\n");
- dp->confused = 1;
- error(Eio);
- }
-
- /*
- * set up the dma (dp->len may be trimmed)
- */
- if(waserror()){
- dmaend(DMAchan);
- nexterror();
- }
- dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread);
- if(dp->len < 0)
- error(Eio);
-
- /*
- * start operation
- */
- fl.ncmd = 0;
- fl.cmd[fl.ncmd++] = cmd | (dp->t->heads > 1 ? Fmulti : 0);
- fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
- fl.cmd[fl.ncmd++] = dp->tcyl;
- fl.cmd[fl.ncmd++] = dp->thead;
- fl.cmd[fl.ncmd++] = dp->tsec;
- fl.cmd[fl.ncmd++] = dp->t->bcode;
- fl.cmd[fl.ncmd++] = dp->t->sectors;
- fl.cmd[fl.ncmd++] = dp->t->gpl;
- fl.cmd[fl.ncmd++] = 0xFF;
- if(floppycmd() < 0)
- error(Eio);
-
- /* Poll ready bits and transfer data */
- floppyexec((char*)a, dp->len, cmd==Fread);
-
- /*
- * give bus to DMA, floppyintr() will read result
- */
- floppywait(0);
- dmaend(DMAchan);
- poperror();
-
- /*
- * check for errors
- */
- if(fl.nstat < 7){
- DPRINT("xfer: confused\n");
- fl.confused = 1;
- error(Eio);
- }
- if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){
- DPRINT("xfer: failed %ux %ux %ux\n", fl.stat[0],
- fl.stat[1], fl.stat[2]);
- DPRINT("offset %lud len %ld\n", off, dp->len);
- if((fl.stat[0]&Codemask)==Cmdexec && fl.stat[1]==Overrun){
- DPRINT("DMA overrun: retry\n");
- } else
- dp->confused = 1;
- error(Eio);
- }
-
- /*
- * check for correct cylinder
- */
- offset = fl.stat[3] * dp->t->heads + fl.stat[4];
- offset = offset*dp->t->sectors + fl.stat[5] - 1;
- offset = offset * c2b[fl.stat[6]];
- if(offset != off+dp->len){
- DPRINT("xfer: ends on wrong cyl\n");
- dp->confused = 1;
- error(Eio);
- }
- poperror();
-
- dp->lasttouched = m->ticks;
- return dp->len;
-}
-
-/*
- * format a track
- */
-static void
-floppyformat(FDrive *dp, Cmdbuf *cb)
-{
- int cyl, h, sec;
- ulong track;
- uchar *buf, *bp;
- FType *t;
-
- /*
- * set the type
- */
- if(cb->nf == 2){
- for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
- if(strcmp(cb->f[1], t->name)==0 && t->dt==dp->dt){
- dp->t = t;
- floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
- break;
- }
- }
- if(t >= &floppytype[nelem(floppytype)])
- error(Ebadarg);
- } else if(cb->nf == 1){
- floppysetdef(dp);
- t = dp->t;
- } else {
- cmderror(cb, "invalid floppy format command");
- SET(t);
- }
-
- /*
- * buffer for per track info
- */
- buf = smalloc(t->sectors*4);
- if(waserror()){
- free(buf);
- nexterror();
- }
-
- /* force a recalibrate to cylinder 0 */
- dp->confused = 1;
- if(!waserror()){
- floppyon(dp);
- poperror();
- }
-
- /*
- * format a track at time
- */
- for(track = 0; track < t->tracks*t->heads; track++){
- cyl = track/t->heads;
- h = track % t->heads;
-
- /*
- * seek to track, ignore errors
- */
- floppyseek(dp, track*t->tsize);
- dp->cyl = cyl;
- dp->confused = 0;
-
- /*
- * set up the dma (dp->len may be trimmed)
- */
- bp = buf;
- for(sec = 1; sec <= t->sectors; sec++){
- *bp++ = cyl;
- *bp++ = h;
- *bp++ = sec;
- *bp++ = t->bcode;
- }
- if(waserror()){
- dmaend(DMAchan);
- nexterror();
- }
- if(dmasetup(DMAchan, buf, bp-buf, 0) < 0)
- error(Eio);
-
- /*
- * start operation
- */
- fl.ncmd = 0;
- fl.cmd[fl.ncmd++] = Fformat;
- fl.cmd[fl.ncmd++] = (h<<2) | dp->dev;
- fl.cmd[fl.ncmd++] = t->bcode;
- fl.cmd[fl.ncmd++] = t->sectors;
- fl.cmd[fl.ncmd++] = t->fgpl;
- fl.cmd[fl.ncmd++] = 0x5a;
- if(floppycmd() < 0)
- error(Eio);
-
- /* Poll ready bits and transfer data */
- floppyexec((char *)buf, bp-buf, 0);
-
- /*
- * give bus to DMA, floppyintr() will read result
- */
- floppywait(1);
- dmaend(DMAchan);
- poperror();
-
- /*
- * check for errors
- */
- if(fl.nstat < 7){
- DPRINT("format: confused\n");
- fl.confused = 1;
- error(Eio);
- }
- if((fl.stat[0]&Codemask)!=0 || fl.stat[1]|| fl.stat[2]){
- DPRINT("format: failed %ux %ux %ux\n",
- fl.stat[0], fl.stat[1], fl.stat[2]);
- dp->confused = 1;
- error(Eio);
- }
- }
- free(buf);
- dp->confused = 1;
- poperror();
-}
-
-static void
-floppyintr(Ureg *)
-{
- switch(fl.cmd[0]&~Fmulti){
- case Fread:
- case Fwrite:
- case Fformat:
- case Fdumpreg:
- floppyresult();
- break;
- case Fseek:
- case Frecal:
- default:
- floppysense(); /* to clear interrupt */
- break;
- }
- fl.ncmd = 0;
- wakeup(&fl.r);
-}
-
-Dev floppydevtab = {
- 'f',
- "floppy",
-
- floppyreset,
- devinit,
- devshutdown,
- floppyattach,
- floppywalk,
- floppystat,
- floppyopen,
- devcreate,
- floppyclose,
- floppyread,
- devbread,
- floppywrite,
- devbwrite,
- devremove,
- devwstat,
-};
diff --git a/os/pc/devi82365.c b/os/pc/devi82365.c
deleted file mode 100644
index 5c67847f..00000000
--- a/os/pc/devi82365.c
+++ /dev/null
@@ -1,1044 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-/*
- * Intel 82365SL PCIC controller and compatibles.
- */
-enum
-{
- /*
- * registers indices
- */
- Rid= 0x0, /* identification and revision */
- Ris= 0x1, /* interface status */
- Rpc= 0x2, /* power control */
- Foutena= (1<<7), /* output enable */
- Fautopower= (1<<5), /* automatic power switching */
- Fcardena= (1<<4), /* PC card enable */
- Rigc= 0x3, /* interrupt and general control */
- Fiocard= (1<<5), /* I/O card (vs memory) */
- Fnotreset= (1<<6), /* reset if not set */
- FSMIena= (1<<4), /* enable change interrupt on SMI */
- Rcsc= 0x4, /* card status change */
- Rcscic= 0x5, /* card status change interrupt config */
- Fchangeena= (1<<3), /* card changed */
- Fbwarnena= (1<<1), /* card battery warning */
- Fbdeadena= (1<<0), /* card battery dead */
- Rwe= 0x6, /* address window enable */
- Fmem16= (1<<5), /* use A23-A12 to decode address */
- Rio= 0x7, /* I/O control */
- Fwidth16= (1<<0), /* 16 bit data width */
- Fiocs16= (1<<1), /* IOCS16 determines data width */
- Fzerows= (1<<2), /* zero wait state */
- Ftiming= (1<<3), /* timing register to use */
- Riobtm0lo= 0x8, /* I/O address 0 start low byte */
- Riobtm0hi= 0x9, /* I/O address 0 start high byte */
- Riotop0lo= 0xa, /* I/O address 0 stop low byte */
- Riotop0hi= 0xb, /* I/O address 0 stop high byte */
- Riobtm1lo= 0xc, /* I/O address 1 start low byte */
- Riobtm1hi= 0xd, /* I/O address 1 start high byte */
- Riotop1lo= 0xe, /* I/O address 1 stop low byte */
- Riotop1hi= 0xf, /* I/O address 1 stop high byte */
- Rmap= 0x10, /* map 0 */
-
- /*
- * CL-PD67xx extension registers
- */
- Rmisc1= 0x16, /* misc control 1 */
- F5Vdetect= (1<<0),
- Fvcc3V= (1<<1),
- Fpmint= (1<<2),
- Fpsirq= (1<<3),
- Fspeaker= (1<<4),
- Finpack= (1<<7),
- Rfifo= 0x17, /* fifo control */
- Fflush= (1<<7), /* flush fifo */
- Rmisc2= 0x1E, /* misc control 2 */
- Flowpow= (1<<1), /* low power mode */
- Rchipinfo= 0x1F, /* chip information */
- Ratactl= 0x26, /* ATA control */
-
- /*
- * offsets into the system memory address maps
- */
- Mbtmlo= 0x0, /* System mem addr mapping start low byte */
- Mbtmhi= 0x1, /* System mem addr mapping start high byte */
- F16bit= (1<<7), /* 16-bit wide data path */
- Mtoplo= 0x2, /* System mem addr mapping stop low byte */
- Mtophi= 0x3, /* System mem addr mapping stop high byte */
- Ftimer1= (1<<6), /* timer set 1 */
- Mofflo= 0x4, /* Card memory offset address low byte */
- Moffhi= 0x5, /* Card memory offset address high byte */
- Fregactive= (1<<6), /* attribute memory */
-
- /*
- * configuration registers - they start at an offset in attribute
- * memory found in the CIS.
- */
- Rconfig= 0,
- Creset= (1<<7), /* reset device */
- Clevel= (1<<6), /* level sensitive interrupt line */
- Cirq= (1<<2), /* IRQ enable */
- Cdecode= (1<<1), /* address decode */
- Cfunc= (1<<0), /* function enable */
- Riobase0= 5,
- Riobase1= 6,
- Riosize= 9,
-};
-
-#define MAP(x,o) (Rmap + (x)*0x8 + o)
-
-typedef struct I82365 I82365;
-
-/* a controller */
-enum
-{
- Ti82365,
- Tpd6710,
- Tpd6720,
- Tvg46x,
-};
-struct I82365
-{
- int type;
- int dev;
- int nslot;
- int xreg; /* index register address */
- int dreg; /* data register address */
- int irq;
-};
-static I82365 *controller[4];
-static int ncontroller;
-static PCMslot *slot;
-static PCMslot *lastslot;
-static nslot;
-
-static void i82365intr(Ureg*, void*);
-static int pcmio(int, ISAConf*);
-static long pcmread(int, int, void*, long, vlong);
-static long pcmwrite(int, int, void*, long, vlong);
-
-static void i82365dump(PCMslot*);
-
-/*
- * reading and writing card registers
- */
-static uchar
-rdreg(PCMslot *pp, int index)
-{
- outb(((I82365*)pp->cp)->xreg, pp->base + index);
- return inb(((I82365*)pp->cp)->dreg);
-}
-static void
-wrreg(PCMslot *pp, int index, uchar val)
-{
- outb(((I82365*)pp->cp)->xreg, pp->base + index);
- outb(((I82365*)pp->cp)->dreg, val);
-}
-
-/*
- * get info about card
- */
-static void
-slotinfo(PCMslot *pp)
-{
- uchar isr;
-
- isr = rdreg(pp, Ris);
- pp->occupied = (isr & (3<<2)) == (3<<2);
- pp->powered = isr & (1<<6);
- pp->battery = (isr & 3) == 3;
- pp->wrprot = isr & (1<<4);
- pp->busy = isr & (1<<5);
- pp->msec = TK2MS(MACHP(0)->ticks);
-}
-
-static int
-vcode(int volt)
-{
- switch(volt){
- case 5:
- return 1;
- case 12:
- return 2;
- default:
- return 0;
- }
-}
-
-/*
- * enable the slot card
- */
-static void
-slotena(PCMslot *pp)
-{
- if(pp->enabled)
- return;
-
- /* power up and unreset, wait's are empirical (???) */
- wrreg(pp, Rpc, Fautopower|Foutena|Fcardena);
- delay(300);
- wrreg(pp, Rigc, 0);
- delay(100);
- wrreg(pp, Rigc, Fnotreset);
- delay(5000);
-
- /* get configuration */
- slotinfo(pp);
- if(pp->occupied){
- pcmcisread(pp);
- pp->enabled = 1;
- } else
- wrreg(pp, Rpc, Fautopower);
-}
-
-/*
- * disable the slot card
- */
-static void
-slotdis(PCMslot *pp)
-{
- wrreg(pp, Rpc, 0); /* turn off card power */
- wrreg(pp, Rwe, 0); /* no windows */
- pp->enabled = 0;
-}
-
-/*
- * status change interrupt
- */
-static void
-i82365intr(Ureg *, void *)
-{
- uchar csc, was;
- PCMslot *pp;
-
- if(slot == 0)
- return;
-
- for(pp = slot; pp < lastslot; pp++){
- csc = rdreg(pp, Rcsc);
- was = pp->occupied;
- slotinfo(pp);
- if(csc & (1<<3) && was != pp->occupied){
- if(!pp->occupied)
- slotdis(pp);
- }
- }
-}
-
-enum
-{
- Mshift= 12,
- Mgran= (1<<Mshift), /* granularity of maps */
- Mmask= ~(Mgran-1), /* mask for address bits important to the chip */
-};
-
-/*
- * get a map for pc card region, return corrected len
- */
-PCMmap*
-pcmmap(int slotno, ulong offset, int len, int attr)
-{
- PCMslot *pp;
- uchar we, bit;
- PCMmap *m, *nm;
- int i;
- ulong e;
-
- pp = slot + slotno;
- lock(&pp->mlock);
-
- /* convert offset to granularity */
- if(len <= 0)
- len = 1;
- e = ROUND(offset+len, Mgran);
- offset &= Mmask;
- len = e - offset;
-
- /* look for a map that covers the right area */
- we = rdreg(pp, Rwe);
- bit = 1;
- nm = 0;
- for(m = pp->mmap; m < &pp->mmap[nelem(pp->mmap)]; m++){
- if((we & bit))
- if(m->attr == attr)
- if(offset >= m->ca && e <= m->cea){
-
- m->ref++;
- unlock(&pp->mlock);
- return m;
- }
- bit <<= 1;
- if(nm == 0 && m->ref == 0)
- nm = m;
- }
- m = nm;
- if(m == 0){
- unlock(&pp->mlock);
- return 0;
- }
-
- /* if isa space isn't big enough, free it and get more */
- if(m->len < len){
- if(m->isa){
- umbfree(m->isa, m->len);
- m->len = 0;
- }
- m->isa = PADDR(umbmalloc(0, len, Mgran));
- if(m->isa == 0){
- print("pcmmap: out of isa space\n");
- unlock(&pp->mlock);
- return 0;
- }
- m->len = len;
- }
-
- /* set up new map */
- m->ca = offset;
- m->cea = m->ca + m->len;
- m->attr = attr;
- i = m-pp->mmap;
- bit = 1<<i;
- wrreg(pp, Rwe, we & ~bit); /* disable map before changing it */
- wrreg(pp, MAP(i, Mbtmlo), m->isa>>Mshift);
- wrreg(pp, MAP(i, Mbtmhi), (m->isa>>(Mshift+8)) | F16bit);
- wrreg(pp, MAP(i, Mtoplo), (m->isa+m->len-1)>>Mshift);
- wrreg(pp, MAP(i, Mtophi), ((m->isa+m->len-1)>>(Mshift+8)));
- offset -= m->isa;
- offset &= (1<<25)-1;
- offset >>= Mshift;
- wrreg(pp, MAP(i, Mofflo), offset);
- wrreg(pp, MAP(i, Moffhi), (offset>>8) | (attr ? Fregactive : 0));
- wrreg(pp, Rwe, we | bit); /* enable map */
- m->ref = 1;
-
- unlock(&pp->mlock);
- return m;
-}
-
-void
-pcmunmap(int slotno, PCMmap* m)
-{
- PCMslot *pp;
-
- pp = slot + slotno;
- lock(&pp->mlock);
- m->ref--;
- unlock(&pp->mlock);
-}
-
-static void
-increfp(PCMslot *pp)
-{
- lock(pp);
- if(pp->ref++ == 0)
- slotena(pp);
- unlock(pp);
-}
-
-static void
-decrefp(PCMslot *pp)
-{
- lock(pp);
- if(pp->ref-- == 1)
- slotdis(pp);
- unlock(pp);
-}
-
-/*
- * look for a card whose version contains 'idstr'
- */
-static int
-pcmcia_pcmspecial(char *idstr, ISAConf *isa)
-{
- PCMslot *pp;
- extern char *strstr(char*, char*);
- int enabled;
-
- for(pp = slot; pp < lastslot; pp++){
- if(pp->special)
- continue; /* already taken */
-
- /*
- * make sure we don't power on cards when we already know what's
- * in them. We'll reread every two minutes if necessary
- */
- enabled = 0;
- if (pp->msec == ~0 || TK2MS(MACHP(0)->ticks) - pp->msec > 120000){
- increfp(pp);
- enabled++;
- }
-
- if(pp->occupied) {
- if(strstr(pp->verstr, idstr)){
- if (!enabled){
- enabled = 1;
- increfp(pp);
- }
- if(isa == 0 || pcmio(pp->slotno, isa) == 0){
- pp->special = 1;
- return pp->slotno;
- }
- }
- } else
- pp->special = 1;
- if (enabled)
- decrefp(pp);
- }
- return -1;
-}
-
-static void
-pcmcia_pcmspecialclose(int slotno)
-{
- PCMslot *pp;
-
- if(slotno >= nslot)
- panic("pcmspecialclose");
- pp = slot + slotno;
- pp->special = 0;
- decrefp(pp);
-}
-
-enum
-{
- Qdir,
- Qmem,
- Qattr,
- Qctl,
-
- Nents = 3,
-};
-
-#define SLOTNO(c) ((ulong)((c->qid.path>>8)&0xff))
-#define TYPE(c) ((ulong)(c->qid.path&0xff))
-#define QID(s,t) (((s)<<8)|(t))
-
-static int
-pcmgen(Chan *c, char*, Dirtab *, int , int i, Dir *dp)
-{
- int slotno;
- Qid qid;
- long len;
- PCMslot *pp;
-
- if(i == DEVDOTDOT){
- mkqid(&qid, Qdir, 0, QTDIR);
- devdir(c, qid, "#y", 0, eve, 0555, dp);
- return 1;
- }
-
- if(i >= Nents*nslot)
- return -1;
- slotno = i/Nents;
- pp = slot + slotno;
- len = 0;
- switch(i%Nents){
- case 0:
- qid.path = QID(slotno, Qmem);
- snprint(up->genbuf, sizeof up->genbuf, "pcm%dmem", slotno);
- len = pp->memlen;
- break;
- case 1:
- qid.path = QID(slotno, Qattr);
- snprint(up->genbuf, sizeof up->genbuf, "pcm%dattr", slotno);
- len = pp->memlen;
- break;
- case 2:
- qid.path = QID(slotno, Qctl);
- snprint(up->genbuf, sizeof up->genbuf, "pcm%dctl", slotno);
- break;
- }
- qid.vers = 0;
- qid.type = QTFILE;
- devdir(c, qid, up->genbuf, len, eve, 0660, dp);
- return 1;
-}
-
-static char *chipname[] =
-{
-[Ti82365] "Intel 82365SL",
-[Tpd6710] "Cirrus Logic CL-PD6710",
-[Tpd6720] "Cirrus Logic CL-PD6720",
-[Tvg46x] "Vadem VG-46x",
-};
-
-static I82365*
-i82365probe(int x, int d, int dev)
-{
- uchar c, id;
- I82365 *cp;
- ISAConf isa;
- int i, nslot;
-
- outb(x, Rid + (dev<<7));
- id = inb(d);
- if((id & 0xf0) != 0x80)
- return 0; /* not a memory & I/O card */
- if((id & 0x0f) == 0x00)
- return 0; /* no revision number, not possible */
-
- cp = xalloc(sizeof(I82365));
- cp->xreg = x;
- cp->dreg = d;
- cp->dev = dev;
- cp->type = Ti82365;
- cp->nslot = 2;
-
- switch(id){
- case 0x82:
- case 0x83:
- case 0x84:
- /* could be a cirrus */
- outb(x, Rchipinfo + (dev<<7));
- outb(d, 0);
- c = inb(d);
- if((c & 0xc0) != 0xc0)
- break;
- c = inb(d);
- if((c & 0xc0) != 0x00)
- break;
- if(c & 0x20){
- cp->type = Tpd6720;
- } else {
- cp->type = Tpd6710;
- cp->nslot = 1;
- }
-
- /* low power mode */
- outb(x, Rmisc2 + (dev<<7));
- c = inb(d);
- outb(d, c & ~Flowpow);
- break;
- }
-
- /* if it's not a Cirrus, it could be a Vadem... */
- if(cp->type == Ti82365){
- /* unlock the Vadem extended regs */
- outb(x, 0x0E + (dev<<7));
- outb(x, 0x37 + (dev<<7));
-
- /* make the id register show the Vadem id */
- outb(x, 0x3A + (dev<<7));
- c = inb(d);
- outb(d, c|0xC0);
- outb(x, Rid + (dev<<7));
- c = inb(d);
- if(c & 0x08)
- cp->type = Tvg46x;
-
- /* go back to Intel compatible id */
- outb(x, 0x3A + (dev<<7));
- c = inb(d);
- outb(d, c & ~0xC0);
- }
-
- memset(&isa, 0, sizeof(ISAConf));
- if(isaconfig("pcmcia", ncontroller, &isa) && isa.irq)
- cp->irq = isa.irq;
- else
- cp->irq = IrqPCMCIA;
-
- for(i = 0; i < isa.nopt; i++){
- if(cistrncmp(isa.opt[i], "nslot=", 6))
- continue;
- nslot = strtol(&isa.opt[i][6], nil, 0);
- if(nslot > 0 && nslot <= 2)
- cp->nslot = nslot;
- }
-
- controller[ncontroller++] = cp;
- return cp;
-}
-
-static void
-i82365dump(PCMslot *pp)
-{
- int i;
-
- for(i = 0; i < 0x40; i++){
- if((i&0x0F) == 0)
- print("\n%2.2uX: ", i);
- print("%2.2uX ", rdreg(pp, i));
- if(((i+1) & 0x0F) == 0x08)
- print(" - ");
- }
- print("\n");
-}
-
-/*
- * set up for slot cards
- */
-void
-devi82365link(void)
-{
- static int already;
- int i, j;
- I82365 *cp;
- PCMslot *pp;
- char buf[32], *p;
-
- if(already)
- return;
- already = 1;
-
- if((p=getconf("pcmcia0")) && strncmp(p, "disabled", 8)==0)
- return;
-
- if(_pcmspecial)
- return;
-
- /* look for controllers if the ports aren't already taken */
- if(ioalloc(0x3E0, 2, 0, "i82365.0") >= 0){
- i82365probe(0x3E0, 0x3E1, 0);
- i82365probe(0x3E0, 0x3E1, 1);
- if(ncontroller == 0)
- iofree(0x3E0);
- }
- if(ioalloc(0x3E2, 2, 0, "i82365.1") >= 0){
- i = ncontroller;
- i82365probe(0x3E2, 0x3E3, 0);
- i82365probe(0x3E2, 0x3E3, 1);
- if(ncontroller == i)
- iofree(0x3E2);
- }
-
- if(ncontroller == 0)
- return;
-
- _pcmspecial = pcmcia_pcmspecial;
- _pcmspecialclose = pcmcia_pcmspecialclose;
-
- for(i = 0; i < ncontroller; i++)
- nslot += controller[i]->nslot;
- slot = xalloc(nslot * sizeof(PCMslot));
-
- lastslot = slot;
- for(i = 0; i < ncontroller; i++){
- cp = controller[i];
- print("#y%d: %d slot %s: port 0x%uX irq %d\n",
- i, cp->nslot, chipname[cp->type], cp->xreg, cp->irq);
- for(j = 0; j < cp->nslot; j++){
- pp = lastslot++;
- pp->slotno = pp - slot;
- pp->memlen = 64*MB;
- pp->base = (cp->dev<<7) | (j<<6);
- pp->cp = cp;
- pp->msec = ~0;
- pp->verstr[0] = 0;
- slotdis(pp);
-
- /* interrupt on status change */
- wrreg(pp, Rcscic, (cp->irq<<4) | Fchangeena);
- rdreg(pp, Rcsc);
- }
-
- /* for card management interrupts */
- snprint(buf, sizeof buf, "i82365.%d", i);
- intrenable(cp->irq, i82365intr, 0, BUSUNKNOWN, buf);
- }
-}
-
-static Chan*
-i82365attach(char *spec)
-{
- return devattach('y', spec);
-}
-
-static Walkqid*
-i82365walk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, 0, 0, pcmgen);
-}
-
-static int
-i82365stat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, 0, 0, pcmgen);
-}
-
-static Chan*
-i82365open(Chan *c, int omode)
-{
- if(c->qid.type & QTDIR){
- if(omode != OREAD)
- error(Eperm);
- } else
- increfp(slot + SLOTNO(c));
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-static void
-i82365close(Chan *c)
-{
- if(c->flag & COPEN)
- if((c->qid.type & QTDIR) == 0)
- decrefp(slot+SLOTNO(c));
-}
-
-/* a memmove using only bytes */
-static void
-memmoveb(uchar *to, uchar *from, int n)
-{
- while(n-- > 0)
- *to++ = *from++;
-}
-
-/* a memmove using only shorts & bytes */
-static void
-memmoves(uchar *to, uchar *from, int n)
-{
- ushort *t, *f;
-
- if((((ulong)to) & 1) || (((ulong)from) & 1) || (n & 1)){
- while(n-- > 0)
- *to++ = *from++;
- } else {
- n = n/2;
- t = (ushort*)to;
- f = (ushort*)from;
- while(n-- > 0)
- *t++ = *f++;
- }
-}
-
-static long
-pcmread(int slotno, int attr, void *a, long n, vlong off)
-{
- int i, len;
- PCMmap *m;
- uchar *ac;
- PCMslot *pp;
- ulong offset = off;
-
- pp = slot + slotno;
- if(pp->memlen < offset)
- return 0;
- if(pp->memlen < offset + n)
- n = pp->memlen - offset;
-
- m = 0;
- if(waserror()){
- if(m)
- pcmunmap(pp->slotno, m);
- nexterror();
- }
-
- ac = a;
- for(len = n; len > 0; len -= i){
- m = pcmmap(pp->slotno, offset, 0, attr);
- if(m == 0)
- error("cannot map PCMCIA card");
- if(offset + len > m->cea)
- i = m->cea - offset;
- else
- i = len;
- memmoveb(ac, KADDR(m->isa + offset - m->ca), i);
- pcmunmap(pp->slotno, m);
- offset += i;
- ac += i;
- }
-
- poperror();
- return n;
-}
-
-static long
-i82365read(Chan *c, void *a, long n, vlong off)
-{
- char *p, *buf, *e;
- PCMslot *pp;
- ulong offset = off;
-
- switch(TYPE(c)){
- case Qdir:
- return devdirread(c, a, n, 0, 0, pcmgen);
- case Qmem:
- case Qattr:
- return pcmread(SLOTNO(c), TYPE(c) == Qattr, a, n, off);
- case Qctl:
- buf = p = malloc(READSTR);
- e = p + READSTR;
- pp = slot + SLOTNO(c);
-
- buf[0] = 0;
- if(pp->occupied){
- p = seprint(p, e, "occupied\n");
- if(pp->verstr[0])
- p = seprint(p, e, "version %s\n", pp->verstr);
- }
- if(pp->enabled)
- p = seprint(p, e, "enabled\n");
- if(pp->powered)
- p = seprint(p, e, "powered\n");
- if(pp->configed)
- p = seprint(p, e, "configed\n");
- if(pp->wrprot)
- p = seprint(p, e, "write protected\n");
- if(pp->busy)
- p = seprint(p, e, "busy\n");
- seprint(p, e, "battery lvl %d\n", pp->battery);
-
- n = readstr(offset, a, n, buf);
- free(buf);
-
- return n;
- }
- error(Ebadarg);
- return -1; /* not reached */
-}
-
-static long
-pcmwrite(int dev, int attr, void *a, long n, vlong off)
-{
- int i, len;
- PCMmap *m;
- uchar *ac;
- PCMslot *pp;
- ulong offset = off;
-
- pp = slot + dev;
- if(pp->memlen < offset)
- return 0;
- if(pp->memlen < offset + n)
- n = pp->memlen - offset;
-
- m = 0;
- if(waserror()){
- if(m)
- pcmunmap(pp->slotno, m);
- nexterror();
- }
-
- ac = a;
- for(len = n; len > 0; len -= i){
- m = pcmmap(pp->slotno, offset, 0, attr);
- if(m == 0)
- error("cannot map PCMCIA card");
- if(offset + len > m->cea)
- i = m->cea - offset;
- else
- i = len;
- memmoveb(KADDR(m->isa + offset - m->ca), ac, i);
- pcmunmap(pp->slotno, m);
- offset += i;
- ac += i;
- }
-
- poperror();
- return n;
-}
-
-static long
-i82365write(Chan *c, void *a, long n, vlong off)
-{
- PCMslot *pp;
- char buf[32];
-
- switch(TYPE(c)){
- case Qctl:
- if(n >= sizeof(buf))
- n = sizeof(buf) - 1;
- strncpy(buf, a, n);
- buf[n] = 0;
- pp = slot + SLOTNO(c);
- if(!pp->occupied)
- error(Eio);
-
- /* set vpp on card */
- if(strncmp(buf, "vpp", 3) == 0)
- wrreg(pp, Rpc, vcode(atoi(buf+3))|Fautopower|Foutena|Fcardena);
- return n;
- case Qmem:
- case Qattr:
- pp = slot + SLOTNO(c);
- if(pp->occupied == 0 || pp->enabled == 0)
- error(Eio);
- n = pcmwrite(pp->slotno, TYPE(c) == Qattr, a, n, off);
- if(n < 0)
- error(Eio);
- return n;
- }
- error(Ebadarg);
- return -1; /* not reached */
-}
-
-Dev i82365devtab = {
- 'y',
- "i82365",
-
- devreset,
- devinit,
- devshutdown,
- i82365attach,
- i82365walk,
- i82365stat,
- i82365open,
- devcreate,
- i82365close,
- i82365read,
- devbread,
- i82365write,
- devbwrite,
- devremove,
- devwstat,
-};
-
-/*
- * configure the PCMslot for IO. We assume very heavily that we can read
- * configuration info from the CIS. If not, we won't set up correctly.
- */
-static int
-pcmio(int slotno, ISAConf *isa)
-{
- uchar we, x, *p;
- PCMslot *pp;
- PCMconftab *ct, *et, *t;
- PCMmap *m;
- int i, index, irq;
- char *cp;
-
- irq = isa->irq;
- if(irq == 2)
- irq = 9;
-
- if(slotno > nslot)
- return -1;
- pp = slot + slotno;
-
- if(!pp->occupied)
- return -1;
-
- et = &pp->ctab[pp->nctab];
-
- ct = 0;
- for(i = 0; i < isa->nopt; i++){
- if(strncmp(isa->opt[i], "index=", 6))
- continue;
- index = strtol(&isa->opt[i][6], &cp, 0);
- if(cp == &isa->opt[i][6] || index >= pp->nctab)
- return -1;
- ct = &pp->ctab[index];
- }
-
- if(ct == 0){
- /* assume default is right */
- if(pp->def)
- ct = pp->def;
- else
- ct = pp->ctab;
-
- /* try for best match */
- if(ct->nio == 0
- || ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){
- for(t = pp->ctab; t < et; t++)
- if(t->nio
- && t->io[0].start == isa->port
- && ((1<<irq) & t->irqs)){
- ct = t;
- break;
- }
- }
- if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){
- for(t = pp->ctab; t < et; t++)
- if(t->nio && ((1<<irq) & t->irqs)){
- ct = t;
- break;
- }
- }
- if(ct->nio == 0){
- for(t = pp->ctab; t < et; t++)
- if(t->nio){
- ct = t;
- break;
- }
- }
- }
-
- if(ct == et || ct->nio == 0)
- return -1;
- if(isa->port == 0 && ct->io[0].start == 0)
- return -1;
-
- /* route interrupts */
- isa->irq = irq;
- wrreg(pp, Rigc, irq | Fnotreset | Fiocard);
-
- /* set power and enable device */
- x = vcode(ct->vpp1);
- wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena);
-
- /* 16-bit data path */
- if(ct->bit16)
- x = Ftiming|Fiocs16|Fwidth16;
- else
- x = Ftiming;
- if(ct->nio == 2 && ct->io[1].start)
- x |= x<<4;
- wrreg(pp, Rio, x);
-
- /*
- * enable io port map 0
- * the 'top' register value includes the last valid address
- */
- if(isa->port == 0)
- isa->port = ct->io[0].start;
- we = rdreg(pp, Rwe);
- wrreg(pp, Riobtm0lo, isa->port);
- wrreg(pp, Riobtm0hi, isa->port>>8);
- i = isa->port+ct->io[0].len-1;
- wrreg(pp, Riotop0lo, i);
- wrreg(pp, Riotop0hi, i>>8);
- we |= 1<<6;
- if(ct->nio >= 2 && ct->io[1].start){
- wrreg(pp, Riobtm1lo, ct->io[1].start);
- wrreg(pp, Riobtm1hi, ct->io[1].start>>8);
- i = ct->io[1].start+ct->io[1].len-1;
- wrreg(pp, Riotop1lo, i);
- wrreg(pp, Riotop1hi, i>>8);
- we |= 1<<7;
- }
- wrreg(pp, Rwe, we);
-
- /* only touch Rconfig if it is present */
- m = pcmmap(slotno, pp->cfg[0].caddr + Rconfig, 0x20, 1);
- p = KADDR(m->isa + pp->cfg[0].caddr - m->ca);
- if(pp->cfg[0].cpresent & (1<<Rconfig)){
- /* Reset adapter */
-
- /* set configuration and interrupt type.
- * if level is possible on the card, use it.
- */
- x = ct->index;
- if(ct->irqtype & 0x20)
- x |= Clevel;
-
- /* enable the device, enable address decode and
- * irq enable.
- */
- x |= Cfunc|Cdecode|Cirq;
-
- p[0] = x;
- //delay(5);
- microdelay(40);
- }
-
- if(pp->cfg[0].cpresent & (1<<Riobase0)){
- /* set up the iobase 0 */
- p[Riobase0 << 1] = isa->port;
- p[Riobase1 << 1] = isa->port >> 8;
- }
-
- if(pp->cfg[0].cpresent & (1<<Riosize))
- p[Riosize << 1] = ct->io[0].len;
- pcmunmap(slotno, m);
- return 0;
-}
diff --git a/os/pc/devlm78.c b/os/pc/devlm78.c
deleted file mode 100644
index 617d5cb9..00000000
--- a/os/pc/devlm78.c
+++ /dev/null
@@ -1,346 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-/* this driver doesn't implement the management interrupts. we
- * leave the LM78 interrupts set to whatever the BIOS did. we do
- * allow reading and writing the the readouts and alarm values.
- * Read(2)ing or write(2)ing at offset 0x0-0x1f, is
- * equivalent to reading or writing lm78 registers 0x20-0x3f.
- */
-enum
-{
- /* address of chip on serial interface */
- Serialaddr= 0x2d,
-
- /* parallel access registers */
- Rpaddr= 0x5,
- Bbusy= (1<<7),
- Rpdata= 0x6,
-
- /* internal register addresses */
- Rconfig= 0x40,
- Bstart= (1<<0),
- Bsmiena= (1<<1),
- Birqena= (1<<2),
- Bintclr= (1<<3),
- Breset= (1<<4),
- Bnmi= (1<<5), /* if set, use nmi, else irq */
- Bpowbypass= (1<<6),
- Binit= (1<<7),
- Ristat1= 0x41,
- Ristat2= 0x42,
- Rsmimask1= 0x43,
- Rsmimask2= 0x44,
- Rnmimask1= 0x45,
- Rnmimask2= 0x46,
- Rvidfan= 0x47, /* set fan counter, and read voltage level */
- Mvid= 0x0f,
- Mfan= 0xf0,
- Raddr= 0x48, /* address used on serial bus */
- Rresetid= 0x49, /* chip reset and ID register */
- Rpost= 0x00, /* start of post ram */
- Rvalue= 0x20, /* start of value ram */
-
- VRsize= 0x20, /* size of value ram */
-};
-
-enum
-{
- Qdir,
- Qlm78vram,
-};
-
-static Dirtab lm78dir[] = {
- ".", { Qdir, 0, QTDIR}, 0, 0555,
- "lm78vram", { Qlm78vram, 0 }, 0, 0444,
-};
-
-/* interface type */
-enum
-{
- None= 0,
- Smbus,
- Parallel,
-};
-
-static struct {
- QLock;
- int probed;
- int ifc; /* which interface is connected */
- SMBus *smbus; /* serial interface */
- int port; /* parallel interface */
-} lm78;
-
-extern SMBus* piix4smbus(void);
-
-/* wait for device to become quiescent and then set the */
-/* register address */
-static void
-setreg(int reg)
-{
- int tries;
-
- for(tries = 0; tries < 1000000; tries++)
- if((inb(lm78.port+Rpaddr) & Bbusy) == 0){
- outb(lm78.port+Rpaddr, reg);
- return;
- }
- error("lm78 broken");
-}
-
-/* routines that actually touch the device */
-static void
-lm78wrreg(int reg, uchar val)
-{
- if(waserror()){
- qunlock(&lm78);
- nexterror();
- }
- qlock(&lm78);
-
- switch(lm78.ifc){
- case Smbus:
- lm78.smbus->transact(lm78.smbus, SMBbytewrite, Serialaddr, reg, &val);
- break;
- case Parallel:
- setreg(reg);
- outb(lm78.port+Rpdata, val);
- break;
- default:
- error(Enodev);
- break;
- }
-
- qunlock(&lm78);
- poperror();
-}
-
-static int
-lm78rdreg(int reg)
-{
- uchar val;
-
- if(waserror()){
- qunlock(&lm78);
- nexterror();
- }
- qlock(&lm78);
-
- switch(lm78.ifc){
- case Smbus:
- lm78.smbus->transact(lm78.smbus, SMBsend, Serialaddr, reg, nil);
- lm78.smbus->transact(lm78.smbus, SMBrecv, Serialaddr, 0, &val);
- break;
- case Parallel:
- setreg(reg);
- val = inb(lm78.port+Rpdata);
- break;
- default:
- error(Enodev);
- break;
- }
-
- qunlock(&lm78);
- poperror();
- return val;
-}
-
-/* start the chip monitoring but don't change any smi
- * interrupts and/or alarms that the BIOS may have set up.
- * this isn't locked because it's thought to be idempotent
- */
-static void
-lm78enable(void)
-{
- uchar config;
-
- if(lm78.ifc == None)
- error(Enodev);
-
- if(lm78.probed == 0){
- /* make sure its really there */
- if(lm78rdreg(Raddr) != Serialaddr){
- lm78.ifc = None;
- error(Enodev);
- } else {
- /* start the sampling */
- config = lm78rdreg(Rconfig);
- config = (config | Bstart) & ~(Bintclr|Binit);
- lm78wrreg(Rconfig, config);
-pprint("Rvidfan %2.2ux\n", lm78rdreg(Rconfig), lm78rdreg(Rvidfan));
- }
- lm78.probed = 1;
- }
-}
-
-enum
-{
- IntelVendID= 0x8086,
- PiixID= 0x122E,
- Piix3ID= 0x7000,
-
- Piix4PMID= 0x7113, /* PIIX4 power management function */
-
- PCSC= 0x78, /* programmable chip select control register */
- PCSC8bytes= 0x01,
-};
-
-/* figure out what kind of interface we could have */
-void
-lm78reset(void)
-{
- int pcs;
- Pcidev *p;
-
- lm78.ifc = None;
- p = nil;
- while((p = pcimatch(p, IntelVendID, 0)) != nil){
- switch(p->did){
- /* these bridges use the PCSC to map the lm78 into port space. */
- /* for this case the lm78's CS# select is connected to the PIIX's */
- /* PCS# output and the bottom 3 bits of address are passed to the */
- /* LM78's A0-A2 inputs. */
- case PiixID:
- case Piix3ID:
- pcs = pcicfgr16(p, PCSC);
- if(pcs & 3) {
- /* already enabled */
- lm78.port = pcs & ~3;
- lm78.ifc = Parallel;
- return;
- }
-
- /* enable the chip, use default address 0x50 */
- pcicfgw16(p, PCSC, 0x50|PCSC8bytes);
- pcs = pcicfgr16(p, PCSC);
- lm78.port = pcs & ~3;
- lm78.ifc = Parallel;
- return;
-
- /* this bridge puts the lm78's serial interface on the smbus */
- case Piix4PMID:
- lm78.smbus = piix4smbus();
- if(lm78.smbus == nil)
- continue;
- print("found piix4 smbus, base %lud\n", lm78.smbus->base);
- lm78.ifc = Smbus;
- return;
- }
- }
-}
-
-Walkqid *
-lm78walk(Chan* c, Chan *nc, char** name, int nname)
-{
- return devwalk(c, nc, name, nname, lm78dir, nelem(lm78dir), devgen);
-}
-
-static int
-lm78stat(Chan* c, uchar* dp, int n)
-{
- return devstat(c, dp, n, lm78dir, nelem(lm78dir), devgen);
-}
-
-static Chan*
-lm78open(Chan* c, int omode)
-{
- return devopen(c, omode, lm78dir, nelem(lm78dir), devgen);
-}
-
-static void
-lm78close(Chan*)
-{
-}
-
-enum
-{
- Linelen= 25,
-};
-
-static long
-lm78read(Chan *c, void *a, long n, vlong offset)
-{
- uchar *va = a;
- int off, e;
-
- off = offset;
-
- switch((ulong)c->qid.path){
- case Qdir:
- return devdirread(c, a, n, lm78dir, nelem(lm78dir), devgen);
-
- case Qlm78vram:
- if(off >= VRsize)
- return 0;
- e = off + n;
- if(e > VRsize)
- e = VRsize;
- for(; off < e; off++)
- *va++ = lm78rdreg(Rvalue+off);
- return (int)(va - (uchar*)a);
- }
- return 0;
-}
-
-static long
-lm78write(Chan *c, void *a, long n, vlong offset)
-{
- uchar *va = a;
- int off, e;
-
- off = offset;
-
- switch((ulong)c->qid.path){
- default:
- error(Eperm);
-
- case Qlm78vram:
- if(off >= VRsize)
- return 0;
- e = off + n;
- if(e > VRsize)
- e = VRsize;
- for(; off < e; off++)
- lm78wrreg(Rvalue+off, *va++);
- return va - (uchar*)a;
- }
- return 0;
-}
-
-extern Dev lm78devtab;
-
-static Chan*
-lm78attach(char* spec)
-{
- lm78enable();
-
- return devattach(lm78devtab.dc, spec);
-}
-
-Dev lm78devtab = {
- 'T',
- "lm78",
-
- lm78reset,
- devinit,
- devshutdown,
- lm78attach,
- lm78walk,
- lm78stat,
- lm78open,
- devcreate,
- lm78close,
- lm78read,
- devbread,
- lm78write,
- devbwrite,
- devremove,
- devwstat,
-};
-
diff --git a/os/pc/devlpt.c b/os/pc/devlpt.c
deleted file mode 100644
index 2fbc2aba..00000000
--- a/os/pc/devlpt.c
+++ /dev/null
@@ -1,245 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-/* Centronix parallel (printer) port */
-
-/* base addresses */
-static int lptbase[] = {
- 0x378, /* lpt1 */
- 0x3bc, /* lpt2 */
- 0x278 /* lpt3 (sic) */
-};
-#define NDEV nelem(lptbase)
-static int lptallocd[NDEV];
-
-/* offsets, and bits in the registers */
-enum
-{
- Qdir= 0x8000,
- /* data latch register */
- Qdlr= 0x0,
- /* printer status register */
- Qpsr= 0x1,
- Fnotbusy= 0x80,
- Fack= 0x40,
- Fpe= 0x20,
- Fselect= 0x10,
- Fnoerror= 0x08,
- /* printer control register */
- Qpcr= 0x2,
- Fie= 0x10,
- Fselectin= 0x08,
- Finitbar= 0x04,
- Faf= 0x02,
- Fstrobe= 0x01,
- /* fake `data register' */
- Qdata= 0x3,
-};
-
-static int lptready(void*);
-static void outch(int, int);
-static void lptintr(Ureg*, void*);
-
-static Rendez lptrendez;
-
-Dirtab lptdir[]={
- ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
- "dlr", {Qdlr}, 1, 0666,
- "psr", {Qpsr}, 5, 0444,
- "pcr", {Qpcr}, 0, 0222,
- "data", {Qdata}, 0, 0222,
-};
-
-static int
-lptgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp)
-{
- Qid qid;
-
- if(i == DEVDOTDOT){
- mkqid(&qid, Qdir, 0, QTDIR);
- devdir(c, qid, ".", 0, eve, 0555, dp);
- return 1;
- }
- i++; /* skip first element for . itself */
- if(tab==0 || i>=ntab)
- return -1;
- tab += i;
- qid = tab->qid;
- qid.path &= ~Qdir;
- if(qid.path < Qdata)
- qid.path += lptbase[c->dev];
- qid.vers = c->dev;
- sprint(up->genbuf, "lpt%lud%s", c->dev+1, tab->name);
- devdir(c, qid, up->genbuf, tab->length, eve, tab->perm, dp);
- return 1;
-}
-
-static Chan*
-lptattach(char *spec)
-{
- Chan *c;
- int i = (spec && *spec) ? strtol(spec, 0, 0) : 1;
- char name[5];
- static int set;
-
- if(!set){
- outb(lptbase[i-1]+Qpcr, 0); /* turn off interrupts */
- set = 1;
- intrenable(IrqLPT, lptintr, 0, BUSUNKNOWN, "lpt");
- }
- if(i < 1 || i > NDEV)
- error(Ebadarg);
- if(lptallocd[i-1] == 0){
- int ecr;
- sprint(name, "lpt%d", i-1);
- if(ioalloc(lptbase[i-1], 3, 0, name) < 0)
- error("lpt port space in use");
- lptallocd[i-1] = 1;
- // Detect ECP - if found, put into PS/2 mode to suit style of driver
- ecr = lptbase[i-1] + 0x402;
- if ((inb(ecr) & 3) == 1) {
- outb(ecr, 0x34);
- if (inb(ecr) == 0x35) {
- outb(ecr, (inb(ecr) & 0x1f) | (1 << 5));
- if(ioalloc(ecr, 1, 0, name) < 0)
- error("lpt ecr port space in use");
- }
- }
- }
- c = devattach('L', spec);
- c->qid.path = Qdir;
- c->dev = i-1;
- return c;
-}
-
-static Walkqid*
-lptwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, lptdir, nelem(lptdir), lptgen);
-}
-
-static int
-lptstat(Chan *c, uchar *dp, int n)
-{
- return devstat(c, dp, n, lptdir, nelem(lptdir), lptgen);
-}
-
-static Chan*
-lptopen(Chan *c, int omode)
-{
- return devopen(c, omode, lptdir, nelem(lptdir), lptgen);
-}
-
-static void
-lptclose(Chan *)
-{
-}
-
-static long
-lptread(Chan *c, void *a, long n, vlong)
-{
- char str[16];
- int size;
- ulong o;
-
- if(c->qid.path == Qdir)
- return devdirread(c, a, n, lptdir, nelem(lptdir), lptgen);
- size = sprint(str, "0x%2.2ux\n", inb(c->qid.path));
- o = c->offset;
- if(o >= size)
- return 0;
- if(o+n > size)
- n = size-c->offset;
- memmove(a, str+o, n);
- return n;
-}
-
-static long
-lptwrite(Chan *c, void *a, long n, vlong)
-{
- char str[16], *p;
- long base, k;
-
- if(n <= 0)
- return 0;
- if(c->qid.path != Qdata){
- if(n > sizeof str-1)
- n = sizeof str-1;
- memmove(str, a, n);
- str[n] = 0;
- outb(c->qid.path, strtoul(str, 0, 0));
- return n;
- }
- p = a;
- k = n;
- base = lptbase[c->dev];
- if(waserror()){
- outb(base+Qpcr, Finitbar);
- nexterror();
- }
- while(--k >= 0)
- outch(base, *p++);
- poperror();
- return n;
-}
-
-static void
-outch(int base, int c)
-{
- int status, tries;
-
- for(tries=0;; tries++) {
- status = inb(base+Qpsr);
- if(status&Fnotbusy)
- break;
- if((status&Fpe)==0 && (status&(Fselect|Fnoerror)) != (Fselect|Fnoerror))
- error(Eio);
- if(tries < 10)
- tsleep(&lptrendez, return0, nil, 1);
- else {
- outb(base+Qpcr, Finitbar|Fie);
- tsleep(&lptrendez, lptready, (void *)base, 100);
- }
- }
- outb(base+Qdlr, c);
- outb(base+Qpcr, Finitbar|Fstrobe);
- outb(base+Qpcr, Finitbar);
-}
-
-static int
-lptready(void *base)
-{
- return inb((int)base+Qpsr)&Fnotbusy;
-}
-
-static void
-lptintr(Ureg *, void *)
-{
- wakeup(&lptrendez);
-}
-
-Dev lptdevtab = {
- 'L',
- "lpt",
-
- devreset,
- devinit,
- devshutdown,
- lptattach,
- lptwalk,
- lptstat,
- lptopen,
- devcreate,
- lptclose,
- lptread,
- devbread,
- lptwrite,
- devbwrite,
- devremove,
- devwstat,
-};
diff --git a/os/pc/devmouse.c b/os/pc/devmouse.c
deleted file mode 100644
index 1b3c55c6..00000000
--- a/os/pc/devmouse.c
+++ /dev/null
@@ -1,672 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-/*
- * TODO
- * - shift key should modify right button with non-serial mice
- * + intellimouse implementation
- * - acceleration for all mouse types
- * + spurious interrupt 7 after probing for ps2 mouse for the first time...?
- * - test with ms busmouse
- * - test with logitech serial mouse
- */
-
-/*
- * mouse types
- */
-enum
-{
- Mouseother,
- Mouseserial,
- MousePS2,
- Mousebus,
- Mouseintelli,
- Mousemsbus,
-};
-
-static int mousetype;
-static int mouseswap;
-static int mouseport; /* port for serial mice, irq for bus mice */
-static int mousesubtype;
-static int accelerated;
-static QLock mouselock;
-
-static int msbusmousedetect(void);
-static int busmousedetect(void);
-static void mousectl(char *buf);
-static void mouseprobe(char *buf, int len);
-static void mousestatus(char *buf, int len);
-
-enum{
- Qdir,
- Qmousectl,
- Qmouseprobe,
-};
-
-static
-Dirtab mousetab[]={
- "mousectl", {Qmousectl, 0}, 0, 0600,
- "mouseprobe", {Qmouseprobe, 0}, 0, 0400,
-};
-
-static Chan*
-mouseattach(char* spec)
-{
- return devattach('m', spec);
-}
-
-static int
-mousewalk(Chan* c, char* name)
-{
- return devwalk(c, name, mousetab, nelem(mousetab), devgen);
-}
-
-static void
-mousestat(Chan* c, char* db)
-{
- devstat(c, db, mousetab, nelem(mousetab), devgen);
-}
-
-static Chan*
-mouseopen(Chan* c, int omode)
-{
- return devopen(c, omode, mousetab, nelem(mousetab), devgen);
-}
-
-static void
-mouseclose(Chan* c)
-{
- USED(c);
-}
-
-static long
-mouseread(Chan* c, void* a, long n, vlong offset)
-{
- char buf[64];
- USED(offset);
-
- switch(c->qid.path & ~CHDIR){
- case Qdir:
- return devdirread(c, a, n, mousetab, nelem(mousetab), devgen);
- case Qmousectl:
- qlock(&mouselock);
- mousestatus(buf, sizeof(buf));
- qunlock(&mouselock);
- n = readstr(offset, a, n, buf);
- break;
- case Qmouseprobe:
- if (mousetype)
- error(Emouseset);
- mouseprobe(buf, sizeof(buf));
- n = readstr(offset, a, n, buf);
- break;
- default:
- n=0;
- break;
- }
- return n;
-}
-
-static long
-mousewrite(Chan* c, void *a, long n, vlong)
-{
- char buf[64];
- if ((c->qid.path & ~CHDIR) != Qmousectl)
- error(Ebadusefd);
- if (n >= sizeof(buf))
- n = sizeof(buf) - 1;
- strncpy(buf, a, n);
- buf[n] = 0;
-
- qlock(&mouselock);
- if (waserror()) {
- qunlock(&mouselock);
- nexterror();
- }
- mousectl(buf);
- poperror();
- qunlock(&mouselock);
- return n;
-}
-
-static void
-track(int b, int dx, int dy)
-{
- static uchar map[8] = {0,4,2,6,1,5,3,7};
- if (mouseswap)
- b = map[b&7];
- mousetrack(b, dx, dy);
-}
-
-static void
-setintellimouse(void)
-{
- i8042auxcmd(0xF3); /* set sample */
- i8042auxcmd(0xC8);
- i8042auxcmd(0xF3); /* set sample */
- i8042auxcmd(0x64);
- i8042auxcmd(0xF3); /* set sample */
- i8042auxcmd(0x50);
-}
-
-/*
- * check for an Intellimouse.
- * this is only used when we know there's an 8042 aux device
- */
-static int
-intellimousedetect(void)
-{
- int id;
- setintellimouse();
- /* check whether the mouse is now in extended mode */
- id = i8042auxcmdval(0xf2); /* identify device */
- if (id != 3) {
- /*
- * set back to standard sample rate (100 per sec)
- */
- i8042auxcmd(0xf3);
- i8042auxcmd(0x64);
- return 0;
- }
- return 1;
-}
-
-static void
-mouseprobe(char *buf, int len)
-{
- USED(len);
- /*
- * bus mice are easiest, so probe them first
- */
- if (busmousedetect())
- sprint(buf, "bus\n");
- else if (msbusmousedetect())
- sprint(buf, "msbus\n");
- else if (i8042auxdetect()) {
- if (intellimousedetect())
- sprint(buf, "ps2intellimouse\n");
- else
- sprint(buf, "ps2\n");
- }
- else
- *buf = 0;
-}
-
-
-static void
-mousestatus(char *buf, int len)
-{
- char *s;
- USED(len);
- s = buf;
- switch (mousetype) {
- case Mouseserial:
- if (mousesubtype)
- s += sprint(s, "serial %d %c\n", mouseport, mousesubtype);
- else
- s += sprint(s, "serial %d\n", mouseport);
- break;
- case MousePS2:
- s += sprint(s, "ps2\n");
- break;
- case Mousebus:
- s += sprint(s, "bus %d\n", mouseport);
- break;
- case Mouseintelli:
- s += sprint(s, "intelli\n");
- break;
- case Mousemsbus:
- s += sprint(s, "msbus %d\n", mouseport);
- break;
- default:
- case Mouseother:
- s += sprint(s, "unknown\n");
- break;
- }
- if (accelerated)
- s += sprint(s, "accelerated\n");
- if (mouseswap)
- sprint(s, "swap\n");
-}
-
-/*
- * Logitech 5 byte packed binary mouse format, 8 bit bytes
- *
- * shift & right button is the same as middle button (for 2 button mice)
- */
-static int
-logitechmouseputc(Queue *q, int c)
-{
- static short msg[5];
- static int nb;
- static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7};
- int dx, dy, newbuttons;
- int mouseshifted;
-
- USED(q);
- if((c&0xF0) == 0x80)
- nb=0;
- msg[nb] = c;
- if(c & 0x80)
- msg[nb] |= ~0xFF; /* sign extend */
- if(++nb == 5){
- mouseshifted = 0; /* XXX should be from keyboard shift key */
- newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
- dx = msg[1]+msg[3];
- dy = -(msg[2]+msg[4]);
- track(newbuttons, dx, dy);
- nb = 0;
- }
- return 0;
-}
-
-/*
- * microsoft 3 button, 7 bit bytes
- *
- * byte 0 - 1 L R Y7 Y6 X7 X6
- * byte 1 - 0 X5 X4 X3 X2 X1 X0
- * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0
- * byte 3 - 0 M x x x x x (optional)
- *
- * shift & right button is the same as middle button (for 2 button mice)
- */
-static int
-m3mouseputc(Queue*, int c)
-{
- static uchar msg[3];
- static int nb;
- static int middle;
- static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 };
- short x;
- int dx, dy, buttons;
-
- /*
- * check bit 6 for consistency
- */
- if(nb==0){
- if((c&0x40) == 0){
- /* an extra byte gets sent for the middle button */
- if(c & 0x1c)
- return 0;
- middle = (c&0x20) ? 2 : 0;
- buttons = (mouse.b & ~2) | middle;
- track(buttons, 0, 0);
- return 0;
- }
- }
- msg[nb] = c&0x3f;
- if(++nb == 3){
- nb = 0;
- buttons = middle | b[(msg[0]>>4)&3];
- x = (msg[0]&0x3)<<14;
- dx = (x>>8) | msg[1];
- x = (msg[0]&0xc)<<12;
- dy = (x>>8) | msg[2];
- track(buttons, dx, dy);
- }
- return 0;
-}
-
-static void
-serialmouse(int port, char *type, int setspeed)
-{
- int (*putc)(Queue *, int) = 0;
- char pn[KNAMELEN];
-
- if(mousetype)
- error(Emouseset);
-
- if(port >= 2 || port < 0)
- error(Ebadarg);
-
- if (type == 0)
- putc = logitechmouseputc;
- else if (*type == 'M')
- putc = m3mouseputc;
- else
- error(Ebadarg);
- snprint(pn, sizeof(pn), "%d", port);
- i8250mouse(pn, putc, setspeed);
- mousetype = Mouseserial;
- mouseport = port;
- mousesubtype = (type && *type == 'M') ? 'M' : 0;
-}
-
-/*
- * ps/2 mouse message is three bytes
- *
- * byte 0 - 0 0 SDY SDX 1 M R L
- * byte 1 - DX
- * byte 2 - DY
- *
- * shift & left button is the same as middle button
- */
-static void
-ps2mouseputc(int c, int shift)
-{
- static short msg[3];
- static int nb;
- static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 };
- int buttons, dx, dy;
-
- /*
- * check byte 0 for consistency
- */
- if(nb==0 && (c&0xc8)!=0x08)
- return;
-
- msg[nb] = c;
- if(++nb == 3){
- nb = 0;
- if(msg[0] & 0x10)
- msg[1] |= 0xFF00;
- if(msg[0] & 0x20)
- msg[2] |= 0xFF00;
-
- buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
- dx = msg[1];
- dy = -msg[2];
- track(buttons, dx, dy);
- }
- return;
-}
-
-/*
- * set up a ps2 mouse
- */
-static void
-ps2mouse(void)
-{
- if(mousetype)
- error(Emouseset);
-
- i8042auxenable(ps2mouseputc);
- /* make mouse streaming, enabled */
- i8042auxcmd(0xEA);
- i8042auxcmd(0xF4);
-
- mousetype = MousePS2;
-}
-
-/* logitech bus mouse ports and commands */
-enum {
- /* ports */
- BMdatap = 0x23c,
- BMsigp = 0x23d,
- BMctlp = 0x23e,
- BMintrp = 0x23e,
- BMconfigp = 0x23f,
-
- /* commands */
- BMintron = 0x0,
- BMintroff = 0x10,
- BMrxlo = 0x80,
- BMrxhi = 0xa0,
- BMrylo = 0xc0,
- BMryhi = 0xe0,
-
- BMconfig = 0x91,
- BMdefault = 0x90,
-
- BMsigval = 0xa5
-};
-
-static void
-busmouseintr(Ureg *, void *)
-{
- char dx, dy;
- uchar b;
- static uchar oldb;
- static Lock intrlock;
- ilock(&intrlock);
- outb(BMintrp, BMintroff);
- outb(BMctlp, BMrxlo);
- dx = inb(BMdatap) & 0xf;
- outb(BMctlp, BMrxhi);
- dx |= (inb(BMdatap) & 0xf) << 4;
- outb(BMctlp, BMrylo);
- dy = inb(BMdatap) & 0xf;
- outb(BMctlp, BMryhi);
- b = inb(BMdatap);
- dy |= (b & 0xf) << 4;
- b = ~(b >> 5) & 7;
- if (dx || dy || b != oldb) {
- oldb = b;
- track((b>>2)|(b&0x02)|((b&0x01)<<2), dx, dy);
- }
- iunlock(&intrlock);
- outb(BMintrp, BMintron);
-}
-
-static int
-busmousedetect(void)
-{
- outb(BMconfigp, BMconfig);
- outb(BMsigp, BMsigval);
- delay(2);
- if (inb(BMsigp) != BMsigval)
- return 0;
- outb(BMconfigp, BMdefault);
- return 1;
-}
-
-/*
- * set up a logitech bus mouse
- */
-static void
-busmouse(int irq)
-{
- if (mousetype)
- error(Emouseset);
- if (!busmousedetect())
- error(Enodev);
-
- intrenable(irq >= 0 ? irq+VectorPIC : VectorBUSMOUSE, busmouseintr, 0, BUSUNKNOWN);
- outb(BMintrp, BMintron);
- mousetype = Mousebus;
- mouseport = irq >= 0 ? irq : VectorBUSMOUSE-VectorPIC;
-}
-
-/* microsoft bus mouse ports and commands */
-enum {
- MBMdatap= 0x23d,
- MBMsigp= 0x23e,
- MBMctlp= 0x23c,
- MBMconfigp= 0x23f,
-
- MBMintron= 0x11,
- MBMintroff= 0x10,
- MBMrbuttons= 0x00,
- MBMrx= 0x01,
- MBMry= 0x02,
- MBMstart= 0x80,
- MBMcmd= 0x07,
-};
-
-static void
-msbusmouseintr(Ureg *, void *)
-{
- char dx, dy;
- uchar b;
- static uchar oldb;
- static Lock intrlock;
- ilock(&intrlock);
- outb(MBMctlp, MBMcmd);
- outb(MBMdatap, inb(MBMdatap)|0x20);
-
- outb(MBMctlp, MBMrx);
- dx = inb(MBMdatap);
-
- outb(MBMctlp, MBMry);
- dy = inb(MBMdatap);
-
- outb(MBMctlp, MBMrbuttons);
- b = inb(MBMdatap) & 0x7;
-
- outb(MBMctlp, MBMcmd);
- outb(MBMdatap, inb(MBMdatap)&0xdf);
-
- if (dx != 0 || dy != 0 || b != oldb) {
- oldb = b;
- /* XXX this is almost certainly wrong */
- track((b>>2)|(b&0x02)|((b&0x01)<<2), dx, dy);
- }
- iunlock(&intrlock);
-}
-
-static int
-msbusmousedetect(void)
-{
- if (inb(MBMsigp) == 0xde) {
- int v, i;
- delay(1);
- v = inb(MBMsigp);
- delay(1);
- for (i = 0; i < 4; i++) {
- if (inb(MBMsigp) != 0xde)
- break;
- delay(1);
- if (inb(MBMsigp) != v)
- break;
- delay(1);
- }
- if (i == 4) {
- outb(MBMctlp, MBMcmd);
- return 1;
- }
- }
- return 0;
-}
-
-static void
-msbusmouse(int irq)
-{
- if (mousetype)
- error(Emouseset);
- if (!msbusmousedetect())
- error(Enodev);
- mousetype = Mousemsbus;
- mouseport = irq >= 0 ? irq : VectorBUSMOUSE-VectorPIC;
- intrenable(irq >= 0 ? irq+VectorPIC : VectorBUSMOUSE, msbusmouseintr, 0, BUSUNKNOWN);
- outb(MBMdatap, MBMintron);
-}
-
-static void
-mousectl(char *buf)
-{
- int nf, x;
- char *field[10];
- nf = getfields(buf, field, 10, 1, " \t\n");
- if (nf < 1)
- return;
- if(strncmp(field[0], "serial", 6) == 0){
- switch(nf){
- /* the difference between these two cases is intriguing - wrtp */
- case 1:
- serialmouse(atoi(field[0]+6), 0, 1);
- break;
- case 2:
- serialmouse(atoi(field[1]), 0, 0);
- break;
- case 3:
- default:
- serialmouse(atoi(field[1]), field[2], 0);
- break;
- }
- } else if(strcmp(field[0], "ps2") == 0){
- ps2mouse();
- } else if (strcmp(field[0], "ps2intellimouse") == 0) {
- ps2mouse();
- setintellimouse();
- } else if (strncmp(field[0], "bus", 3) == 0 || strncmp(field[0], "msbus", 5) == 0) {
- int irq, isms;
-
- isms = (field[0][0] == 'm');
- if (nf == 1)
- irq = atoi(field[0] + (isms ? 5 : 3));
- else
- irq = atoi(field[1]);
- if (irq < 1)
- irq = -1;
- if (isms)
- msbusmouse(irq);
- else
- busmouse(irq);
- } else if(strcmp(field[0], "accelerated") == 0){
- switch(mousetype){
- case MousePS2:
- x = splhi();
- i8042auxcmd(0xE7);
- splx(x);
- accelerated = 1;
- break;
- }
- } else if(strcmp(field[0], "linear") == 0){
- switch(mousetype){
- case MousePS2:
- x = splhi();
- i8042auxcmd(0xE6);
- splx(x);
- accelerated = 0;
- break;
- }
- } else if(strcmp(field[0], "res") == 0){
- int n,m;
- switch(nf){
- default:
- n = 0x02;
- m = 0x23;
- break;
- case 2:
- n = atoi(field[1])&0x3;
- m = 0x7;
- break;
- case 3:
- n = atoi(field[1])&0x3;
- m = atoi(field[2])&0x7;
- break;
- }
-
- switch(mousetype){
- case MousePS2:
- x = splhi();
- i8042auxcmd(0xE8);
- i8042auxcmd(n);
- i8042auxcmd(0x5A);
- i8042auxcmd(0x30|m);
- i8042auxcmd(0x5A);
- i8042auxcmd(0x20|(m>>1));
- splx(x);
- break;
- }
- } else if(strcmp(field[0], "swap") == 0)
- mouseswap ^= 1;
-}
-
-Dev mousedevtab = { /* defaults in dev.c */
- 'm',
- "mouse",
-
- devreset, /* devreset */
- devinit, /* devinit */
- mouseattach,
- devdetach,
- devclone, /* devclone */
- mousewalk,
- mousestat,
- mouseopen,
- devcreate, /* devcreate */
- mouseclose,
- mouseread,
- devbread, /* devbread */
- mousewrite,
- devbwrite, /* devbwrite */
- devremove, /* devremove */
- devwstat, /* devwstat */
-};
-
diff --git a/os/pc/devmpeg.c b/os/pc/devmpeg.c
deleted file mode 100644
index 038cfa6c..00000000
--- a/os/pc/devmpeg.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-/*
- * Boffin MPEG decoder
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "zoran.h"
-#include "crystal.h"
-#include "io.h"
-
-enum
-{
-
- CPUACCCTRL = 0x20, /* Trident Window Chip control registers */
- CPUACCMD = 0x21,
- BNKADR = 0x22,
- SYSCONFIG = 0x23,
- VGACOMP = 0x24,
- VGAMASK = 0x25,
- VIDCOMPL = 0x26,
- VIDCOMPH = 0x27,
- MOS = 0x28,
- DISPCTRL = 0x29,
- CAPCTRL = 0x2a,
- OVLKT = 0x2b,
- OVLWINHSTRT = 0x2c,
- OVLWINVSTRT = 0x2d,
- OVLWINHEND = 0x2e,
- OVLWINVEND = 0x2f,
- RESERVED1 = 0x30,
- RESERVED2 = 0x31,
- DISPWINVSTRT1 = 0x32,
- DISPWINVSTRT2 = 0x33,
- DISPWINVEND = 0x34,
- DISPWINHSTRT1 = 0x35,
- DISPWINHSTRT2 = 0x36,
- DISPWINHEND = 0x37,
- CAPWINVSTRT = 0x38,
- CAPWINHSTRT = 0x39,
- CAPWINVMF = 0x3a,
- CAPWINHMF = 0x3b,
- RESERVED3 = 0x3c,
- CAPMASK = 0x3d,
- BNKPOLATION = 0x3e,
- SYNCPOL = 0x3f,
- DISPVTOTAL = 0x40,
- DISPHTOTAL = 0x41,
- DISPVSTRT = 0x42,
- DISPVEND = 0x43,
- DISPHSTRT = 0x44,
- DISPHEND = 0x45,
- DISPSYNCW = 0x46,
- DISPCRTCCTRL = 0x47,
- CAPVTOTAL = 0x48,
- CAPHTOTAL = 0x49,
- CAPVSTRT = 0x4a,
- CAPVEND = 0x4b,
- CAPHSTRT = 0x4c,
- CAPHEND = 0x4d,
- CAPSYNCW = 0x4e,
- CAPCRTCCTRL = 0x4f,
- VIDLUTDACRW = 0x50,
- VIDLUTDACRW0 = (VIDLUTDACRW),
- VIDLUTDACRW1 = (VIDLUTDACRW+1),
- VIDLUTDACRW2 = (VIDLUTDACRW+2),
- VIDLUTDACRW3 = (VIDLUTDACRW+3),
- VIDLUTDACRW4 = (VIDLUTDACRW+4),
- VIDLUTDACRW5 = (VIDLUTDACRW+5),
- VIDLUTDACRW6 = (VIDLUTDACRW+6),
- VIDLUTDACRW7 = (VIDLUTDACRW+7),
- VGALUTDACRW = 0x58,
- VGALUTDACRW0 = (VGALUTDACRW),
- VGALUTDACRW1 = (VGALUTDACRW+1),
- VGALUTDACRW2 = (VGALUTDACRW+2),
- VGALUTDACRW3 = (VGALUTDACRW+3),
- VGALUTDACRW4 = (VGALUTDACRW+4),
- VGALUTDACRW5 = (VGALUTDACRW+5),
- VGALUTDACRW6 = (VGALUTDACRW+6),
- VGALUTDACRW7 = (VGALUTDACRW+7),
- HZOOMF = 0x60,
- VZOOMF = 0x61,
- DELAY1 = 0x62,
- DELAY2 = 0x63,
-
- TRILO = 0,
- TRIHI = 1,
- TRIINDEX = 2,
-
- SCL = 0x02,
- SDA = 0x01,
- I2CR = 0x2B,
- SAA7110 = 0x9c,
- WRITE_C = 0x00,
- I2DLY = 5,
-};
-
-enum
-{
- ZR36100 = 0x1e0,
- ZRIRQ = 15,
- ZRDMA = 6,
-
- ZRIDREG = 4, /* offset */
- ZRMACH210 = 6, /* offset */
- ZRREG0 = 8, /* offset */
- ZRREG1 = 10, /* offset */
- ZRSR = ZRREG1, /* offset */
- ZRRDY = (1<<3),
- ZRIDLE = (1<<2),
- ZRREG2 = 12, /* offset */
- ZRREG3 = 14, /* offset */
-
- SIFwidth = 320,
- SIFheight = 240,
-
- IDPCOUNT = 3064,
- PMDPCOUNT = 2048,
- SVMDPCOUNT = 2048,
-
- HIWAT = 2*128*1024,
- DMABLK = 16384,
-};
-
-static struct {
- int zrport;
- int irq;
- int dma;
- int trport;
-} mpegconf;
-
-static char Evmode[] = "video format not supported";
-static char Eaudio[] = "invalid audio layer";
-static char Earate[] = "bad audio sample rate";
-
-/* Status bits depend on board revision */
-static short STDBY;
-static short VIDSEL;
-static short VSNIRQn;
-static short INTENAn;
-static short DSPBOOT;
-static short DSPRST;
-static short MPGRST;
-static int machsr;
-static int dopen;
-static int started;
-static int stop;
-static int pause;
-static int sp2br;
-static int sp2cd;
-static char properties[] = "video mpeg1,sif\naudio musicam,I musicam,II\n";
-static void inittrident(void);
-static int initzoran(void);
-static void initcrystal(void);
-static void mpegintr(Ureg*, void*);
-static void setwindow(int, char**);
-static void freebufs(void);
-static int mkbuf(char*, int);
-
-typedef struct Buf Buf;
-struct Buf
-{
- int nchar;
- uchar* ptr;
- Buf* link;
- uchar data[1];
-};
-
-static struct
-{
- Lock;
- int qlen;
- Buf* head;
- Buf* tail;
- Rendez flow;
-} bqueue;
-
-static int
-zrstatus(void)
-{
- return ins(mpegconf.zrport+ZRSR) & 0xf;
-}
-
-static int
-zrwaitrdy(int timo, char *msg)
-{
- int i;
-
- for(i = 0; i < timo; i++)
- if(ins(mpegconf.zrport+ZRSR) & ZRRDY)
- return 0;
-
- print("devmpeg: device not ready %s\n", msg);
- return 1;
-}
-
-static void
-zrdma(Buf *b)
-{
- int n;
-
- n = dmasetup(mpegconf.dma, b->ptr, b->nchar, 0);
- b->ptr += n;
- b->nchar -= n;
- bqueue.qlen -= n;
-}
-
-static void
-triwr(int reg, int val)
-{
- outb(mpegconf.trport+TRIINDEX, reg);
- outb(mpegconf.trport+TRILO, val);
- outb(mpegconf.trport+TRIHI, val>>8);
-}
-
-static int
-trird(int reg)
-{
- int v;
-
- outb(mpegconf.trport+TRIINDEX, reg);
- v = inb(mpegconf.trport+TRILO);
- v |= inb(mpegconf.trport+TRIHI)<<8;
-
- return v;
-}
-
-enum
-{
- Qdir,
- Qdata,
- Qctl,
-};
-static Dirtab mpegtab[]=
-{
- "mpeg", {Qdata, 0}, 0, 0666,
- "mpegctl", {Qctl, 0}, 0, 0666,
-};
-
-static void
-mpegreset(void)
-{
- ISAConf isa;
-
- mpegconf.zrport = ZR36100;
- mpegconf.irq = ZRIRQ;
- mpegconf.dma = ZRDMA;
-
- memset(&isa, 0, sizeof(isa));
- if(isaconfig("mpeg", 0, &isa) == 0)
- return;
- if(isa.port)
- mpegconf.zrport = isa.port;
- if(isa.irq)
- mpegconf.irq = isa.irq;
- if(isa.dma)
- mpegconf.dma = isa.dma;
- dmainit(mpegconf.dma, 64*1024);
- print("mpeg0: port 0x%uX, irq %d, dma %d\n",
- mpegconf.zrport, mpegconf.irq, mpegconf.dma);
- mpegconf.trport = mpegconf.zrport+0x100;
- intrenable(VectorPIC+mpegconf.irq, mpegintr, 0, BUSUNKNOWN);
-}
-
-static void
-mpeginit(void)
-{
- if(mpegconf.trport == 0)
- return;
-
- inittrident();
- setwindow(0, 0);
-}
-
-static Chan*
-mpegattach(char *spec)
-{
- if(mpegconf.trport == 0)
- error(Enodev);
-
- return devattach('E', spec);
-}
-
-static int
-mpegwalk(Chan *c, char *name)
-{
- return devwalk(c, name, mpegtab, nelem(mpegtab), devgen);
-}
-
-static void
-mpegstat(Chan *c, char *db)
-{
- devstat(c, db, mpegtab, nelem(mpegtab), devgen);
-}
-
-static Chan*
-mpegopen(Chan *c, int omode)
-{
- switch(c->qid.path) {
- default:
- break;
- case Qdata:
- if(dopen)
- error(Einuse);
- dopen = 1;
- break;
- }
- return devopen(c, omode, mpegtab, nelem(mpegtab), devgen);
-}
-
-static void
-mpegclose(Chan *c)
-{
- int i;
-
- switch(c->qid.path) {
- default:
- break;
- case Qdata:
- if((c->flag & COPEN) == 0)
- break;
- if(started) {
- for(i = 0; i < 50; i++) {
- if(ins(mpegconf.zrport+ZRSR) & ZRIDLE)
- break;
- tsleep(&up->sleep, return0, 0, 100);
- }
- }
- if(stop != 0)
- outs(mpegconf.zrport+ZRREG1, 0x1000);
- microdelay(15);
- outs(mpegconf.zrport+ZRREG1, 0x8000);
- freebufs();
- dopen = 0;
- }
-}
-
-static long
-mpegread(Chan *c, void *a, long n, ulong off)
-{
- switch(c->qid.path & ~CHDIR){
- default:
- error(Eperm);
- case Qdir:
- return devdirread(c, a, n, mpegtab, nelem(mpegtab), devgen);
- case Qctl:
- return readstr(off, a, n, properties);
- }
- return 0;
-}
-
-#define SCALE(a, b) ((((a)<<10)/(b))-1024)
-enum
-{
- CWINVF = 0x3ff,
- CWINHF = 0x1da,
-};
-
-static void
-setwindow(int nf, char **field)
-{
- int minx, miny, maxx, maxy, width, height;
-
- if(field == 0) {
- minx = 0;
- miny = 0;
- maxx = 0;
- maxy = 0;
- }
- else {
- if(nf != 5)
- error(Ebadarg);
-
- minx = strtoul(field[1], 0, 0);
- miny = strtoul(field[2], 0, 0);
- maxx = strtoul(field[3], 0, 0) + 8;
- maxy = strtoul(field[4], 0, 0);
- }
-
- triwr(OVLWINHSTRT, minx);
- triwr(OVLWINVSTRT, miny);
- triwr(OVLWINHEND, maxx+12);
- triwr(OVLWINVEND, maxy);
-
- width = maxx - minx;
- height = maxy - miny;
- if(width >= SIFwidth) {
- triwr(HZOOMF, SCALE(width, SIFwidth));
- triwr(CAPWINHMF, CWINHF);
- }
- else {
- triwr(HZOOMF, SCALE(SIFwidth, SIFwidth));
- triwr(CAPWINHMF, width*CWINHF/SIFwidth);
- }
- if(height >= SIFheight) {
- triwr(VZOOMF, SCALE(height, SIFheight));
- triwr(CAPWINVMF, CWINVF);
- }
- else {
- triwr(VZOOMF, SCALE(SIFheight, SIFheight));
- triwr(CAPWINVMF, height*CWINVF/SIFheight);
- }
-}
-
-static int
-mpegflow(void*)
-{
- return bqueue.qlen < HIWAT || stop;
-}
-
-static int
-mkbuf(char *d, int n)
-{
- Buf *b;
-
- b = malloc(sizeof(Buf)+n);
- if(b == 0)
- return 0;
-
- memmove(b->data, d, n);
- b->ptr = b->data;
- b->nchar = n;
- b->link = 0;
-
- ilock(&bqueue);
- bqueue.qlen += n;
- if(bqueue.head)
- bqueue.tail->link = b;
- else
- bqueue.head = b;
- bqueue.tail = b;
- iunlock(&bqueue);
-
- return 1;
-}
-
-static void
-freebufs(void)
-{
- Buf *next;
-
- ilock(&bqueue);
- bqueue.qlen = 0;
- while(bqueue.head) {
- next = bqueue.head->link;
- free(bqueue.head);
- bqueue.head = next;
- }
- iunlock(&bqueue);
-}
-
-typedef struct Audio Audio;
-struct Audio {
- int rate;
- int cd;
- int br;
-};
-
-static Audio AudioclkI[] =
-{
- 64000, 0x000000bb, 0x00071797,
- 96000, 0x0000007d, 0x00071c71,
- 128000, 0x0000005d, 0x00070de1,
- 160000, 0x0000004b, 0x00071c71,
- 192000, 0x0000003e, 0x00070de1,
- 224000, 0x00000035, 0x00070906,
- 256000, 0x0000002e, 0x0006fa76,
- 288000, 0x00000029, 0x0006ff51,
- 320000, 0x00000025, 0x0007042b,
- 352000, 0x00000022, 0x00071797,
- 384000, 0x0000001f, 0x00070de1,
- 416000, 0x0000001c, 0x0006e70b,
- 448000, 0x0000001a, 0x0006e70b,
-};
-
-static Audio AudioclkII[] =
-{
- 48000, 0x000000fa, 0x00071c71,
- 56000, 0x000000d6, 0x00071a04,
- 64000, 0x000000bb, 0x00071797,
- 80000, 0x00000096, 0x00071c71,
- 96000, 0x0000007d, 0x00071c71,
- 112000, 0x0000006b, 0x00071a04,
- 128000, 0x0000005d, 0x00070de1,
- 160000, 0x0000004b, 0x00071c71,
- 192000, 0x0000003e, 0x00070de1,
- 224000, 0x00000035, 0x00070906,
- 256000, 0x0000002e, 0x0006fa76,
- 320000, 0x00000025, 0x0007042b,
- 384000, 0x0000001f, 0x00070de1,
-};
-
-static long
-mpegwrite(Chan *c, char *a, long n, vlong)
-{
- Audio *t;
- int i, nf, l, x;
- char buf[128], *field[10];
-
- switch(c->qid.path & ~CHDIR) {
- case Qctl:
- if(n > sizeof(buf)-1)
- n = sizeof(buf)-1;
- memmove(buf, a, n);
- buf[n] = '\0';
-
- nf = getfields(buf, field, nelem(field), 1, " \t\n");
- if(nf < 1)
- error(Ebadarg);
-
- if(strcmp(field[0], "stop") == 0) {
- if(started == 0)
- error("not started");
- if(pause) {
- pause = 0;
- outs(mpegconf.zrport+ZRREG1, 0x9000);
- }
- stop = 1;
- outs(mpegconf.zrport+ZRREG1, 0x1000);
- microdelay(15);
- outs(mpegconf.zrport+ZRREG1, 0x8000);
- wakeup(&bqueue.flow);
- return n;
- }
- if(strcmp(field[0], "pause") == 0) {
- if(started == 0)
- error("not started");
- if(pause == 0) {
- pause = 1;
- outs(mpegconf.zrport+ZRREG1, 0x1000);
- }
- else {
- pause = 0;
- outs(mpegconf.zrport+ZRREG1, 0x9000);
- }
- return n;
- }
- if(strcmp(field[0], "window") == 0) {
- setwindow(nf, field);
- return n;
- }
- if(strcmp(field[0], "audio") == 0) {
- if(nf < 3)
- error(Ebadarg);
- t = 0;
- if(strcmp(field[1], "musicam,I") == 0)
- t = AudioclkI;
- else
- if(strcmp(field[1], "musicam,II") == 0)
- t = AudioclkII;
- else
- error(Eaudio);
- x = strtoul(field[2], 0, 0);
- for(i = 0; t[i].rate != 0; i++) {
- if(t[i].rate == x) {
- sp2cd = t[i].cd;
- sp2br = t[i].br;
- return n;
- }
- }
- error(Earate);
- }
- if(strcmp(field[0], "video") == 0) {
- if(nf != 3)
- error(Ebadarg);
- if(strcmp(field[1], "iso11172") != 0)
- error(Evmode);
- if(strcmp(field[2], "mpeg1,sif") != 0)
- error(Evmode);
- return n;
- }
- if(strcmp(field[0], "init") == 0) {
- inittrident();
- for(i = 0; i < 3; i++)
- if(initzoran() != -1)
- break;
- initcrystal();
- started = 0;
- stop = 0;
- pause = 0;
- return n;
- }
- error(Ebadarg);
- case Qdata:
- if(n & 1)
- error("odd write");
-
- while(!mpegflow(0))
- sleep(&bqueue.flow, mpegflow, 0);
-
- if(stop)
- error("stopped");
-
- x = n;
- while(x) {
- l = x;
- if(l > DMABLK)
- l = DMABLK;
- if(mkbuf(a, l) == 0)
- error(Enomem);
- x -= l;
- a += l;
- }
- if(started || bqueue.qlen < (HIWAT*3)/4)
- break;
-
- zrdma(bqueue.head);
- outs(mpegconf.zrport+ZRREG1, 0x0000);
- outs(mpegconf.zrport+ZRREG1, 0x0000);
- started = 1;
- break;
- default:
- error(Ebadusefd);
- }
- return n;
-}
-
-Dev mpegdevtab = {
- 'E',
- "mpeg",
-
- mpegreset,
- mpeginit,
- mpegattach,
- devdetach,
- devclone,
- mpegwalk,
- mpegstat,
- mpegopen,
- devcreate,
- mpegclose,
- mpegread,
- devbread,
- mpegwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-static void
-initctl(void)
-{
- int boardid;
- static int done;
-
- if(done)
- return;
-
- boardid = ins(mpegconf.zrport+ZRIDREG);
- if(boardid == 0xE3E3) { /* REV c/d */
- STDBY = 0x0000;
- VIDSEL = 0x2020;
- VSNIRQn = 0x1010;
- INTENAn = 0x0808;
- DSPBOOT = 0x0404;
- DSPRST = 0x0202;
- MPGRST = 0x0101;
- }
- else { /* REV b */
- STDBY = 0x0404;
- VIDSEL = 0x1010;
- VSNIRQn = 0x8080;
- INTENAn = 0x4040;
- DSPBOOT = 0x0202;
- DSPRST = 0x0101;
- MPGRST = 0x2020;
- }
- done = 1;
-
-}
-
-/*
- * nbl (reg 0x1[ab]) was 0x0022, nblf (reg 1[cd]) was 0x0006
- */
-static uchar
-zrparam[] =
-{
-/* 00 */ 0xEF, 0x01, 0x01, 0x01, 0x80, 0x0E, 0x31, 0x00,
-/* 08 */ 0x01, 0x60, 0x00, 0x00, 0x03, 0x5A, 0x00, 0x7A,
-/* 10 */ 0x00, 0x10, 0x00, 0x08, 0x00, 0xF0, 0x00, 0x00,
-/* 18 */ 0x02, 0x0D, 0x00, 0x1e, 0x00, 0x0a, 0x00, 0x02,
-/* 20 */ 0x40, 0x06, 0x80, 0x00, 0x80, 0x00, 0x05, 0x9B,
-/* 28 */ 0x07, 0x16, 0xFD, 0x25, 0xFE, 0xA0, 0x00, 0x00,
-/* 30 */ 0x00, 0x07, 0x0d, 0xe1, 0x00, 0x00, 0x00, 0x3E,
-/* 38 */ 0x00, 0x00, 0x09, 0x51, 0x00, 0x00, 0xCD, 0xFE,
-/* 40 */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 58 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 68 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 70 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 78 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static int
-initzoran(void)
-{
- int i, nbytes, zrs;
-
- initctl();
- freebufs();
-
- machsr = DSPRST|VSNIRQn;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- microdelay(4000);
-
- machsr |= STDBY;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- microdelay(4000);
-
- machsr |= MPGRST;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- microdelay(4000);
- machsr &= ~MPGRST;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- microdelay(4000);
- machsr |= MPGRST;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- microdelay(4000);
-
- if(zrwaitrdy(2000, "load IDP"))
- return -1;
-
- for(i = 0; i < IDPCOUNT; i++)
- outb(mpegconf.zrport+ZRREG2, zrmpeg1[i]);
-
- if(((zrs = zrstatus()) & 3) != 3) {
-/* print("devmpeg: error loading IDP sr=%2.2ux\n", zrs); */
- USED(zrs);
- return -1;
- }
-
- if(zrwaitrdy(2000, "load PMDP"))
- return -1;
-
- for(i = 0; i < PMDPCOUNT; i++)
- outb(mpegconf.zrport+ZRREG3, zrmpeg2[i]);
-
- if(((zrs = zrstatus()) & 3) != 3) {
-/* print("devmpeg: error loading PMDP sr=%2.2ux\n", zrs); */
- USED(zrs);
- return -1;
- }
-
- zrparam[0x36] = sp2cd>>8;
- zrparam[0x37] = sp2cd>>0;
- zrparam[0x31] = sp2br>>16;
- zrparam[0x32] = sp2br>>8;
- zrparam[0x33] = sp2br>>0;
-
- nbytes = 16;
- for(i = 0; i < 128; i++) {
- if(nbytes >= 16) {
- if(zrwaitrdy(2000, "load parameters"))
- return -1;
- nbytes = 0;
- }
- outb(mpegconf.zrport+ZRREG0, zrparam[i]);
- nbytes++;
- }
-
- if(zrwaitrdy(2000, "load SVMDP"))
- return -1;
-
- for(i = 0; i < SVMDPCOUNT; i++)
- outb(mpegconf.zrport+ZRREG3, zrmpeg3s[i]);
-
- if(((zrs = zrstatus()) & 3) != 3) {
-/* print("devmpeg: error loading SVMDP sr=%2.2ux\n", zrs); */
- USED(zrs);
- return -1;
- }
- return 0;
-}
-
-static struct
-{
- short reg;
- ushort val;
-} trireg[] =
-{
- 0x20, 0x0400,
- 0x21, 0x00e9,
- 0x22, 0x0000,
- 0x23, 0x07ee,
- 0x24, 0x0005,
- 0x25, 0xff00,
- 0x26, 0x0000,
- 0x27, 0x7fff,
- 0x28, 0x0004,
- 0x29, 0x88a0,
- 0x2a, 0x0011,
- 0x2b, 0x8540,
- 0x2c, 0x00c4,
- 0x2d, 0x00ac,
- 0x2e, 0x020f,
- 0x2f, 0x019d,
- 0x30, 0x00bd,
- 0x31, 0x00ff,
- 0x32, 0x0000,
- 0x33, 0x0000,
- 0x34, 0x03ff,
- 0x35, 0x0000,
- 0x36, 0x0000,
- 0x37, 0x03ff,
- 0x38, 0x0000,
- 0x39, 0x0000,
- 0x3a, 0x03ff,
- 0x3b, 0x01da,
- 0x3c, 0xe8ce,
- 0x3d, 0x2ac0,
- 0x3e, 0x891f,
- 0x3f, 0x3e25,
- 0x40, 0x03ff,
- 0x41, 0x01ff,
- 0x42, 0x001f,
- 0x43, 0x01ff,
- 0x44, 0x003b,
- 0x45, 0x0186,
- 0x46, 0x1d06,
- 0x47, 0x1a4f,
- 0x48, 0x020d,
- 0x49, 0x01ad,
- 0x4a, 0x001b,
- 0x4b, 0x01fd,
- 0x4c, 0x003a,
- 0x4d, 0x034b,
- 0x4e, 0x2006,
- 0x4f, 0x0083,
- 0x50, 0xef08,
- 0x51, 0xef3a,
- 0x52, 0xefff,
- 0x53, 0xef08,
- 0x54, 0xef08,
- 0x55, 0xef15,
- 0x56, 0xefc0,
- 0x57, 0xef08,
- 0x58, 0xefef,
- 0x59, 0xefef,
- 0x5a, 0xefef,
- 0x5b, 0xefef,
- 0x5c, 0xefef,
- 0x5d, 0xefef,
- 0x5e, 0xefef,
- 0x5f, 0xefef,
- 0x60, 0x0000,
- 0x61, 0x0004,
- 0x62, 0x0020,
- 0x63, 0x8080,
- 0x64, 0x0300,
- -1
-};
-
-static void
-clrI2C(uchar b)
-{
- uchar t;
-
- outb(mpegconf.trport+TRIINDEX, I2CR);
- t = inb(mpegconf.trport+TRIHI);
- t &= ~b;
- outb(mpegconf.trport+TRIHI, t);
-}
-
-static void
-setI2C(uchar b)
-{
- uchar t;
-
- outb(mpegconf.trport+TRIINDEX, I2CR);
- t = inb(mpegconf.trport+TRIHI);
- t |= b;
- outb(mpegconf.trport+TRIHI, t);
-}
-
-static void
-startI2C(void)
-{
- setI2C(SDA);
- setI2C(SCL);
- microdelay(I2DLY);
- clrI2C(SDA);
- microdelay(I2DLY);
- clrI2C(SCL);
- microdelay(I2DLY);
-}
-
-static void
-endI2C(void)
-{
- clrI2C(SDA);
- clrI2C(SCL);
- microdelay(I2DLY);
- setI2C(SCL);
- microdelay(I2DLY);
- setI2C(SDA);
- microdelay(I2DLY);
-}
-
-static void
-wrI2Cbit(uchar b)
-{
- clrI2C(SDA);
- clrI2C(SCL);
- microdelay(I2DLY);
- if(b & 1) {
- setI2C(SDA);
- microdelay(I2DLY);
- setI2C(SCL);
- microdelay(I2DLY);
- clrI2C(SCL);
- microdelay(I2DLY);
- clrI2C(SDA);
- microdelay(I2DLY);
- }
- else {
- setI2C(SCL);
- microdelay(I2DLY);
- clrI2C(SCL);
- microdelay(I2DLY);
- }
-}
-
-static void
-wrI2CB(unsigned char data)
-{
- int i;
-
- for(i = 0; i < 8; i++)
- wrI2Cbit(data >>(7-i));
-}
-
-static int
-rdI2CBit(void)
-{
- int bit = 1;
-
- setI2C(SDA);
- clrI2C(SCL);
- setI2C(SCL);
- outb(mpegconf.trport+TRIINDEX, I2CR);
- if(inb(mpegconf.trport+TRIHI) & SDA)
- bit = 0;
- clrI2C(SDA);
- clrI2C(SCL);
-
- return bit;
-}
-
-static int
-wrI2CD(uchar data)
-{
- int r;
- ulong s;
-
- s = splhi();
- wrI2CB(data);
- r = rdI2CBit();
- splx(s);
- return r;
-}
-
-static uchar
-setupSAA7110[] =
-{
- /* Digital */
- 0x4c, 0x3c, 0x0d, 0xef, 0xbd, 0xf0, 0x40, 0x03,
- 0xf8, 0xf8, 0x90, 0x90, 0x00, 0x02, 0x10, 0x77,
- 0x00, 0x2c, 0x40, 0x40, 0x3b, 0x10, 0xfc, 0xd2,
- 0xf0, 0x80,
-
- /* Analog */
- 0xd9, 0x16, 0x40, 0x40, 0x80, 0x40, 0x80, 0x4f,
- 0xfe, 0x01, 0xcf, 0x0f, 0x03, 0x01, 0x81, 0x0a,
- 0x40, 0x35, 0x02, 0x8c, 0x03
-};
-
-static void
-addrI2CB(int addr, int val)
-{
- ulong s;
-
- s = splhi();
- startI2C();
- wrI2CD(SAA7110|WRITE_C);
- wrI2CD(addr);
- wrI2CD(val);
- endI2C();
- splx(s);
-}
-
-static void
-inittrident(void)
-{
- int i;
-
- for(i = 0; trireg[i].reg != -1; i++)
- triwr(trireg[i].reg, trireg[i].val);
-
- for(i = 0; i < 47; i++)
- addrI2CB(i, setupSAA7110[i]);
-}
-
-static void
-initcrystal(void)
-{
- int i;
- static int done;
-
- if(done)
- return;
-
- done = 1;
-
- initctl();
-
- /* Reboot the Musicam decoder */
- clrI2C(SCL);
- clrI2C(SDA);
- machsr |= DSPRST;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- machsr |= DSPBOOT;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- machsr &= ~DSPRST;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- machsr |= DSPRST;
- outs(mpegconf.zrport+ZRMACH210, machsr);
- machsr &= ~DSPBOOT;
- outs(mpegconf.zrport+ZRMACH210, machsr);
-
- startI2C();
- wrI2CD(0);
- for(i = 0; i < sizeof(crystal); i++ )
- wrI2CD(crystal[i]);
- endI2C();
-}
-
-static void
-mpegintr(Ureg*, void*)
-{
- Buf *b;
-
- b = bqueue.head;
- if(b == 0 || dmadone(mpegconf.dma) == 0)
- return;
-
- dmaend(mpegconf.dma);
- if(b->nchar == 0) {
- bqueue.head = b->link;
- free(b);
-
- b = bqueue.head;
- if(b == 0) {
- started = 0;
- return;
- }
- }
- zrdma(b);
- wakeup(&bqueue.flow);
-}
diff --git a/os/pc/devpccard.c b/os/pc/devpccard.c
deleted file mode 100644
index 3f6a09ca..00000000
--- a/os/pc/devpccard.c
+++ /dev/null
@@ -1,1949 +0,0 @@
-/*
- cardbus and pcmcia (grmph) support.
-*/
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-#define MAP(x,o) (Rmap + (x)*0x8 + o)
-
-enum {
- TI_vid = 0x104c,
- TI_1131_did = 0xAC15,
- TI_1250_did = 0xAC16,
- TI_1450_did = 0xAC1B,
- TI_1251A_did = 0xAC1D,
- TI_1420_did = 0xAC51,
-
- Ricoh_vid = 0x1180,
- Ricoh_475_did = 0x0475,
- Ricoh_476_did = 0x0476,
- Ricoh_478_did = 0x0478,
-
- Nslots = 4, /* Maximum number of CardBus slots to use */
-
- K = 1024,
- M = K * K,
-
- LegacyAddr = 0x3e0,
- NUMEVENTS = 10,
-
- TI1131xSC = 0x80, // system control
- TI122X_SC_INTRTIE = 1 << 29,
- TI12xxIM = 0x8c, //
- TI1131xCC = 0x91, // card control
- TI113X_CC_RIENB = 1 << 7,
- TI113X_CC_ZVENABLE = 1 << 6,
- TI113X_CC_PCI_IRQ_ENA = 1 << 5,
- TI113X_CC_PCI_IREQ = 1 << 4,
- TI113X_CC_PCI_CSC = 1 << 3,
- TI113X_CC_SPKROUTEN = 1 << 1,
- TI113X_CC_IFG = 1 << 0,
- TI1131xDC = 0x92, // device control
-};
-
-typedef struct Variant Variant;
-struct Variant {
- ushort vid;
- ushort did;
- char *name;
-};
-
-static Variant variant[] = {
-{ Ricoh_vid, Ricoh_475_did, "Ricoh 475 PCI/Cardbus bridge", },
-{ Ricoh_vid, Ricoh_476_did, "Ricoh 476 PCI/Cardbus bridge", },
-{ Ricoh_vid, Ricoh_478_did, "Ricoh 478 PCI/Cardbus bridge", },
-{ TI_vid, TI_1131_did, "TI PCI-1131 Cardbus Controller", },
-{ TI_vid, TI_1250_did, "TI PCI-1250 Cardbus Controller", },
-{ TI_vid, TI_1450_did, "TI PCI-1450 Cardbus Controller", },
-{ TI_vid, TI_1251A_did, "TI PCI-1251A Cardbus Controller", },
-{ TI_vid, TI_1420_did, "TI PCI-1420 Cardbus Controller", },
-};
-
-/* Cardbus registers */
-enum {
- SocketEvent = 0,
- SE_CCD = 3 << 1,
- SE_POWER = 1 << 3,
- SocketMask = 1,
- SocketState = 2,
- SS_CCD = 3 << 1,
- SS_POWER = 1 << 3,
- SS_PC16 = 1 << 4,
- SS_CBC = 1 << 5,
- SS_NOTCARD = 1 << 7,
- SS_BADVCC = 1 << 9,
- SS_5V = 1 << 10,
- SS_3V = 1 << 11,
- SocketForce = 3,
- SocketControl = 4,
- SC_5V = 0x22,
- SC_3V = 0x33,
-};
-
-enum {
- PciPCR_IO = 1 << 0,
- PciPCR_MEM = 1 << 1,
- PciPCR_Master = 1 << 2,
-
- PciPMC = 0xa4,
-
- Nbars = 6,
- Ncmd = 10,
- CBIRQ = 9,
-
- PC16,
- PC32,
-};
-
-enum {
- Ti82365,
- Tpd6710,
- Tpd6720,
- Tvg46x,
-};
-
-static char *chipname[] = {
-[Ti82365] "Intel 82365SL",
-[Tpd6710] "Cirrus Logic PD6710",
-[Tpd6720] "Cirrus Logic PD6720",
-[Tvg46x] "Vadem VG-46x",
-};
-
-/*
- * Intel 82365SL PCIC controller for the PCMCIA or
- * Cirrus Logic PD6710/PD6720 which is mostly register compatible
- */
-enum
-{
- /*
- * registers indices
- */
- Rid= 0x0, /* identification and revision */
- Ris= 0x1, /* interface status */
- Rpc= 0x2, /* power control */
- Foutena= (1<<7), /* output enable */
- Fautopower= (1<<5), /* automatic power switching */
- Fcardena= (1<<4), /* PC card enable */
- Rigc= 0x3, /* interrupt and general control */
- Fiocard= (1<<5), /* I/O card (vs memory) */
- Fnotreset= (1<<6), /* reset if not set */
- FSMIena= (1<<4), /* enable change interrupt on SMI */
- Rcsc= 0x4, /* card status change */
- Rcscic= 0x5, /* card status change interrupt config */
- Fchangeena= (1<<3), /* card changed */
- Fbwarnena= (1<<1), /* card battery warning */
- Fbdeadena= (1<<0), /* card battery dead */
- Rwe= 0x6, /* address window enable */
- Fmem16= (1<<5), /* use A23-A12 to decode address */
- Rio= 0x7, /* I/O control */
- Fwidth16= (1<<0), /* 16 bit data width */
- Fiocs16= (1<<1), /* IOCS16 determines data width */
- Fzerows= (1<<2), /* zero wait state */
- Ftiming= (1<<3), /* timing register to use */
- Riobtm0lo= 0x8, /* I/O address 0 start low byte */
- Riobtm0hi= 0x9, /* I/O address 0 start high byte */
- Riotop0lo= 0xa, /* I/O address 0 stop low byte */
- Riotop0hi= 0xb, /* I/O address 0 stop high byte */
- Riobtm1lo= 0xc, /* I/O address 1 start low byte */
- Riobtm1hi= 0xd, /* I/O address 1 start high byte */
- Riotop1lo= 0xe, /* I/O address 1 stop low byte */
- Riotop1hi= 0xf, /* I/O address 1 stop high byte */
- Rmap= 0x10, /* map 0 */
-
- /*
- * CL-PD67xx extension registers
- */
- Rmisc1= 0x16, /* misc control 1 */
- F5Vdetect= (1<<0),
- Fvcc3V= (1<<1),
- Fpmint= (1<<2),
- Fpsirq= (1<<3),
- Fspeaker= (1<<4),
- Finpack= (1<<7),
- Rfifo= 0x17, /* fifo control */
- Fflush= (1<<7), /* flush fifo */
- Rmisc2= 0x1E, /* misc control 2 */
- Flowpow= (1<<1), /* low power mode */
- Rchipinfo= 0x1F, /* chip information */
- Ratactl= 0x26, /* ATA control */
-
- /*
- * offsets into the system memory address maps
- */
- Mbtmlo= 0x0, /* System mem addr mapping start low byte */
- Mbtmhi= 0x1, /* System mem addr mapping start high byte */
- F16bit= (1<<7), /* 16-bit wide data path */
- Mtoplo= 0x2, /* System mem addr mapping stop low byte */
- Mtophi= 0x3, /* System mem addr mapping stop high byte */
- Ftimer1= (1<<6), /* timer set 1 */
- Mofflo= 0x4, /* Card memory offset address low byte */
- Moffhi= 0x5, /* Card memory offset address high byte */
- Fregactive= (1<<6), /* attribute memory */
-
- /*
- * configuration registers - they start at an offset in attribute
- * memory found in the CIS.
- */
- Rconfig= 0,
- Creset= (1<<7), /* reset device */
- Clevel= (1<<6), /* level sensitive interrupt line */
-};
-
-/*
- * read and crack the card information structure enough to set
- * important parameters like power
- */
-/* cis memory walking */
-typedef struct Cisdat Cisdat;
-struct Cisdat {
- uchar *cisbase;
- int cispos;
- int cisskip;
- int cislen;
-};
-
-typedef struct Pcminfo Pcminfo;
-struct Pcminfo {
- char verstr[512]; /* Version string */
- PCMmap mmap[4]; /* maps, last is always for the kernel */
- ulong conf_addr; /* Config address */
- uchar conf_present; /* Config register present */
- int nctab; /* In use configuration tables */
- PCMconftab ctab[8]; /* Configuration tables */
- PCMconftab *defctab; /* Default conftab */
-
- int port; /* Actual port usage */
- int irq; /* Actual IRQ usage */
-};
-
-typedef struct Cardbus Cardbus;
-struct Cardbus {
- Lock;
- Variant *variant; /* Which CardBus chipset */
- Pcidev *pci; /* The bridge itself */
- ulong *regs; /* Cardbus registers */
- int ltype; /* Legacy type */
- int lindex; /* Legacy port index address */
- int ldata; /* Legacy port data address */
- int lbase; /* Base register for this socket */
-
- int state; /* Current state of card */
- int type; /* Type of card */
- Pcminfo linfo; /* PCMCIA slot info */
-
- int special; /* card is allocated to a driver */
-
- int refs; /* Number of refs to slot */
- Lock refslock; /* inc/dev ref lock */
-};
-
-static int managerstarted;
-
-enum {
- Mshift= 12,
- Mgran= (1<<Mshift), /* granularity of maps */
- Mmask= ~(Mgran-1), /* mask for address bits important to the chip */
-};
-
-static Cardbus cbslots[Nslots];
-static int nslots;
-
-static ulong exponent[8] = {
- 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
-};
-
-static ulong vmant[16] = {
- 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
-};
-
-static ulong mantissa[16] = {
- 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80,
-};
-
-static char Enocard[] = "No card in slot";
-
-enum
-{
- CMdown,
- CMpower,
-};
-
-static Cmdtab pccardctlmsg[] =
-{
- CMdown, "down", 2,
- CMpower, "power", 1,
-};
-
-static void cbint(Ureg *, void *);
-static int powerup(Cardbus *);
-static void configure(Cardbus *);
-static void managecard(Cardbus *);
-static void cardmanager(void *);
-static void eject(Cardbus *);
-static void interrupt(Ureg *, void *);
-static void powerdown(Cardbus *cb);
-static void unconfigure(Cardbus *cb);
-
-static void i82365probe(Cardbus *cb, int lindex, int ldata);
-static void i82365configure(Cardbus *cb);
-static PCMmap *isamap(Cardbus *cb, ulong offset, int len, int attr);
-static void isaunmap(PCMmap* m);
-static uchar rdreg(Cardbus *cb, int index);
-static void wrreg(Cardbus *cb, int index, uchar val);
-static int readc(Cisdat *cis, uchar *x);
-static void tvers1(Cardbus *cb, Cisdat *cis, int );
-static void tcfig(Cardbus *cb, Cisdat *cis, int );
-static void tentry(Cardbus *cb, Cisdat *cis, int );
-static int vcode(int volt);
-static int pccard_pcmspecial(char *idstr, ISAConf *isa);
-static void pccard_pcmspecialclose(int slotno);
-
-enum {
- CardDetected,
- CardPowered,
- CardEjected,
- CardConfigured,
-};
-
-static char *messages[] = {
-[CardDetected] "CardDetected",
-[CardPowered] "CardPowered",
-[CardEjected] "CardEjected",
-[CardConfigured] "CardConfigured",
-};
-
-enum {
- SlotEmpty,
- SlotFull,
- SlotPowered,
- SlotConfigured,
-};
-
-static char *states[] = {
-[SlotEmpty] "SlotEmpty",
-[SlotFull] "SlotFull",
-[SlotPowered] "SlotPowered",
-[SlotConfigured] "SlotConfigured",
-};
-
-static void
-engine(Cardbus *cb, int message)
-{
- //print("engine(%d): %s(%s)\n",
- // (int)(cb - cbslots), states[cb->state], messages[message]);
- switch (cb->state) {
- case SlotEmpty:
-
- switch (message) {
- case CardDetected:
- cb->state = SlotFull;
- powerup(cb);
- break;
- case CardEjected:
- break;
- default:
- //print("#Y%d: Invalid message %s in SlotEmpty state\n",
- // (int)(cb - cbslots), messages[message]);
- break;
- }
- break;
-
- case SlotFull:
-
- switch (message) {
- case CardPowered:
- cb->state = SlotPowered;
- configure(cb);
- break;
- case CardEjected:
- cb->state = SlotEmpty;
- powerdown(cb);
- break;
- default:
- //print("#Y%d: Invalid message %s in SlotFull state\n",
- // (int)(cb - cbslots), messages[message]);
- break;
- }
- break;
-
- case SlotPowered:
-
- switch (message) {
- case CardConfigured:
- cb->state = SlotConfigured;
- break;
- case CardEjected:
- cb->state = SlotEmpty;
- unconfigure(cb);
- powerdown(cb);
- break;
- default:
- //print("#Y%d: Invalid message %s in SlotPowered state\n",
- // (int)(cb - cbslots), messages[message]);
- break;
- }
- break;
-
- case SlotConfigured:
-
- switch (message) {
- case CardEjected:
- cb->state = SlotEmpty;
- unconfigure(cb);
- powerdown(cb);
- break;
- default:
- //print("#Y%d: Invalid message %s in SlotConfigured state\n",
- // (int)(cb - cbslots), messages[message]);
- break;
- }
- break;
- }
-}
-
-static void
-qengine(Cardbus *cb, int message)
-{
- lock(cb);
- engine(cb, message);
- unlock(cb);
-}
-
-typedef struct Events Events;
-struct Events {
- Cardbus *cb;
- int message;
-};
-
-static Lock levents;
-static Events events[NUMEVENTS];
-static Rendez revents;
-static int nevents;
-
-static void
-iengine(Cardbus *cb, int message)
-{
- if (nevents >= NUMEVENTS) {
- print("#Y: Too many events queued, discarding request\n");
- return;
- }
- ilock(&levents);
- events[nevents].cb = cb;
- events[nevents].message = message;
- nevents++;
- iunlock(&levents);
- wakeup(&revents);
-}
-
-static int
-eventoccured(void)
-{
- return nevents > 0;
-}
-
-static void
-processevents(void *)
-{
- while (1) {
- int message;
- Cardbus *cb;
-
- sleep(&revents, (int (*)(void *))eventoccured, nil);
-
- cb = nil;
- message = 0;
- ilock(&levents);
- if (nevents > 0) {
- cb = events[0].cb;
- message = events[0].message;
- nevents--;
- if (nevents > 0)
- memmove(events, &events[1], nevents * sizeof(Events));
- }
- iunlock(&levents);
-
- if (cb)
- qengine(cb, message);
- }
-}
-
-static void
-cbinterrupt(Ureg *, void *)
-{
- int i;
-
- for (i = 0; i != nslots; i++) {
- Cardbus *cb = &cbslots[i];
- ulong event, state;
-
- event= cb->regs[SocketEvent];
- state = cb->regs[SocketState];
- rdreg(cb, Rcsc); /* Ack the interrupt */
-
- //print("interrupt: slot %d, event %.8lX, state %.8lX, (%s)\n",
- // (int)(cb - cbslots), event, state, states[cb->state]);
-
- if (event & SE_CCD) {
- cb->regs[SocketEvent] |= SE_CCD; /* Ack interrupt */
- if (state & SE_CCD) {
- if (cb->state != SlotEmpty) {
- print("#Y: take cardejected interrupt\n");
- iengine(cb, CardEjected);
- }
- }
- else
- iengine(cb, CardDetected);
- }
-
- if (event & SE_POWER) {
- cb->regs[SocketEvent] |= SE_POWER; /* Ack interrupt */
- iengine(cb, CardPowered);
- }
- }
-}
-
-void
-devpccardlink(void)
-{
- static int initialized;
- Pcidev *pci;
- int i;
- uchar intl;
- char *p;
-
- if (initialized)
- return;
- initialized = 1;
-
- if((p=getconf("pccard0")) && strncmp(p, "disabled", 8)==0)
- return;
-
- if(_pcmspecial)
- return;
-
- /* Allocate legacy space */
- if (ioalloc(LegacyAddr, 2, 0, "i82365.0") < 0)
- print("#Y: WARNING: Cannot allocate legacy ports\n");
-
- /* Find all CardBus controllers */
- pci = nil;
- intl = (uchar)-1;
- while ((pci = pcimatch(pci, 0, 0)) != nil) {
- ulong baddr;
- Cardbus *cb;
- int slot;
- uchar pin;
-
- for (i = 0; i != nelem(variant); i++)
- if (pci->vid == variant[i].vid && pci->did == variant[i].did)
- break;
- if (i == nelem(variant))
- continue;
-
- /* initialize this slot */
- slot = nslots++;
- cb = &cbslots[slot];
-
- cb->pci = pci;
- cb->variant = &variant[i];
-
- if (pci->vid != TI_vid) {
- // Gross hack, needs a fix. Inherit the mappings from 9load
- // for the TIs (pb)
- pcicfgw32(pci, PciCBMBR0, 0xffffffff);
- pcicfgw32(pci, PciCBMLR0, 0);
- pcicfgw32(pci, PciCBMBR1, 0xffffffff);
- pcicfgw32(pci, PciCBMLR1, 0);
- pcicfgw32(pci, PciCBIBR0, 0xffffffff);
- pcicfgw32(pci, PciCBILR0, 0);
- pcicfgw32(pci, PciCBIBR1, 0xffffffff);
- pcicfgw32(pci, PciCBILR1, 0);
- }
-
- // Set up PCI bus numbers if needed.
- if (pcicfgr8(pci, PciSBN) == 0) {
- static int busbase = 0x20;
-
- pcicfgw8(pci, PciSBN, busbase);
- pcicfgw8(pci, PciUBN, busbase + 2);
- busbase += 3;
- }
-
- // Patch up intl if needed.
- if ((pin = pcicfgr8(pci, PciINTP)) != 0 &&
- (pci->intl == 0xff || pci->intl == 0)) {
- pci->intl = pciipin(nil, pin);
- pcicfgw8(pci, PciINTL, pci->intl);
-
- if (pci->intl == 0xff || pci->intl == 0)
- print("#Y%d: No interrupt?\n", (int)(cb - cbslots));
- }
-
- // Don't you love standards!
- if (pci->vid == TI_vid) {
- if (pci->did <= TI_1131_did) {
- uchar cc;
-
- cc = pcicfgr8(pci, TI1131xCC);
- cc &= ~(TI113X_CC_PCI_IRQ_ENA |
- TI113X_CC_PCI_IREQ |
- TI113X_CC_PCI_CSC |
- TI113X_CC_ZVENABLE);
- cc |= TI113X_CC_PCI_IRQ_ENA |
- TI113X_CC_PCI_IREQ |
- TI113X_CC_SPKROUTEN;
- pcicfgw8(pci, TI1131xCC, cc);
-
- // PCI interrupts only
- pcicfgw8(pci, TI1131xDC,
- pcicfgr8(pci, TI1131xDC) & ~6);
-
- // CSC ints to PCI bus.
- wrreg(cb, Rigc, rdreg(cb, Rigc) | 0x10);
- }
- else if (pci->did == TI_1250_did) {
- print("No support yet for the TI_1250_did, prod pb\n");
- }
- else if (pci->did == TI_1420_did) {
- // Disable Vcc protection
- pcicfgw32(cb->pci, 0x80,
- pcicfgr32(cb->pci, 0x80) | (1 << 21));
- }
-
- pcicfgw16(cb->pci, PciPMC, pcicfgr16(cb->pci, PciPMC) & ~3);
- }
-
- if (intl != -1 && intl != pci->intl)
- intrenable(pci->intl, cbinterrupt, cb, pci->tbdf, "cardbus");
- intl = pci->intl;
-
- if ((baddr = pcicfgr32(cb->pci, PciBAR0)) == 0) {
- int align = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;
-
- baddr = upamalloc(baddr, align, align);
- pcicfgw32(cb->pci, PciBAR0, baddr);
- cb->regs = (ulong *)KADDR(baddr);
- }
- else
- cb->regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0));
- cb->state = SlotEmpty;
-
- /* Don't really know what to do with this... */
- i82365probe(cb, LegacyAddr, LegacyAddr + 1);
-
- print("#Y%ld: %s, %.8ulX intl %d\n", cb - cbslots,
- variant[i].name, baddr, pci->intl);
- }
-
- if (nslots == 0){
- iofree(LegacyAddr);
- return;
- }
-
- _pcmspecial = pccard_pcmspecial;
- _pcmspecialclose = pccard_pcmspecialclose;
-
- for (i = 0; i != nslots; i++) {
- Cardbus *cb = &cbslots[i];
-
- if ((cb->regs[SocketState] & SE_CCD) == 0)
- engine(cb, CardDetected);
- }
-
- delay(500); /* Allow time for power up */
-
- for (i = 0; i != nslots; i++) {
- Cardbus *cb = &cbslots[i];
-
- if (cb->regs[SocketState] & SE_POWER)
- engine(cb, CardPowered);
-
- /* Ack and enable interrupts on all events */
- // cb->regs[SocketEvent] = cb->regs[SocketEvent];
- cb->regs[SocketMask] |= 0xF;
- wrreg(cb, Rcscic, 0xC);
- }
-}
-
-static int
-powerup(Cardbus *cb)
-{
- ulong state;
- ushort bcr;
-
- state = cb->regs[SocketState];
- if (state & SS_PC16) {
-
- // print("#Y%ld: Probed a PC16 card, powering up card\n", cb - cbslots);
- cb->type = PC16;
- memset(&cb->linfo, 0, sizeof(Pcminfo));
-
- /* power up and unreset, wait's are empirical (???) */
- wrreg(cb, Rpc, Fautopower|Foutena|Fcardena);
- delay(300);
- wrreg(cb, Rigc, 0);
- delay(100);
- wrreg(cb, Rigc, Fnotreset);
- delay(500);
-
- return 1;
- }
-
- if (state & SS_CCD)
- return 0;
-
- if (state & SS_NOTCARD) {
- print("#Y%ld: Not a card inserted\n", cb - cbslots);
- return 0;
- }
-
- if ((state & SS_3V) == 0 && (state & SS_5V) == 0) {
- print("#Y%ld: Unsupported voltage, powering down card!\n",
- cb - cbslots);
- cb->regs[SocketControl] = 0;
- return 0;
- }
-
- //print("#Y%ld: card %spowered at %d volt\n", cb - cbslots,
- // (state & SS_POWER)? "": "not ",
- // (state & SS_3V)? 3: (state & SS_5V)? 5: -1);
-
- /* Power up the card
- * and make sure the secondary bus is not in reset.
- */
- cb->regs[SocketControl] = (state & SS_5V)? SC_5V: SC_3V;
- delay(50);
- bcr = pcicfgr16(cb->pci, PciBCR);
- bcr &= ~0x40;
- pcicfgw16(cb->pci, PciBCR, bcr);
- delay(100);
-
- cb->type = (state & SS_PC16)? PC16: PC32;
- return 1;
-}
-
-static void
-powerdown(Cardbus *cb)
-{
- ushort bcr;
-
- if (cb->type == PC16) {
-
- wrreg(cb, Rpc, 0); /* turn off card power */
- wrreg(cb, Rwe, 0); /* no windows */
-
- cb->type = -1;
- return;
- }
-
- bcr = pcicfgr16(cb->pci, PciBCR);
- bcr |= 0x40;
- pcicfgw16(cb->pci, PciBCR, bcr);
- cb->regs[SocketControl] = 0;
- cb->type = -1;
-}
-
-static void
-configure(Cardbus *cb)
-{
- int i;
- Pcidev *pci;
-
- //print("configuring slot %d (%s)\n", (int)(cb - cbslots), states[cb->state]);
- if (cb->state == SlotConfigured)
- return;
- engine(cb, CardConfigured);
-
- delay(50); /* Emperically established */
-
- if (cb->type == PC16) {
- i82365configure(cb);
- return;
- }
-
- /* Scan the CardBus for new PCI devices */
- pciscan(pcicfgr8(cb->pci, PciSBN), &cb->pci->bridge);
- pci = cb->pci->bridge;
- while (pci) {
- ulong size, bar;
- int memindex, ioindex;
-
- pcicfgw16(pci, PciPCR,
- pcicfgr16(pci, PciPCR) & ~(PciPCR_IO|PciPCR_MEM));
-
- /* Treat the found device as an ordinary PCI card. It seems that the
- CIS is not always present in CardBus cards. XXX, need to support
- multifunction cards */
- memindex = ioindex = 0;
- for (i = 0; i != Nbars; i++) {
-
- if (pci->mem[i].size == 0) continue;
- if (pci->mem[i].bar & 1) {
-
- // Allocate I/O space
- if (ioindex > 1) {
- print("#Y%ld: WARNING: Can only configure 2 I/O slots\n", cb - cbslots);
- continue;
- }
- bar = ioreserve(-1, pci->mem[i].size, 0, "cardbus");
-
- pci->mem[i].bar = bar | 1;
- pcicfgw32(pci, PciBAR0 + i * sizeof(ulong),
- pci->mem[i].bar);
- pcicfgw16(cb->pci, PciCBIBR0 + ioindex * 8, bar);
- pcicfgw16(cb->pci, PciCBILR0 + ioindex * 8,
- bar + pci->mem[i].size - 1);
- //print("ioindex[%d] %.8uX (%d)\n",
- // ioindex, bar, pci->mem[i].size);
- ioindex++;
- continue;
- }
-
- // Allocating memory space
- if (memindex > 1) {
- print("#Y%ld: WARNING: Can only configure 2 memory slots\n", cb - cbslots);
- continue;
- }
-
- bar = upamalloc(0, pci->mem[i].size, BY2PG);
- pci->mem[i].bar = bar | (pci->mem[i].bar & 0x80);
- pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), pci->mem[i].bar);
- pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, bar);
- pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8,
- bar + pci->mem[i].size - 1);
-
- if (pci->mem[i].bar & 0x80)
- /* Enable prefetch */
- pcicfgw16(cb->pci, PciBCR,
- pcicfgr16(cb->pci, PciBCR) |
- (1 << (8 + memindex)));
-
- //print("memindex[%d] %.8uX (%d)\n",
- // memindex, bar, pci->mem[i].size);
- memindex++;
- }
-
- if ((size = pcibarsize(pci, PciEBAR0)) > 0) {
-
- if (memindex > 1)
- print("#Y%ld: WARNING: Too many memory spaces, not mapping ROM space\n",
- cb - cbslots);
- else {
- pci->rom.bar = upamalloc(0, size, BY2PG);
- pci->rom.size = size;
-
- pcicfgw32(pci, PciEBAR0, pci->rom.bar);
- pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8,
- pci->rom.bar);
- pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8,
- pci->rom.bar + pci->rom.size - 1);
- }
- }
-
- /* Set the basic PCI registers for the device */
- pci->pcr = pcicfgr16(pci, PciPCR) | PciPCR_IO|PciPCR_MEM|PciPCR_Master;
- pci->cls = 8;
- pci->ltr = 64;
- pcicfgw16(pci, PciPCR, pci->pcr);
- pcicfgw8(pci, PciCLS, pci->cls);
- pcicfgw8(pci, PciLTR, pci->ltr);
-
- if (pcicfgr8(pci, PciINTP)) {
- pci->intl = pcicfgr8(cb->pci, PciINTL);
- pcicfgw8(pci, PciINTL, pci->intl);
-
- /* Route interrupts to INTA#/B# */
- pcicfgw16(cb->pci, PciBCR,
- pcicfgr16(cb->pci, PciBCR) & ~(1 << 7));
- }
-
- pci = pci->list;
- }
-}
-
-static void
-unconfigure(Cardbus *cb)
-{
- Pcidev *pci;
- int i, ioindex, memindex;
-
- if (cb->type == PC16) {
- print("#Y%d: Don't know how to unconfigure a PC16 card\n",
- (int)(cb - cbslots));
-
- memset(&cb->linfo, 0, sizeof(Pcminfo));
- return;
- }
-
- pci = cb->pci->bridge;
- if (pci == nil)
- return; /* Not configured */
- cb->pci->bridge = nil;
-
- memindex = ioindex = 0;
- while (pci) {
- Pcidev *_pci;
-
- for (i = 0; i != Nbars; i++) {
- if (pci->mem[i].size == 0) continue;
- if (pci->mem[i].bar & 1) {
- iofree(pci->mem[i].bar & ~1);
- pcicfgw16(cb->pci, PciCBIBR0 + ioindex * 8,
- (ushort)-1);
- pcicfgw16(cb->pci, PciCBILR0 + ioindex * 8, 0);
- ioindex++;
- continue;
- }
-
- upafree(pci->mem[i].bar & ~0xF, pci->mem[i].size);
- pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8,
- (ulong)-1);
- pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 0);
- pcicfgw16(cb->pci, PciBCR,
- pcicfgr16(cb->pci, PciBCR) &
- ~(1 << (8 + memindex)));
- memindex++;
- }
-
- if (pci->rom.bar && memindex < 2) {
- upafree(pci->rom.bar & ~0xF, pci->rom.size);
- pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8,
- (ulong)-1);
- pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 0);
- memindex++;
- }
-
- _pci = pci->list;
- free(_pci);
- pci = _pci;
- }
-}
-
-static void
-i82365configure(Cardbus *cb)
-{
- int this;
- Cisdat cis;
- PCMmap *m;
- uchar type, link;
-
- /*
- * Read all tuples in attribute space.
- */
- m = isamap(cb, 0, 0, 1);
- if(m == 0)
- return;
-
- cis.cisbase = KADDR(m->isa);
- cis.cispos = 0;
- cis.cisskip = 2;
- cis.cislen = m->len;
-
- /* loop through all the tuples */
- for(;;){
- this = cis.cispos;
- if(readc(&cis, &type) != 1)
- break;
- if(type == 0xFF)
- break;
- if(readc(&cis, &link) != 1)
- break;
-
- switch(type){
- default:
- break;
- case 0x15:
- tvers1(cb, &cis, type);
- break;
- case 0x1A:
- tcfig(cb, &cis, type);
- break;
- case 0x1B:
- tentry(cb, &cis, type);
- break;
- }
-
- if(link == 0xFF)
- break;
- cis.cispos = this + (2+link);
- }
- isaunmap(m);
-}
-
-/*
- * look for a card whose version contains 'idstr'
- */
-static int
-pccard_pcmspecial(char *idstr, ISAConf *isa)
-{
- int i, irq;
- PCMconftab *ct, *et;
- Pcminfo *pi;
- Cardbus *cb;
- uchar x, we, *p;
-
- cb = nil;
- for (i = 0; i != nslots; i++) {
- cb = &cbslots[i];
-
- lock(cb);
- if (cb->state == SlotConfigured &&
- cb->type == PC16 &&
- !cb->special &&
- strstr(cb->linfo.verstr, idstr))
- break;
- unlock(cb);
- }
-
- if (i == nslots) {
- // print("#Y: %s not found\n", idstr);
- return -1;
- }
-
- pi = &cb->linfo;
-
- /*
- * configure the PCMslot for IO. We assume very heavily that we can read
- * configuration info from the CIS. If not, we won't set up correctly.
- */
- irq = isa->irq;
- if(irq == 2)
- irq = 9;
-
- et = &pi->ctab[pi->nctab];
- ct = nil;
- for(i = 0; i < isa->nopt; i++){
- int index;
- char *cp;
-
- if(strncmp(isa->opt[i], "index=", 6))
- continue;
- index = strtol(&isa->opt[i][6], &cp, 0);
- if(cp == &isa->opt[i][6] || index >= pi->nctab) {
- unlock(cb);
- print("#Y%d: Cannot find index %d in conf table\n",
- (int)(cb - cbslots), index);
- return -1;
- }
- ct = &pi->ctab[index];
- }
-
- if(ct == nil){
- PCMconftab *t;
-
- /* assume default is right */
- if(pi->defctab)
- ct = pi->defctab;
- else
- ct = pi->ctab;
-
- /* try for best match */
- if(ct->nio == 0
- || ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){
- for(t = pi->ctab; t < et; t++)
- if(t->nio
- && t->io[0].start == isa->port
- && ((1<<irq) & t->irqs)){
- ct = t;
- break;
- }
- }
- if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){
- for(t = pi->ctab; t < et; t++)
- if(t->nio && ((1<<irq) & t->irqs)){
- ct = t;
- break;
- }
- }
- if(ct->nio == 0){
- for(t = pi->ctab; t < et; t++)
- if(t->nio){
- ct = t;
- break;
- }
- }
- }
-
- if(ct == et || ct->nio == 0) {
- unlock(cb);
- print("#Y%d: No configuration?\n", (int)(cb - cbslots));
- return -1;
- }
- if(isa->port == 0 && ct->io[0].start == 0) {
- unlock(cb);
- print("#Y%d: No part or start address\n", (int)(cb - cbslots));
- return -1;
- }
-
- cb->special = 1; /* taken */
-
- /* route interrupts */
- isa->irq = irq;
- wrreg(cb, Rigc, irq | Fnotreset | Fiocard);
-
- /* set power and enable device */
- x = vcode(ct->vpp1);
- wrreg(cb, Rpc, x|Fautopower|Foutena|Fcardena);
-
- /* 16-bit data path */
- if(ct->bit16)
- x = Ftiming|Fiocs16|Fwidth16;
- else
- x = Ftiming;
- if(ct->nio == 2 && ct->io[1].start)
- x |= x<<4;
- wrreg(cb, Rio, x);
-
- /*
- * enable io port map 0
- * the 'top' register value includes the last valid address
- */
- if(isa->port == 0)
- isa->port = ct->io[0].start;
- we = rdreg(cb, Rwe);
- wrreg(cb, Riobtm0lo, isa->port);
- wrreg(cb, Riobtm0hi, isa->port>>8);
- i = isa->port+ct->io[0].len-1;
- wrreg(cb, Riotop0lo, i);
- wrreg(cb, Riotop0hi, i>>8);
- we |= 1<<6;
- if(ct->nio == 2 && ct->io[1].start){
- wrreg(cb, Riobtm1lo, ct->io[1].start);
- wrreg(cb, Riobtm1hi, ct->io[1].start>>8);
- i = ct->io[1].start+ct->io[1].len-1;
- wrreg(cb, Riotop1lo, i);
- wrreg(cb, Riotop1hi, i>>8);
- we |= 1<<7;
- }
- wrreg(cb, Rwe, we);
-
- /* only touch Rconfig if it is present */
- if(pi->conf_present & (1<<Rconfig)){
- PCMmap *m;
-
- /* Reset adapter */
- m = isamap(cb, pi->conf_addr + Rconfig, 1, 1);
- p = KADDR(m->isa + pi->conf_addr + Rconfig - m->ca);
-
- /* set configuration and interrupt type */
- x = ct->index;
- if(ct->irqtype & 0x20)
- x |= Clevel;
- *p = x;
- delay(5);
-
- isaunmap(m);
- }
-
- pi->port = isa->port;
- pi->irq = isa->irq;
- unlock(cb);
-
- print("#Y%d: %s irq %d, port %lX\n", (int)(cb - cbslots), pi->verstr, isa->irq, isa->port);
- return (int)(cb - cbslots);
-}
-
-static void
-pccard_pcmspecialclose(int slotno)
-{
- Cardbus *cb = &cbslots[slotno];
-
- wrreg(cb, Rwe, 0); /* no windows */
- cb->special = 0;
-}
-
-static int
-xcistuple(int slotno, int tuple, int subtuple, void *v, int nv, int attr)
-{
- PCMmap *m;
- Cisdat cis;
- int i, l;
- uchar *p;
- uchar type, link, n, c;
- int this, subtype;
- Cardbus *cb = &cbslots[slotno];
-
- m = isamap(cb, 0, 0, attr);
- if(m == 0)
- return -1;
-
- cis.cisbase = KADDR(m->isa);
- cis.cispos = 0;
- cis.cisskip = attr ? 2 : 1;
- cis.cislen = m->len;
-
- /* loop through all the tuples */
- for(i = 0; i < 1000; i++){
- this = cis.cispos;
- if(readc(&cis, &type) != 1)
- break;
- if(type == 0xFF)
- break;
- if(readc(&cis, &link) != 1)
- break;
- if(link == 0xFF)
- break;
-
- n = link;
- if (link > 1 && subtuple != -1) {
- if (readc(&cis, &c) != 1)
- break;
- subtype = c;
- n--;
- } else
- subtype = -1;
-
- if(type == tuple && subtype == subtuple) {
- p = v;
- for(l=0; l<nv && l<n; l++)
- if(readc(&cis, p++) != 1)
- break;
- isaunmap(m);
- return nv;
- }
- cis.cispos = this + (2+link);
- }
- isaunmap(m);
- return -1;
-}
-
-static Chan*
-pccardattach(char *spec)
-{
- if (!managerstarted) {
- managerstarted = 1;
- kproc("cardbus", processevents, nil);
- }
- return devattach('Y', spec);
-}
-
-enum
-{
- Qdir,
- Qctl,
-
- Nents = 1,
-};
-
-#define SLOTNO(c) ((ulong)((c->qid.path>>8)&0xff))
-#define TYPE(c) ((ulong)(c->qid.path&0xff))
-#define QID(s,t) (((s)<<8)|(t))
-
-static int
-pccardgen(Chan *c, char*, Dirtab *, int , int i, Dir *dp)
-{
- int slotno;
- Qid qid;
- long len;
- int entry;
-
- if(i == DEVDOTDOT){
- mkqid(&qid, Qdir, 0, QTDIR);
- devdir(c, qid, "#Y", 0, eve, 0555, dp);
- return 1;
- }
-
- len = 0;
- if(i >= Nents * nslots) return -1;
- slotno = i / Nents;
- entry = i % Nents;
- if (entry == 0) {
- qid.path = QID(slotno, Qctl);
- snprint(up->genbuf, sizeof up->genbuf, "cb%dctl", slotno);
- }
- else {
- /* Entries for memory regions. I'll implement them when
- needed. (pb) */
- }
- qid.vers = 0;
- qid.type = QTFILE;
- devdir(c, qid, up->genbuf, len, eve, 0660, dp);
- return 1;
-}
-
-static Walkqid*
-pccardwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, 0, 0, pccardgen);
-}
-
-static int
-pccardstat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, 0, 0, pccardgen);
-}
-
-static void
-increfp(Cardbus *cb)
-{
- lock(&cb->refslock);
- cb->refs++;
- unlock(&cb->refslock);
-}
-
-static void
-decrefp(Cardbus *cb)
-{
- lock(&cb->refslock);
- cb->refs--;
- unlock(&cb->refslock);
-}
-
-static Chan*
-pccardopen(Chan *c, int omode)
-{
- if (c->qid.type & QTDIR){
- if(omode != OREAD)
- error(Eperm);
- } else
- increfp(&cbslots[SLOTNO(c)]);
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-static void
-pccardclose(Chan *c)
-{
- if(c->flag & COPEN)
- if((c->qid.type & QTDIR) == 0)
- decrefp(&cbslots[SLOTNO(c)]);
-}
-
-static long
-pccardread(Chan *c, void *a, long n, vlong offset)
-{
- Cardbus *cb;
- char *buf, *p, *e;
- int i;
-
- switch(TYPE(c)){
- case Qdir:
- return devdirread(c, a, n, 0, 0, pccardgen);
-
- case Qctl:
- buf = p = malloc(READSTR);
- buf[0] = 0;
- e = p + READSTR;
-
- cb = &cbslots[SLOTNO(c)];
- lock(cb);
- p = seprint(p, e, "slot %ld: %s; ", cb - cbslots, states[cb->state]);
-
- switch (cb->type) {
- case -1:
- seprint(p, e, "\n");
- break;
-
- case PC32:
- if (cb->pci->bridge) {
- Pcidev *pci = cb->pci->bridge;
- int i;
-
- while (pci) {
- p = seprint(p, e, "%.4uX %.4uX; irq %d\n",
- pci->vid, pci->did, pci->intl);
- for (i = 0; i != Nbars; i++)
- if (pci->mem[i].size)
- p = seprint(p, e,
- "\tmem[%d] %.8ulX (%.8uX)\n",
- i, pci->mem[i].bar,
- pci->mem[i].size);
- if (pci->rom.size)
- p = seprint(p, e, "\tROM %.8ulX (%.8uX)\n",
- pci->rom.bar, pci->rom.size);
- pci = pci->list;
- }
- }
- break;
-
- case PC16:
- if (cb->state == SlotConfigured) {
- Pcminfo *pi = &cb->linfo;
-
- p = seprint(p, e, "%s port %X; irq %d;\n",
- pi->verstr, pi->port,
- pi->irq);
- for (i = 0; i != pi->nctab; i++) {
- PCMconftab *ct;
- int j;
-
- ct = &pi->ctab[i];
- p = seprint(p, e,
- "\tconfiguration[%d] irqs %.4uX; vpp %d, %d; %s\n",
- i, ct->irqs, ct->vpp1, ct->vpp2,
- (ct == pi->defctab)? "(default);": "");
- for (j = 0; j != ct->nio; j++)
- if (ct->io[j].len > 0)
- p = seprint(p, e, "\t\tio[%d] %.8ulX %uld\n",
- j, ct->io[j].start, ct->io[j].len);
- }
- }
- break;
- }
- unlock(cb);
-
- n = readstr(offset, a, n, buf);
- free(buf);
- return n;
- }
- return 0;
-}
-
-static long
-pccardwrite(Chan *c, void *v, long n, vlong)
-{
- Rune r;
- ulong n0;
- char *device;
- Cmdbuf *cbf;
- Cmdtab *ct;
- Cardbus *cb;
-
- n0 = n;
- switch(TYPE(c)){
- case Qctl:
- cb = &cbslots[SLOTNO(c)];
-
- cbf = parsecmd(v, n);
- if(waserror()){
- free(cbf);
- nexterror();
- }
- ct = lookupcmd(cbf, pccardctlmsg, nelem(pccardctlmsg));
- switch(ct->index){
- case CMdown:
- device = cbf->f[1];
- device += chartorune(&r, device);
- if ((n = devno(r, 1)) >= 0 && devtab[n]->config)
- devtab[n]->config(0, device, nil);
- qengine(cb, CardEjected);
- break;
- case CMpower:
- if ((cb->regs[SocketState] & SS_CCD) == 0)
- qengine(cb, CardDetected);
- break;
- }
- poperror();
- free(cbf);
- break;
- }
- return n0 - n;
-}
-
-Dev pccarddevtab = {
- 'Y',
- "cardbus",
-
- devreset,
- devinit,
- devshutdown,
- pccardattach,
- pccardwalk,
- pccardstat,
- pccardopen,
- devcreate,
- pccardclose,
- pccardread,
- devbread,
- pccardwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-static PCMmap *
-isamap(Cardbus *cb, ulong offset, int len, int attr)
-{
- uchar we, bit;
- PCMmap *m, *nm;
- Pcminfo *pi;
- int i;
- ulong e;
-
- pi = &cb->linfo;
-
- /* convert offset to granularity */
- if(len <= 0)
- len = 1;
- e = ROUND(offset+len, Mgran);
- offset &= Mmask;
- len = e - offset;
-
- /* look for a map that covers the right area */
- we = rdreg(cb, Rwe);
- bit = 1;
- nm = 0;
- for(m = pi->mmap; m < &pi->mmap[nelem(pi->mmap)]; m++){
- if((we & bit))
- if(m->attr == attr)
- if(offset >= m->ca && e <= m->cea){
-
- m->ref++;
- return m;
- }
- bit <<= 1;
- if(nm == 0 && m->ref == 0)
- nm = m;
- }
- m = nm;
- if(m == 0)
- return 0;
-
- /* if isa space isn't big enough, free it and get more */
- if(m->len < len){
- if(m->isa){
- umbfree(m->isa, m->len);
- m->len = 0;
- }
- m->isa = PADDR(umbmalloc(0, len, Mgran));
- if(m->isa == 0){
- print("isamap: out of isa space\n");
- return 0;
- }
- m->len = len;
- }
-
- /* set up new map */
- m->ca = offset;
- m->cea = m->ca + m->len;
- m->attr = attr;
- i = m - pi->mmap;
- bit = 1<<i;
- wrreg(cb, Rwe, we & ~bit); /* disable map before changing it */
- wrreg(cb, MAP(i, Mbtmlo), m->isa>>Mshift);
- wrreg(cb, MAP(i, Mbtmhi), (m->isa>>(Mshift+8)) | F16bit);
- wrreg(cb, MAP(i, Mtoplo), (m->isa+m->len-1)>>Mshift);
- wrreg(cb, MAP(i, Mtophi), ((m->isa+m->len-1)>>(Mshift+8)));
- offset -= m->isa;
- offset &= (1<<25)-1;
- offset >>= Mshift;
- wrreg(cb, MAP(i, Mofflo), offset);
- wrreg(cb, MAP(i, Moffhi), (offset>>8) | (attr ? Fregactive : 0));
- wrreg(cb, Rwe, we | bit); /* enable map */
- m->ref = 1;
-
- return m;
-}
-
-static void
-isaunmap(PCMmap* m)
-{
- m->ref--;
-}
-
-/*
- * reading and writing card registers
- */
-static uchar
-rdreg(Cardbus *cb, int index)
-{
- outb(cb->lindex, cb->lbase + index);
- return inb(cb->ldata);
-}
-
-static void
-wrreg(Cardbus *cb, int index, uchar val)
-{
- outb(cb->lindex, cb->lbase + index);
- outb(cb->ldata, val);
-}
-
-static int
-readc(Cisdat *cis, uchar *x)
-{
- if(cis->cispos >= cis->cislen)
- return 0;
- *x = cis->cisbase[cis->cisskip*cis->cispos];
- cis->cispos++;
- return 1;
-}
-
-static ulong
-getlong(Cisdat *cis, int size)
-{
- uchar c;
- int i;
- ulong x;
-
- x = 0;
- for(i = 0; i < size; i++){
- if(readc(cis, &c) != 1)
- break;
- x |= c<<(i*8);
- }
- return x;
-}
-
-static void
-tcfig(Cardbus *cb, Cisdat *cis, int )
-{
- uchar size, rasize, rmsize;
- uchar last;
- Pcminfo *pi;
-
- if(readc(cis, &size) != 1)
- return;
- rasize = (size&0x3) + 1;
- rmsize = ((size>>2)&0xf) + 1;
- if(readc(cis, &last) != 1)
- return;
-
- pi = &cb->linfo;
- pi->conf_addr = getlong(cis, rasize);
- pi->conf_present = getlong(cis, rmsize);
-}
-
-static void
-tvers1(Cardbus *cb, Cisdat *cis, int )
-{
- uchar c, major, minor, last;
- int i;
- Pcminfo *pi;
-
- pi = &cb->linfo;
- if(readc(cis, &major) != 1)
- return;
- if(readc(cis, &minor) != 1)
- return;
- last = 0;
- for(i = 0; i < sizeof(pi->verstr) - 1; i++){
- if(readc(cis, &c) != 1)
- return;
- if(c == 0)
- c = ';';
- if(c == '\n')
- c = ';';
- if(c == 0xff)
- break;
- if(c == ';' && last == ';')
- continue;
- pi->verstr[i] = c;
- last = c;
- }
- pi->verstr[i] = 0;
-}
-
-static ulong
-microvolt(Cisdat *cis)
-{
- uchar c;
- ulong microvolts;
- ulong exp;
-
- if(readc(cis, &c) != 1)
- return 0;
- exp = exponent[c&0x7];
- microvolts = vmant[(c>>3)&0xf]*exp;
- while(c & 0x80){
- if(readc(cis, &c) != 1)
- return 0;
- switch(c){
- case 0x7d:
- break; /* high impedence when sleeping */
- case 0x7e:
- case 0x7f:
- microvolts = 0; /* no connection */
- break;
- default:
- exp /= 10;
- microvolts += exp*(c&0x7f);
- }
- }
- return microvolts;
-}
-
-static ulong
-nanoamps(Cisdat *cis)
-{
- uchar c;
- ulong nanoamps;
-
- if(readc(cis, &c) != 1)
- return 0;
- nanoamps = exponent[c&0x7]*vmant[(c>>3)&0xf];
- while(c & 0x80){
- if(readc(cis, &c) != 1)
- return 0;
- if(c == 0x7d || c == 0x7e || c == 0x7f)
- nanoamps = 0;
- }
- return nanoamps;
-}
-
-/*
- * only nominal voltage (feature 1) is important for config,
- * other features must read card to stay in sync.
- */
-static ulong
-power(Cisdat *cis)
-{
- uchar feature;
- ulong mv;
-
- mv = 0;
- if(readc(cis, &feature) != 1)
- return 0;
- if(feature & 1)
- mv = microvolt(cis);
- if(feature & 2)
- microvolt(cis);
- if(feature & 4)
- microvolt(cis);
- if(feature & 8)
- nanoamps(cis);
- if(feature & 0x10)
- nanoamps(cis);
- if(feature & 0x20)
- nanoamps(cis);
- if(feature & 0x40)
- nanoamps(cis);
- return mv/1000000;
-}
-
-static ulong
-ttiming(Cisdat *cis, int scale)
-{
- uchar unscaled;
- ulong nanosecs;
-
- if(readc(cis, &unscaled) != 1)
- return 0;
- nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
- nanosecs = nanosecs * exponent[scale];
- return nanosecs;
-}
-
-static void
-timing(Cisdat *cis, PCMconftab *ct)
-{
- uchar c, i;
-
- if(readc(cis, &c) != 1)
- return;
- i = c&0x3;
- if(i != 3)
- ct->maxwait = ttiming(cis, i); /* max wait */
- i = (c>>2)&0x7;
- if(i != 7)
- ct->readywait = ttiming(cis, i); /* max ready/busy wait */
- i = (c>>5)&0x7;
- if(i != 7)
- ct->otherwait = ttiming(cis, i); /* reserved wait */
-}
-
-static void
-iospaces(Cisdat *cis, PCMconftab *ct)
-{
- uchar c;
- int i, nio;
-
- ct->nio = 0;
- if(readc(cis, &c) != 1)
- return;
-
- ct->bit16 = ((c>>5)&3) >= 2;
- if(!(c & 0x80)){
- ct->io[0].start = 0;
- ct->io[0].len = 1<<(c&0x1f);
- ct->nio = 1;
- return;
- }
-
- if(readc(cis, &c) != 1)
- return;
-
- /*
- * For each of the range descriptions read the
- * start address and the length (value is length-1).
- */
- nio = (c&0xf)+1;
- for(i = 0; i < nio; i++){
- ct->io[i].start = getlong(cis, (c>>4)&0x3);
- ct->io[i].len = getlong(cis, (c>>6)&0x3)+1;
- }
- ct->nio = nio;
-}
-
-static void
-irq(Cisdat *cis, PCMconftab *ct)
-{
- uchar c;
-
- if(readc(cis, &c) != 1)
- return;
- ct->irqtype = c & 0xe0;
- if(c & 0x10)
- ct->irqs = getlong(cis, 2);
- else
- ct->irqs = 1<<(c&0xf);
- ct->irqs &= 0xDEB8; /* levels available to card */
-}
-
-static void
-memspace(Cisdat *cis, int asize, int lsize, int host)
-{
- ulong haddress, address, len;
-
- len = getlong(cis, lsize)*256;
- address = getlong(cis, asize)*256;
- USED(len, address);
- if(host){
- haddress = getlong(cis, asize)*256;
- USED(haddress);
- }
-}
-
-static void
-tentry(Cardbus *cb, Cisdat *cis, int )
-{
- uchar c, i, feature;
- PCMconftab *ct;
- Pcminfo *pi;
-
- pi = &cb->linfo;
- if(pi->nctab >= nelem(pi->ctab))
- return;
- if(readc(cis, &c) != 1)
- return;
- ct = &pi->ctab[pi->nctab++];
-
- /* copy from last default config */
- if(pi->defctab)
- *ct = *pi->defctab;
-
- ct->index = c & 0x3f;
-
- /* is this the new default? */
- if(c & 0x40)
- pi->defctab = ct;
-
- /* memory wait specified? */
- if(c & 0x80){
- if(readc(cis, &i) != 1)
- return;
- if(i&0x80)
- ct->memwait = 1;
- }
-
- if(readc(cis, &feature) != 1)
- return;
- switch(feature&0x3){
- case 1:
- ct->vpp1 = ct->vpp2 = power(cis);
- break;
- case 2:
- power(cis);
- ct->vpp1 = ct->vpp2 = power(cis);
- break;
- case 3:
- power(cis);
- ct->vpp1 = power(cis);
- ct->vpp2 = power(cis);
- break;
- default:
- break;
- }
- if(feature&0x4)
- timing(cis, ct);
- if(feature&0x8)
- iospaces(cis, ct);
- if(feature&0x10)
- irq(cis, ct);
- switch((feature>>5)&0x3){
- case 1:
- memspace(cis, 0, 2, 0);
- break;
- case 2:
- memspace(cis, 2, 2, 0);
- break;
- case 3:
- if(readc(cis, &c) != 1)
- return;
- for(i = 0; i <= (c&0x7); i++)
- memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
- break;
- }
-}
-
-static void
-i82365probe(Cardbus *cb, int lindex, int ldata)
-{
- uchar c, id;
- int dev = 0; /* According to the Ricoh spec 00->3F _and_ 80->BF seem
- to be the same socket A (ditto for B). */
-
- outb(lindex, Rid + (dev<<7));
- id = inb(ldata);
- if((id & 0xf0) != 0x80)
- return; /* not a memory & I/O card */
- if((id & 0x0f) == 0x00)
- return; /* no revision number, not possible */
-
- cb->lindex = lindex;
- cb->ldata = ldata;
- cb->ltype = Ti82365;
- cb->lbase = (int)(cb - cbslots) * 0x40;
-
- switch(id){
- case 0x82:
- case 0x83:
- case 0x84:
- /* could be a cirrus */
- outb(cb->lindex, Rchipinfo + (dev<<7));
- outb(cb->ldata, 0);
- c = inb(cb->ldata);
- if((c & 0xc0) != 0xc0)
- break;
- c = inb(cb->ldata);
- if((c & 0xc0) != 0x00)
- break;
- if(c & 0x20){
- cb->ltype = Tpd6720;
- } else {
- cb->ltype = Tpd6710;
- }
- break;
- }
-
- /* if it's not a Cirrus, it could be a Vadem... */
- if(cb->ltype == Ti82365){
- /* unlock the Vadem extended regs */
- outb(cb->lindex, 0x0E + (dev<<7));
- outb(cb->lindex, 0x37 + (dev<<7));
-
- /* make the id register show the Vadem id */
- outb(cb->lindex, 0x3A + (dev<<7));
- c = inb(cb->ldata);
- outb(cb->ldata, c|0xC0);
- outb(cb->lindex, Rid + (dev<<7));
- c = inb(cb->ldata);
- if(c & 0x08)
- cb->ltype = Tvg46x;
-
- /* go back to Intel compatible id */
- outb(cb->lindex, 0x3A + (dev<<7));
- c = inb(cb->ldata);
- outb(cb->ldata, c & ~0xC0);
- }
-}
-
-static int
-vcode(int volt)
-{
- switch(volt){
- case 5:
- return 1;
- case 12:
- return 2;
- default:
- return 0;
- }
-}
-
diff --git a/os/pc/devpnp.c b/os/pc/devpnp.c
deleted file mode 100644
index fe4c05dd..00000000
--- a/os/pc/devpnp.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- * ISA PNP 1.0 support + access to PCI configuration space
- *
- * TODO
- * - implement PNP card configuration (setting io bases etc)
- * - write user program to drive PNP configuration...
- * - extend PCI raw access to configuration space (writes, byte/short access?)
- * - implement PCI access to memory/io space/BIOS ROM
- * - use c->aux instead of performing lookup on each read/write?
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-typedef struct Pnp Pnp;
-typedef struct Card Card;
-
-struct Pnp
-{
- QLock;
- int rddata;
- int debug;
- Card *cards;
-};
-
-struct Card
-{
- int csn;
- ulong id1;
- ulong id2;
- char *cfgstr;
- int ncfg;
- Card* next;
-};
-
-static Pnp pnp;
-
-#define DPRINT if(pnp.debug) print
-#define XPRINT if(1) print
-
-enum {
- Address = 0x279,
- WriteData = 0xa79,
-
- Qtopdir = 0,
-
- Qpnpdir,
- Qpnpctl,
- Qcsnctl,
- Qcsnraw,
-
- Qpcidir,
- Qpcictl,
- Qpciraw,
-};
-
-#define TYPE(q) ((ulong)(q).path & 0x0F)
-#define CSN(q) (((ulong)(q).path>>4) & 0xFF)
-#define QID(c, t) (((c)<<4)|(t))
-
-static Dirtab topdir[] = {
- ".", { Qtopdir, 0, QTDIR }, 0, 0555,
- "pnp", { Qpnpdir, 0, QTDIR }, 0, 0555,
- "pci", { Qpcidir, 0, QTDIR }, 0, 0555,
-};
-
-static Dirtab pnpdir[] = {
- ".", { Qpnpdir, 0, QTDIR }, 0, 0555,
- "ctl", { Qpnpctl, 0, 0 }, 0, 0666,
-};
-
-extern Dev pnpdevtab;
-static int wrconfig(Card*, char*);
-
-static char key[32] =
-{
- 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,
- 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,
- 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,
- 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39,
-};
-
-static void
-cmd(int reg, int val)
-{
- outb(Address, reg);
- outb(WriteData, val);
-}
-
-/* Send initiation key, putting each card in Sleep state */
-static void
-initiation(void)
-{
- int i;
-
- /* ensure each card's LFSR is reset */
- outb(Address, 0x00);
- outb(Address, 0x00);
-
- /* send initiation key */
- for (i = 0; i < 32; i++)
- outb(Address, key[i]);
-}
-
-/* isolation protocol... */
-static int
-readbit(int rddata)
-{
- int r1, r2;
-
- r1 = inb(rddata);
- r2 = inb(rddata);
- microdelay(250);
- return (r1 == 0x55) && (r2 == 0xaa);
-}
-
-static int
-isolate(int rddata, ulong *id1, ulong *id2)
-{
- int i, csum, bit;
- uchar *p, id[9];
-
- outb(Address, 0x01); /* point to serial isolation register */
- delay(1);
- csum = 0x6a;
- for(i = 0; i < 64; i++){
- bit = readbit(rddata);
- csum = (csum>>1) | (((csum&1) ^ ((csum>>1)&1) ^ bit)<<7);
- p = &id[i>>3];
- *p = (*p>>1) | (bit<<7);
- }
- for(; i < 72; i++){
- p = &id[i>>3];
- *p = (*p>>1) | (readbit(rddata)<<7);
- }
- *id1 = (id[3]<<24)|(id[2]<<16)|(id[1]<<8)|id[0];
- *id2 = (id[7]<<24)|(id[6]<<16)|(id[5]<<8)|id[4];
- if(*id1 == 0)
- return 0;
- if(id[8] != csum)
- DPRINT("pnp: bad checksum id1 %lux id2 %lux csum %x != %x\n", *id1, *id2, csum, id[8]); /**/
- return id[8] == csum;
-}
-
-static int
-getresbyte(int rddata)
-{
- int tries = 0;
-
- outb(Address, 0x05);
- while ((inb(rddata) & 1) == 0)
- if (tries++ > 1000000)
- error("pnp: timeout waiting for resource data\n");
- outb(Address, 0x04);
- return inb(rddata);
-}
-
-static char *
-serial(ulong id1, ulong id2)
-{
- int i1, i2, i3;
- ulong x;
- static char buf[20];
-
- i1 = (id1>>2)&31;
- i2 = ((id1<<3)&24)+((id1>>13)&7);
- i3 = (id1>>8)&31;
- x = (id1>>8)&0xff00|(id1>>24)&0x00ff;
- if (i1 > 0 && i1 < 27 && i2 > 0 && i2 < 27 && i3 > 0 && i3 < 27 && (id1 & (1<<7)) == 0)
- snprint(buf, sizeof(buf), "%c%c%c%.4lux.%lux", 'A'+i1-1, 'A'+i2-1, 'A'+i3-1, x, id2);
- else
- snprint(buf, sizeof(buf), "%.4lux%.4lux.%lux", (id1<<8)&0xff00|(id1>>8)&0x00ff, x, id2);
- return buf;
-}
-
-static Card *
-findcsn(int csn, int create, int dolock)
-{
- Card *c, *nc, **l;
-
- if(dolock)
- qlock(&pnp);
- l = &pnp.cards;
- for(c = *l; c != nil; c = *l) {
- if(c->csn == csn)
- goto done;
- if(c->csn > csn)
- break;
- l = &c->next;
- }
- if(create) {
- *l = nc = malloc(sizeof(Card));
- nc->next = c;
- nc->csn = csn;
- c = nc;
- }
-done:
- if(dolock)
- qunlock(&pnp);
- return c;
-}
-
-static int
-newcsn(void)
-{
- int csn;
- Card *c;
-
- csn = 1;
- for(c = pnp.cards; c != nil; c = c->next) {
- if(c->csn > csn)
- break;
- csn = c->csn+1;
- }
- return csn;
-}
-
-static int
-pnpncfg(int rddata)
-{
- int i, n, x, ncfg, n1, n2;
-
- ncfg = 0;
- for (;;) {
- x = getresbyte(rddata);
- if((x & 0x80) == 0) {
- n = (x&7)+1;
- for(i = 1; i < n; i++)
- getresbyte(rddata);
- }
- else {
- n1 = getresbyte(rddata);
- n2 = getresbyte(rddata);
- n = (n2<<8)|n1 + 3;
- for (i = 3; i < n; i++)
- getresbyte(rddata);
- }
- ncfg += n;
- if((x>>3) == 0x0f)
- break;
- }
- return ncfg;
-}
-
-/* look for cards, and assign them CSNs */
-static int
-pnpscan(int rddata, int dawn)
-{
- Card *c;
- int csn;
- ulong id1, id2;
-
- initiation(); /* upsilon sigma */
- cmd(0x02, 0x04+0x01); /* reset CSN on all cards and reset logical devices */
- delay(1); /* delay after resetting cards */
-
- cmd(0x03, 0); /* Wake all cards with a CSN of 0 */
- cmd(0x00, rddata>>2); /* Set the READ_DATA port on all cards */
- while(isolate(rddata, &id1, &id2)) {
- for(c = pnp.cards; c != nil; c = c->next)
- if(c->id1 == id1 && c->id2 == id2)
- break;
- if(c == nil) {
- csn = newcsn();
- c = findcsn(csn, 1, 0);
- c->id1 = id1;
- c->id2 = id2;
- }
- else if(c->cfgstr != nil) {
- if(!wrconfig(c, c->cfgstr))
- print("pnp%d: bad cfg: %s\n", c->csn, c->cfgstr);
- c->cfgstr = nil;
- }
- cmd(0x06, c->csn); /* set the card's csn */
- if(dawn)
- print("pnp%d: %s\n", c->csn, serial(id1, id2));
- c->ncfg = pnpncfg(rddata);
- cmd(0x03, 0); /* Wake all cards with a CSN of 0, putting this card to sleep */
- }
- cmd(0x02, 0x02); /* return cards to Wait for Key state */
- if(pnp.cards != 0) {
- pnp.rddata = rddata;
- return 1;
- }
- return 0;
-}
-
-static void
-pnpreset(void)
-{
- Card *c;
- ulong id1, id2;
- int csn, i1, i2, i3, x;
- char *s, *p, buf[20];
- ISAConf isa;
-
- memset(&isa, 0, sizeof(ISAConf));
- pnp.rddata = -1;
- if (isaconfig("pnp", 0, &isa) == 0)
- return;
- if(isa.port < 0x203 || isa.port > 0x3ff)
- return;
- for(csn = 1; csn < 256; csn++) {
- sprint(buf, "pnp%d", csn);
- s = getconf(buf);
- if(s == 0)
- continue;
- if(strlen(s) < 8 || s[7] != '.' || s[0] < 'A' || s[0] > 'Z' || s[1] < 'A' || s[1] > 'Z' || s[2] < 'A' || s[2] > 'Z') {
-bad:
- print("pnp%d: bad conf string %s\n", csn, s);
- continue;
- }
- i1 = s[0]-'A'+1;
- i2 = s[1]-'A'+1;
- i3 = s[2]-'A'+1;
- x = strtoul(&s[3], 0, 16);
- id1 = (i1<<2)|((i2>>3)&3)|((i2&7)<<13)|(i3<<8)|((x&0xff)<<24)|((x&0xff00)<<8);
- id2 = strtoul(&s[8], &p, 16);
- if(*p == ' ')
- p++;
- else if(*p == '\0')
- p = nil;
- else
- goto bad;
- c = findcsn(csn, 1, 0);
- c->id1 = id1;
- c->id2 = id2;
- c->cfgstr = p;
- }
- pnpscan(isa.port, 1);
-}
-
-static int
-csngen(Chan *c, int t, int csn, Card *cp, Dir *dp)
-{
- Qid q;
-
- switch(t) {
- case Qcsnctl:
- q = (Qid){QID(csn, Qcsnctl), 0, 0};
- sprint(up->genbuf, "csn%dctl", csn);
- devdir(c, q, up->genbuf, 0, eve, 0664, dp);
- return 1;
- case Qcsnraw:
- q = (Qid){QID(csn, Qcsnraw), 0, 0};
- sprint(up->genbuf, "csn%draw", csn);
- devdir(c, q, up->genbuf, cp->ncfg, eve, 0444, dp);
- return 1;
- }
- return -1;
-}
-
-static int
-pcigen(Chan *c, int t, int tbdf, Dir *dp)
-{
- Qid q;
-
- q = (Qid){BUSBDF(tbdf)|t, 0, 0};
- switch(t) {
- case Qpcictl:
- sprint(up->genbuf, "%d.%d.%dctl", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
- devdir(c, q, up->genbuf, 0, eve, 0444, dp);
- return 1;
- case Qpciraw:
- sprint(up->genbuf, "%d.%d.%draw", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
- devdir(c, q, up->genbuf, 128, eve, 0444, dp);
- return 1;
- }
- return -1;
-}
-
-static int
-pnpgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
-{
- Qid q;
- Card *cp;
- Pcidev *p;
- int csn, tbdf;
-
- switch(TYPE(c->qid)){
- case Qtopdir:
- if(s == DEVDOTDOT){
- q = (Qid){QID(0, Qtopdir), 0, QTDIR};
- sprint(up->genbuf, "#%C", pnpdevtab.dc);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- return devgen(c, nil, topdir, nelem(topdir), s, dp);
- case Qpnpdir:
- if(s == DEVDOTDOT){
- q = (Qid){QID(0, Qtopdir), 0, QTDIR};
- sprint(up->genbuf, "#%C", pnpdevtab.dc);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- if(s < nelem(pnpdir)-1)
- return devgen(c, nil, pnpdir, nelem(pnpdir), s, dp);
- s -= nelem(pnpdir)-1;
- qlock(&pnp);
- cp = pnp.cards;
- while(s >= 2 && cp != nil) {
- s -= 2;
- cp = cp->next;
- }
- qunlock(&pnp);
- if(cp == nil)
- return -1;
- return csngen(c, s+Qcsnctl, cp->csn, cp, dp);
- case Qpnpctl:
- return devgen(c, nil, pnpdir, nelem(pnpdir), s, dp);
- case Qcsnctl:
- case Qcsnraw:
- csn = CSN(c->qid);
- cp = findcsn(csn, 0, 1);
- if(cp == nil)
- return -1;
- return csngen(c, TYPE(c->qid), csn, cp, dp);
- case Qpcidir:
- if(s == DEVDOTDOT){
- q = (Qid){QID(0, Qtopdir), 0, QTDIR};
- sprint(up->genbuf, "#%C", pnpdevtab.dc);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- p = pcimatch(nil, 0, 0);
- while(s >= 2 && p != nil) {
- p = pcimatch(p, 0, 0);
- s -= 2;
- }
- if(p == nil)
- return -1;
- return pcigen(c, s+Qpcictl, p->tbdf, dp);
- case Qpcictl:
- case Qpciraw:
- tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path);
- p = pcimatchtbdf(tbdf);
- if(p == nil)
- return -1;
- return pcigen(c, TYPE(c->qid), tbdf, dp);
- default:
- break;
- }
- return -1;
-}
-
-static Chan*
-pnpattach(char *spec)
-{
- return devattach(pnpdevtab.dc, spec);
-}
-
-Walkqid*
-pnpwalk(Chan* c, Chan *nc, char** name, int nname)
-{
- return devwalk(c, nc, name, nname, (Dirtab *)0, 0, pnpgen);
-}
-
-static int
-pnpstat(Chan* c, uchar* dp, int n)
-{
- return devstat(c, dp, n, (Dirtab *)0, 0L, pnpgen);
-}
-
-static Chan*
-pnpopen(Chan *c, int omode)
-{
- c = devopen(c, omode, (Dirtab*)0, 0, pnpgen);
- switch(TYPE(c->qid)){
- default:
- break;
- }
- return c;
-}
-
-static void
-pnpclose(Chan*)
-{
-}
-
-static long
-pnpread(Chan *c, void *va, long n, vlong offset)
-{
- ulong x;
- Card *cp;
- Pcidev *p;
- char buf[256], *ebuf, *w;
- char *a = va;
- int csn, i, tbdf, r;
-
- switch(TYPE(c->qid)){
- case Qtopdir:
- case Qpnpdir:
- case Qpcidir:
- return devdirread(c, a, n, (Dirtab *)0, 0L, pnpgen);
- case Qpnpctl:
- if(pnp.rddata > 0)
- sprint(up->genbuf, "enabled 0x%x\n", pnp.rddata);
- else
- sprint(up->genbuf, "disabled\n");
- return readstr(offset, a, n, up->genbuf);
- case Qcsnraw:
- csn = CSN(c->qid);
- cp = findcsn(csn, 0, 1);
- if(cp == nil)
- error(Egreg);
- if(offset+n > cp->ncfg)
- n = cp->ncfg - offset;
- qlock(&pnp);
- initiation();
- cmd(0x03, csn); /* Wake up the card */
- for(i = 0; i < offset+9; i++) /* 9 == skip serial + csum */
- getresbyte(pnp.rddata);
- for(i = 0; i < n; i++)
- a[i] = getresbyte(pnp.rddata);
- cmd(0x03, 0); /* Wake all cards with a CSN of 0, putting this card to sleep */
- cmd(0x02, 0x02); /* return cards to Wait for Key state */
- qunlock(&pnp);
- break;
- case Qcsnctl:
- csn = CSN(c->qid);
- cp = findcsn(csn, 0, 1);
- if(cp == nil)
- error(Egreg);
- sprint(up->genbuf, "%s\n", serial(cp->id1, cp->id2));
- return readstr(offset, a, n, up->genbuf);
- case Qpcictl:
- tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path);
- p = pcimatchtbdf(tbdf);
- if(p == nil)
- error(Egreg);
- ebuf = buf+sizeof buf-1; /* -1 for newline */
- w = seprint(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d",
- p->ccrb, p->ccru, p->ccrp, p->vid, p->did, p->intl);
- for(i=0; i<nelem(p->mem); i++){
- if(p->mem[i].size == 0)
- continue;
- w = seprint(w, ebuf, " %d:%.8lux %d", i, p->mem[i].bar, p->mem[i].size);
- }
- *w++ = '\n';
- *w = '\0';
- return readstr(offset, a, n, buf);
- case Qpciraw:
- tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path);
- p = pcimatchtbdf(tbdf);
- if(p == nil)
- error(Egreg);
- if(offset > 256)
- return 0;
- if(n+offset > 256)
- n = 256-offset;
- if(offset%4)
- error(Ebadarg);
- r = offset;
- for(i = 0; i+4 <= n; i+=4) {
- x = pcicfgr32(p, r);
- a[0] = x;
- a[1] = (x>>8);
- a[2] = (x>>16);
- a[3] = (x>>24);
- a += 4;
- r += 4;
- }
- return i;
- default:
- error(Egreg);
- }
- return n;
-}
-
-static long
-pnpwrite(Chan *c, void *a, long n, vlong)
-{
- int csn;
- Card *cp;
- ulong port;
- char buf[256];
-
- if(n >= sizeof(buf))
- n = sizeof(buf)-1;
- strncpy(buf, a, n);
- buf[n] = 0;
-
- switch(TYPE(c->qid)){
- case Qpnpctl:
- if(strncmp(buf, "port ", 5) == 0) {
- port = strtoul(buf+5, 0, 0);
- if(port < 0x203 || port > 0x3ff)
- error("bad value for rddata port");
- qlock(&pnp);
- if(waserror()) {
- qunlock(&pnp);
- nexterror();
- }
- if(pnp.rddata > 0)
- error("pnp port already set");
- if(!pnpscan(port, 0))
- error("no cards found");
- qunlock(&pnp);
- poperror();
- }
- else if(strncmp(buf, "debug ", 6) == 0)
- pnp.debug = strtoul(buf+6, 0, 0);
- else
- error(Ebadctl);
- break;
- case Qcsnctl:
- csn = CSN(c->qid);
- cp = findcsn(csn, 0, 1);
- if(cp == nil)
- error(Egreg);
- if(!wrconfig(cp, buf))
- error(Ebadctl);
- break;
- default:
- error(Egreg);
- }
- return n;
-}
-
-static int
-wrconfig(Card *c, char *cmd)
-{
- /* This should implement setting of I/O bases, etc */
- USED(c, cmd);
- return 1;
-}
-
-
-Dev pnpdevtab = {
- '$',
- "pnp",
-
- pnpreset,
- devinit,
- devshutdown,
- pnpattach,
- pnpwalk,
- pnpstat,
- pnpopen,
- devcreate,
- pnpclose,
- pnpread,
- devbread,
- pnpwrite,
- devbwrite,
- devremove,
- devwstat,
-};
diff --git a/os/pc/devrtc.c b/os/pc/devrtc.c
deleted file mode 100644
index f6e1d911..00000000
--- a/os/pc/devrtc.c
+++ /dev/null
@@ -1,461 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-/*
- * real time clock and non-volatile ram
- */
-
-enum {
- Paddr= 0x70, /* address port */
- Pdata= 0x71, /* data port */
-
- Seconds= 0x00,
- Minutes= 0x02,
- Hours= 0x04,
- Mday= 0x07,
- Month= 0x08,
- Year= 0x09,
- Status= 0x0A,
-
- Nvoff= 128, /* where usable nvram lives */
- Nvsize= 256,
-
- Nbcd= 6,
-};
-
-typedef struct Rtc Rtc;
-struct Rtc
-{
- int sec;
- int min;
- int hour;
- int mday;
- int mon;
- int year;
-};
-
-
-enum{
- Qdir = 0,
- Qrtc,
- Qnvram,
-};
-
-Dirtab rtcdir[]={
- ".", {Qdir, 0, QTDIR}, 0, 0555,
- "nvram", {Qnvram, 0}, Nvsize, 0664,
- "rtc", {Qrtc, 0}, 0, 0664,
-};
-
-static ulong rtc2sec(Rtc*);
-static void sec2rtc(ulong, Rtc*);
-
-void
-rtcinit(void)
-{
- if(ioalloc(Paddr, 2, 0, "rtc/nvr") < 0)
- panic("rtcinit: ioalloc failed");
-}
-
-static Chan*
-rtcattach(char* spec)
-{
- return devattach('r', spec);
-}
-
-static Walkqid*
-rtcwalk(Chan* c, Chan *nc, char** name, int nname)
-{
- return devwalk(c, nc, name, nname, rtcdir, nelem(rtcdir), devgen);
-}
-
-static int
-rtcstat(Chan* c, uchar* dp, int n)
-{
- return devstat(c, dp, n, rtcdir, nelem(rtcdir), devgen);
-}
-
-static Chan*
-rtcopen(Chan* c, int omode)
-{
- omode = openmode(omode);
- switch((ulong)c->qid.path){
- case Qrtc:
- if(strcmp(up->env->user, eve)!=0 && omode!=OREAD)
- error(Eperm);
- break;
- case Qnvram:
- if(strcmp(up->env->user, eve)!=0)
- error(Eperm);
- }
- return devopen(c, omode, rtcdir, nelem(rtcdir), devgen);
-}
-
-static void
-rtcclose(Chan*)
-{
-}
-
-#define GETBCD(o) ((bcdclock[o]&0xf) + 10*(bcdclock[o]>>4))
-
-static long
-_rtctime(void)
-{
- uchar bcdclock[Nbcd];
- Rtc rtc;
- int i;
-
- /* don't do the read until the clock is no longer busy */
- for(i = 0; i < 10000; i++){
- outb(Paddr, Status);
- if(inb(Pdata) & 0x80)
- continue;
-
- /* read clock values */
- outb(Paddr, Seconds); bcdclock[0] = inb(Pdata);
- outb(Paddr, Minutes); bcdclock[1] = inb(Pdata);
- outb(Paddr, Hours); bcdclock[2] = inb(Pdata);
- outb(Paddr, Mday); bcdclock[3] = inb(Pdata);
- outb(Paddr, Month); bcdclock[4] = inb(Pdata);
- outb(Paddr, Year); bcdclock[5] = inb(Pdata);
-
- outb(Paddr, Status);
- if((inb(Pdata) & 0x80) == 0)
- break;
- }
-
- /*
- * convert from BCD
- */
- rtc.sec = GETBCD(0);
- rtc.min = GETBCD(1);
- rtc.hour = GETBCD(2);
- rtc.mday = GETBCD(3);
- rtc.mon = GETBCD(4);
- rtc.year = GETBCD(5);
-
- /*
- * the world starts jan 1 1970
- */
- if(rtc.year < 70)
- rtc.year += 2000;
- else
- rtc.year += 1900;
- return rtc2sec(&rtc);
-}
-
-static Lock nvrtlock;
-
-long
-rtctime(void)
-{
- int i;
- long t, ot;
-
- ilock(&nvrtlock);
-
- /* loop till we get two reads in a row the same */
- t = _rtctime();
- for(i = 0; i < 100; i++){
- ot = t;
- t = _rtctime();
- if(ot == t)
- break;
- }
- if(i == 100) print("we are boofheads\n");
-
- iunlock(&nvrtlock);
-
- return t;
-}
-
-static long
-rtcread(Chan* c, void* buf, long n, vlong off)
-{
- ulong t;
- char *a, *start;
- ulong offset = off;
-
- if(c->qid.type & QTDIR)
- return devdirread(c, buf, n, rtcdir, nelem(rtcdir), devgen);
-
- switch((ulong)c->qid.path){
- case Qrtc:
- t = rtctime();
- n = readnum(offset, buf, n, t, 12);
- return n;
- case Qnvram:
- if(n == 0)
- return 0;
- if(n > Nvsize)
- n = Nvsize;
- a = start = smalloc(n);
-
- ilock(&nvrtlock);
- for(t = offset; t < offset + n; t++){
- if(t >= Nvsize)
- break;
- outb(Paddr, Nvoff+t);
- *a++ = inb(Pdata);
- }
- iunlock(&nvrtlock);
-
- if(waserror()){
- free(start);
- nexterror();
- }
- memmove(buf, start, t - offset);
- poperror();
-
- free(start);
- return t - offset;
- }
- error(Ebadarg);
- return 0;
-}
-
-#define PUTBCD(n,o) bcdclock[o] = (n % 10) | (((n / 10) % 10)<<4)
-
-static long
-rtcwrite(Chan* c, void* buf, long n, vlong off)
-{
- int t;
- char *a, *start;
- Rtc rtc;
- ulong secs;
- uchar bcdclock[Nbcd];
- char *cp, *ep;
- ulong offset = off;
-
- if(offset!=0)
- error(Ebadarg);
-
-
- switch((ulong)c->qid.path){
- case Qrtc:
- /*
- * read the time
- */
- cp = ep = buf;
- ep += n;
- while(cp < ep){
- if(*cp>='0' && *cp<='9')
- break;
- cp++;
- }
- secs = strtoul(cp, 0, 0);
-
- /*
- * convert to bcd
- */
- sec2rtc(secs, &rtc);
- PUTBCD(rtc.sec, 0);
- PUTBCD(rtc.min, 1);
- PUTBCD(rtc.hour, 2);
- PUTBCD(rtc.mday, 3);
- PUTBCD(rtc.mon, 4);
- PUTBCD(rtc.year, 5);
-
- /*
- * write the clock
- */
- ilock(&nvrtlock);
- outb(Paddr, Seconds); outb(Pdata, bcdclock[0]);
- outb(Paddr, Minutes); outb(Pdata, bcdclock[1]);
- outb(Paddr, Hours); outb(Pdata, bcdclock[2]);
- outb(Paddr, Mday); outb(Pdata, bcdclock[3]);
- outb(Paddr, Month); outb(Pdata, bcdclock[4]);
- outb(Paddr, Year); outb(Pdata, bcdclock[5]);
- iunlock(&nvrtlock);
- return n;
- case Qnvram:
- if(n == 0)
- return 0;
- if(n > Nvsize)
- n = Nvsize;
-
- start = a = smalloc(n);
- if(waserror()){
- free(start);
- nexterror();
- }
- memmove(a, buf, n);
- poperror();
-
- ilock(&nvrtlock);
- for(t = offset; t < offset + n; t++){
- if(t >= Nvsize)
- break;
- outb(Paddr, Nvoff+t);
- outb(Pdata, *a++);
- }
- iunlock(&nvrtlock);
-
- free(start);
- return t - offset;
- }
- error(Ebadarg);
- return 0;
-}
-
-Dev rtcdevtab = {
- 'r',
- "rtc",
-
- devreset,
- rtcinit,
- devshutdown,
- rtcattach,
- rtcwalk,
- rtcstat,
- rtcopen,
- devcreate,
- rtcclose,
- rtcread,
- devbread,
- rtcwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-#define SEC2MIN 60L
-#define SEC2HOUR (60L*SEC2MIN)
-#define SEC2DAY (24L*SEC2HOUR)
-
-/*
- * days per month plus days/year
- */
-static int dmsize[] =
-{
- 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-static int ldmsize[] =
-{
- 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/*
- * return the days/month for the given year
- */
-static int*
-yrsize(int y)
-{
- if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0))
- return ldmsize;
- else
- return dmsize;
-}
-
-/*
- * compute seconds since Jan 1 1970
- */
-static ulong
-rtc2sec(Rtc *rtc)
-{
- ulong secs;
- int i;
- int *d2m;
-
- secs = 0;
-
- /*
- * seconds per year
- */
- for(i = 1970; i < rtc->year; i++){
- d2m = yrsize(i);
- secs += d2m[0] * SEC2DAY;
- }
-
- /*
- * seconds per month
- */
- d2m = yrsize(rtc->year);
- for(i = 1; i < rtc->mon; i++)
- secs += d2m[i] * SEC2DAY;
-
- secs += (rtc->mday-1) * SEC2DAY;
- secs += rtc->hour * SEC2HOUR;
- secs += rtc->min * SEC2MIN;
- secs += rtc->sec;
-
- return secs;
-}
-
-/*
- * compute rtc from seconds since Jan 1 1970
- */
-static void
-sec2rtc(ulong secs, Rtc *rtc)
-{
- int d;
- long hms, day;
- int *d2m;
-
- /*
- * break initial number into days
- */
- hms = secs % SEC2DAY;
- day = secs / SEC2DAY;
- if(hms < 0) {
- hms += SEC2DAY;
- day -= 1;
- }
-
- /*
- * generate hours:minutes:seconds
- */
- rtc->sec = hms % 60;
- d = hms / 60;
- rtc->min = d % 60;
- d /= 60;
- rtc->hour = d;
-
- /*
- * year number
- */
- if(day >= 0)
- for(d = 1970; day >= *yrsize(d); d++)
- day -= *yrsize(d);
- else
- for (d = 1970; day < 0; d--)
- day += *yrsize(d-1);
- rtc->year = d;
-
- /*
- * generate month
- */
- d2m = yrsize(rtc->year);
- for(d = 1; day >= d2m[d]; d++)
- day -= d2m[d];
- rtc->mday = day + 1;
- rtc->mon = d;
-
- return;
-}
-
-uchar
-nvramread(int addr)
-{
- uchar data;
-
- ilock(&nvrtlock);
- outb(Paddr, addr);
- data = inb(Pdata);
- iunlock(&nvrtlock);
-
- return data;
-}
-
-void
-nvramwrite(int addr, uchar data)
-{
- ilock(&nvrtlock);
- outb(Paddr, addr);
- outb(Pdata, data);
- iunlock(&nvrtlock);
-}
diff --git a/os/pc/devtv.c b/os/pc/devtv.c
deleted file mode 100644
index 5e45fa37..00000000
--- a/os/pc/devtv.c
+++ /dev/null
@@ -1,1826 +0,0 @@
-/*
- * Driver for Hauppage TV board
- *
- * Control commands:
- *
- * init
- * window %d %d %d %d
- * colorkey %d %d %d %d %d %d
- * capture %d %d %d %d
- * capbrightness %d
- * capcontrast %d
- * capsaturation %d
- * caphue %d
- * capbw %d
- * brightness %d
- * contrast %d
- * saturation %d
- * source %d
- * svideo %d
- * format %d
- * channel %d %d
- * signal
- * volume %d [ %d ]
- * bass %d
- * treble %d
- * freeze %d
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "tv.h"
-
-#include <draw.h>
-
-enum {
- MemSize= 1,
- MemAddr= 0xB8000,
-
- CompressReg= -14,
-
- /* smart lock registers */
- SLReg1= -2,
- SLReg2= -1,
-
- /* the Bt812 registers */
- Bt812Index= -5,
- Bt812Data= -6,
-
- Bt2VideoPresent= 0x40,
- Bt4ColorBars= 0x40,
- Bt5YCFormat= 0x80,
- Bt7TriState= 0x0C,
-
- /* VxP 500 registers */
- Vxp500Index= 0,
- Vxp500Data= 1,
-
- /* video controller registers */
- MemoryWindowBaseAddrA= 0x14,
- MemoryWindowBaseAddrB= 0x15,
- MemoryPageReg= 0x16,
- MemoryConfReg= 0x18,
- ISAControl= 0x30,
- I2CControl= 0x34,
- InputVideoConfA= 0x38,
- InputVideoConfB= 0x39,
- ISASourceWindowWidthA= 0x3A,
- ISASourceWindowWidthB= 0x3B,
- ISASourceWindowHeightA= 0x3C,
- ISASourceWindowHeightB= 0x3D,
- InputHorzCropLeftA= 0x40,
- InputHorzCropLeftB= 0x41,
- InputHorzCropRightA= 0x44,
- InputHorzCropRightB= 0x45,
- InputHorzCropTopA= 0x48,
- InputHorzCropTopB= 0x49,
- InputHorzCropBottomA= 0x4C,
- InputHorzCropBottomB= 0x4D,
- InputHorzFilter= 0x50,
- InputHorzScaleControlA= 0x54,
- InputHorzScaleControlB= 0x55,
- InputVertInterpolControl= 0x58,
- InputVertScaleControlA= 0x5C,
- InputVertScaleControlB= 0x5D,
- InputFieldPixelBufStatus= 0x64,
- VideoInputFrameBufDepthA= 0x68,
- VideoInputFrameBufDepthB= 0x69,
- AcquisitionControl= 0x6C,
- AcquisitionAddrA= 0x70,
- AcquisitionAddrB= 0x71,
- AcquisitionAddrC= 0x72,
- VideoBufferLayoutControl= 0x73,
- CaptureControl= 0x80,
- CaptureViewPortAddrA= 0x81,
- CaptureViewPortAddrB= 0x82,
- CaptureViewPortAddrC= 0x83,
- CaptureViewPortWidthA= 0x84,
- CaptureViewPortWidthB= 0x85,
- CaptureViewPortHeightA= 0x86,
- CaptureViewPortHeightB= 0x87,
- CapturePixelBufLow= 0x88,
- CapturePixelBufHigh= 0x89,
- CaptureMultiBufDepthA= 0x8A,
- CaptureMultiBufDepthB= 0x8B,
- DisplayControl= 0x92,
- VGAControl= 0x94,
- OutputProcControlA= 0x96,
- OutputProcControlB= 0x97,
- DisplayViewPortStartAddrA= 0xA0,
- DisplayViewPortStartAddrB= 0xA1,
- DisplayViewPortStartAddrC= 0xA2,
- DisplayViewPortWidthA= 0xA4,
- DisplayViewPortWidthB= 0xA5,
- DisplayViewPortHeightA= 0xA6,
- DisplayViewPortHeightB= 0xA7,
- DisplayViewPortOrigTopA= 0xA8,
- DisplayViewPortOrigTopB= 0xA9,
- DisplayViewPortOrigLeftA= 0xAA,
- DisplayViewPortOrigLeftB= 0xAB,
- DisplayWindowLeftA= 0xB0,
- DisplayWindowLeftB= 0xB1,
- DisplayWindowRightA= 0xB4,
- DisplayWindowRightB= 0xB5,
- DisplayWindowTopA= 0xB8,
- DisplayWindowTopB= 0xB9,
- DisplayWindowBottomA= 0xBC,
- DisplayWindowBottomB= 0xBD,
- OutputVertZoomControlA= 0xC0,
- OutputVertZoomControlB= 0xC1,
- OutputHorzZoomControlA= 0xC4,
- OutputHorzZoomControlB= 0xC5,
- BrightnessControl= 0xC8,
- ContrastControl= 0xC9,
- SaturationControl= 0xCA,
- VideoOutIntrStatus= 0xD3,
-
- /* smart lock bits */
- PixelClk= 0x03,
- SmartLock= 0x00,
- FeatureConnector= 0x01,
- Divider= 0x02,
- Window= 0x08,
- KeyWindow= 0x0C,
- HSyncLow= 0x20,
- VSyncLow= 0x40,
-
- ClkBit= 0x01,
- DataBit= 0x02,
- HoldBit= 0x04,
- SelBit= 0x08,
- DivControl= 0x40,
-
- /* i2c bus control bits */
- I2C_Clock= 0x02,
- I2C_Data= 0x08,
- I2C_RdClock= 0x10,
- I2C_RdData= 0x20,
- I2C_RdData_D= 0x40,
-
- /* I2C bus addresses */
- Adr5249= 0x22, /* teletext decoder */
- Adr8444= 0x48, /* 6-bit DAC (TDA 8444) */
- Adr6300= 0x80, /* sound fader (TEA 6300) */
- Adr6320= 0x80, /* sound fader (TEA 6320T) */
- AdrTuner= 0xC0,
-
- /* Philips audio chips */
- TEA6300= 0,
- TEA6320T= 1,
-
- /* input formats */
- NTSC_M = 0,
- NTSC_443 = 1,
- External = 2,
-
- NTSCCropLeft= 36, /* NTSC 3.6 usec */
- NTSCCropRight= 558, /* NTSC 55.8 usec */
-
- /* color control indices */
- Vxp500Brightness= 1,
- Vxp500Contrast= 2,
- Vxp500Saturation= 3,
- Bt812Brightness= 4,
- Bt812Contrast= 5,
- Bt812Saturation= 6,
- Bt812Hue= 7,
- Bt812BW= 8,
-
- /* board revision numbers */
- RevisionPP= 0,
- RevisionA= 1,
- HighQ= 2,
-
- /* VGA controller registers */
- VGAMiscOut= 0x3CC,
- VGAIndex= 0x3D4,
- VGAData= 0x3D5,
- VGAHorzTotal= 0x00,
-};
-
-enum {
- Qdir,
- Qdata,
- Qctl,
-};
-
-static
-Dirtab tvtab[]={
- ".", {Qdir, 0, QTDIR}, 0, 0555,
- "tv", {Qdata, 0}, 0, 0666,
- "tvctl", {Qctl, 0}, 0, 0666,
-};
-
-static
-int ports[] = { /* board addresses */
- 0x51C, 0x53C, 0x55C, 0x57C,
- 0x59C, 0x5BC, 0x5DC, 0x5FC
-};
-
-/*
- * Default settings, settings between 0..100
- */
-static
-int defaults[] = {
- Vxp500Brightness, 0,
- Vxp500Contrast, 54,
- Vxp500Saturation, 54,
- Bt812Brightness, 13,
- Bt812Contrast, 57,
- Bt812Saturation, 51,
- Bt812Hue, 0,
- Bt812BW, 0,
-};
-
-static int port;
-static int soundchip;
-static int boardrev;
-static int left, right;
-static int vsync, hsync;
-static ulong xtalfreq;
-static ushort cropleft, cropright;
-static ushort cropbottom, croptop;
-static Rectangle window, capwindow;
-
-static void setreg(int, int);
-static void setbt812reg(int, int);
-static void videoinit(void);
-static void createwindow(Rectangle);
-static void setcontrols(int, uchar);
-static void setcolorkey(int, int, int, int, int, int);
-static void soundinit(void);
-static void setvolume(int, int);
-static void setbass(int);
-static void settreble(int);
-static void setsoundsource(int);
-static void tunerinit(void);
-static void settuner(int, int);
-static void setvideosource(int);
-static int waitvideosignal(void);
-static void freeze(int);
-static void setsvideo(int);
-static void setinputformat(int);
-static void enablevideo(void);
-static void *saveframe(int *);
-
-static int
-min(int a, int b)
-{
- return a < b ? a : b;
-}
-
-static int
-max(int a, int b)
-{
- return a < b ? b : a;
-}
-
-static int
-present(int port)
-{
- outb(port+Vxp500Index, 0xAA);
- if (inb(port+Vxp500Index) != 0xAA)
- return 0;
- outb(port+Vxp500Index, 0x55);
- outb(port+Vxp500Data, 0xAA);
- if (inb(port+Vxp500Index) != 0x55)
- return 0;
- if (inb(port+Vxp500Data) != 0xAA)
- return 0;
- outb(port+Vxp500Data, 0x55);
- if (inb(port+Vxp500Index) != 0x55)
- return 0;
- if (inb(port+Vxp500Data) != 0x55)
- return 0;
- return 1;
-}
-
-static int
-getvsync(void)
-{
- int vslow, vshigh, s;
- ushort timo;
-
- s = splhi();
-
- outb(port+Vxp500Index, VideoOutIntrStatus);
-
- /* wait for VSync to go high then low */
- for (timo = ~0; timo; timo--)
- if (inb(port+Vxp500Data) & 2) break;
- for (timo = ~0; timo; timo--)
- if ((inb(port+Vxp500Data) & 2) == 0) break;
-
- /* count how long it stays low and how long it stays high */
- for (vslow = 0, timo = ~0; timo; timo--, vslow++)
- if (inb(port+Vxp500Data) & 2) break;
- for (vshigh = 0, timo = ~0; timo; timo--, vshigh++)
- if ((inb(port+Vxp500Data) & 2) == 0) break;
- splx(s);
-
- return vslow < vshigh;
-}
-
-static int
-gethsync(void)
-{
- int hslow, hshigh, s;
- ushort timo;
-
- s = splhi();
-
- outb(port+Vxp500Index, VideoOutIntrStatus);
-
- /* wait for HSync to go high then low */
- for (timo = ~0; timo; timo--)
- if (inb(port+Vxp500Data) & 1) break;
- for (timo = ~0; timo; timo--)
- if ((inb(port+Vxp500Data) & 1) == 0) break;
-
- /* count how long it stays low and how long it stays high */
- for (hslow = 0, timo = ~0; timo; timo--, hslow++)
- if (inb(port+Vxp500Data) & 1) break;
- for (hshigh = 0, timo = ~0; timo; timo--, hshigh++)
- if ((inb(port+Vxp500Data) & 1) == 0) break;
- splx(s);
-
- return hslow < hshigh;
-}
-
-static void
-tvinit(void)
-{
- int i;
-
- for (i = 0, port = 0; i < nelem(ports); i++) {
- if (present(ports[i])) {
- port = ports[i];
- break;
- }
- }
- if (i == nelem(ports))
- return;
-
- /*
- * the following routines are the prefered way to
- * find out the sync polarities. Unfortunately, it
- * doesn't always work.
- */
-#ifndef VSync
- vsync = getvsync();
- hsync = gethsync();
-#else
- vsync = VSync;
- hsync = HSync;
-#endif
- left = right = 80;
- soundinit();
- tunerinit();
- videoinit();
-}
-
-static Chan*
-tvattach(char *spec)
-{
- if (port == 0)
- error(Enonexist);
- return devattach('V', spec);
-}
-
-static Walkqid*
-tvwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, tvtab, nelem(tvtab), devgen);
-}
-
-static int
-tvstat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, tvtab, nelem(tvtab), devgen);
-}
-
-static Chan*
-tvopen(Chan *c, int omode)
-{
- return devopen(c, omode, tvtab, nelem(tvtab), devgen);
-}
-
-static void
-tvclose(Chan *)
-{
-}
-
-static long
-tvread(Chan *c, void *a, long n, vlong offset)
-{
- static void *frame;
- static int size;
-
- USED(offset);
-
- switch((ulong)c->qid.path){
- case Qdir:
- return devdirread(c, a, n, tvtab, nelem(tvtab), devgen);
- case Qdata:
- if (eqrect(capwindow, Rect(0, 0, 0, 0)))
- error(Ebadarg);
- if (offset == 0)
- frame = saveframe(&size);
- if (frame) {
- if (n > size - offset)
- n = size - offset;
- memmove(a, (char *)frame + offset, n);
- } else
- error(Enovmem);
- break;
- default:
- n=0;
- break;
- }
- return n;
-}
-
-static long
-tvwrite(Chan *c, void *vp, long n, vlong offset)
-{
- char buf[128], *field[10], *a;
- int i, nf, source;
- static Rectangle win;
- static int hsize, size = 0;
- static void *frame;
-
- USED(offset);
-
- a = vp;
- switch((ulong)c->qid.path){
- case Qctl:
- if (n > sizeof(buf)-1)
- n = sizeof(buf)-1;
- memmove(buf, a, n);
- buf[n] = '\0';
-
- nf = getfields(buf, field, nelem(field), 1, " \t");
- if (nf < 1) error(Ebadarg);
-
- if (strcmp(field[0], "init") == 0) {
- window = Rect(0, 0, 0, 0);
- capwindow = Rect(0, 0, 0, 0);
- source = 0; /* video 0 input */
- setvideosource(source);
- left = right = 80;
- setsoundsource(source);
- for (i = 0; i < nelem(defaults); i += 2)
- setcontrols(defaults[i], defaults[i+1]);
- } else if (strcmp(field[0], "colorkey") == 0) {
- if (nf < 7) error(Ebadarg);
- setcolorkey(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0),
- strtoul(field[3], 0, 0), strtoul(field[4], 0, 0),
- strtoul(field[5], 0, 0), strtoul(field[6], 0, 0));
- } else if (strcmp(field[0], "window") == 0) {
- if (nf < 5) error(Ebadarg);
- createwindow(Rect(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0),
- strtoul(field[3], 0, 0), strtoul(field[4], 0, 0)));
- setvolume(left, right);
- } else if (strcmp(field[0], "capture") == 0) {
- if (nf < 5) error(Ebadarg);
- capwindow = Rect(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0),
- strtoul(field[3], 0, 0), strtoul(field[4], 0, 0));
- } else if (strcmp(field[0], "freeze") == 0) {
- if (nf < 2) error(Ebadarg);
- freeze(strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "capbrightness") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Bt812Brightness, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "capcontrast") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Bt812Contrast, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "capsaturation") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Bt812Saturation, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "caphue") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Bt812Hue, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "capbw") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Bt812BW, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "brightness") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Vxp500Brightness, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "contrast") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Vxp500Contrast, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "saturation") == 0) {
- if (nf < 2) error(Ebadarg);
- setcontrols(Vxp500Saturation, strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "source") == 0) {
- if (nf < 2) error(Ebadarg);
- source = strtoul(field[1], 0, 0);
- setvideosource(source);
- setsoundsource(source);
- } else if (strcmp(field[0], "svideo") == 0) {
- if (nf < 2) error(Ebadarg);
- setsvideo(strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "format") == 0) {
- if (nf < 2) error(Ebadarg);
- setinputformat(strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "channel") == 0) {
- if (nf < 3) error(Ebadarg);
- setvolume(0, 0);
- settuner(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0));
- tsleep(&up->sleep, return0, 0, 300);
- setvolume(left, right);
- } else if (strcmp(field[0], "signal") == 0) {
- if (!waitvideosignal())
- error(Etimedout);
- } else if (strcmp(field[0], "volume") == 0) {
- if (nf < 2) error(Ebadarg);
- left = strtoul(field[1], 0, 0);
- if (nf < 3)
- right = left;
- else
- right = strtoul(field[2], 0, 0);
- setvolume(left, right);
- } else if (strcmp(field[0], "bass") == 0) {
- if (nf < 2) error(Ebadarg);
- setbass(strtoul(field[1], 0, 0));
- } else if (strcmp(field[0], "treble") == 0) {
- if (nf < 2) error(Ebadarg);
- settreble(strtoul(field[1], 0, 0));
- } else
- error(Ebadctl);
- break;
- default:
- error(Ebadusefd);
- }
- return n;
-}
-
-
-Dev tvdevtab = {
- 'V',
- "tv",
-
- devreset,
- tvinit,
- devshutdown,
- tvattach,
- tvwalk,
- tvstat,
- tvopen,
- devcreate,
- tvclose,
- tvread,
- devbread,
- tvwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-static void
-setreg(int index, int data)
-{
- outb(port+Vxp500Index, index);
- outb(port+Vxp500Data, data);
-}
-
-static unsigned int
-getreg(int index)
-{
- outb(port+Vxp500Index, index);
- return inb(port+Vxp500Data);
-}
-
-/*
- * I2C routines
- */
-static void
-delayi2c(void)
-{
- int i, val;
-
- /* delay for 4.5 usec to guarantee clock time */
- for (i = 0; i < 75; i++) { /* was 50 */
- val = inb(port+Vxp500Data);
- USED(val);
- }
-}
-
-static int
-waitSDA(void)
-{
- ushort timo;
-
- /* wait for i2c clock to float high */
- for (timo = ~0; timo; timo--)
- if (inb(port+Vxp500Data) & I2C_RdData)
- break;
- if (!timo) print("devtv: waitSDA fell out of loop\n");
- return !timo;
-}
-
-static int
-waitSCL(void)
-{
- ushort timo;
-
- /* wait for i2c clock to float high */
- for (timo = ~0; timo; timo--)
- if (inb(port+Vxp500Data) & I2C_RdClock)
- break;
- delayi2c();
- if (!timo) print("devtv: waitSCL fell out of loop\n");
- return !timo;
-}
-
-static int
-seti2cdata(int data)
-{
- int b, reg, val;
- int error;
-
- error = 0;
- reg = inb(port+Vxp500Data);
- for (b = 0x80; b; b >>= 1) {
- if (data & b)
- reg |= I2C_Data;
- else
- reg &= ~I2C_Data;
- outb(port+Vxp500Data, reg);
- reg |= I2C_Clock;
- outb(port+Vxp500Data, reg);
- error |= waitSCL();
- reg &= ~I2C_Clock;
- outb(port+Vxp500Data, reg);
- delayi2c();
- }
- reg |= I2C_Data;
- outb(port+Vxp500Data, reg);
- reg |= I2C_Clock;
- outb(port+Vxp500Data, reg);
- error |= waitSCL();
- val = inb(port+Vxp500Data);
- USED(val);
- reg &= ~I2C_Clock;
- outb(port+Vxp500Data, reg);
- delayi2c();
- return error;
-}
-
-static int
-seti2creg(int id, int index, int data)
-{
- int reg, error;
-
- error = 0;
- /* set i2c control register to enable i2c clock and data lines */
- setreg(I2CControl, I2C_Data|I2C_Clock);
- error |= waitSDA();
- error |= waitSCL();
- outb(port+Vxp500Data, I2C_Clock);
- delayi2c();
- outb(port+Vxp500Data, 0);
- delayi2c();
-
- error |= seti2cdata(id);
- error |= seti2cdata(index);
- error |= seti2cdata(data);
-
- reg = inb(port+Vxp500Data);
- reg &= ~I2C_Data;
- outb(port+Vxp500Data, reg);
- reg |= I2C_Clock;
- outb(port+Vxp500Data, reg);
- error |= waitSCL();
- reg |= I2C_Data;
- outb(port+Vxp500Data, reg);
- error |= waitSDA();
- return error;
-}
-
-static int
-seti2cregs(int id, int index, int n, uchar *data)
-{
- int reg, error;
-
- error = 0;
- /* set i2c control register to enable i2c clock and data lines */
- setreg(I2CControl, I2C_Data|I2C_Clock);
- error |= waitSDA();
- error |= waitSCL();
- outb(port+Vxp500Data, I2C_Clock);
- delayi2c();
- outb(port+Vxp500Data, 0);
- delayi2c();
-
- /* send data */
- error |= seti2cdata(id);
- error |= seti2cdata(index);
- while (n--)
- error |= seti2cdata(*data++);
-
- /* send stop */
- reg = inb(port+Vxp500Data);
- reg &= ~I2C_Data;
- outb(port+Vxp500Data, reg);
- reg |= I2C_Clock;
- outb(port+Vxp500Data, reg);
- error |= waitSCL();
- reg |= I2C_Data;
- outb(port+Vxp500Data, reg);
- error |= waitSDA();
- return error;
-}
-
-/*
- * Audio routines
- */
-static void
-setvolume(int left, int right)
-{
- int vol, loudness = 0;
-
- if (soundchip == TEA6300) {
- seti2creg(Adr6300, 0, (63L * left) / 100);
- seti2creg(Adr6300, 1, (63L * right) / 100);
- vol = (15L * max(left, right)) / 100;
- seti2creg(Adr6300, 4, 0x30 | vol);
- } else {
- vol = (63L * max(left, right)) / 100;
- seti2creg(Adr6320, 0, vol | (loudness << 6));
- seti2creg(Adr6320, 1, (63L * right) / 100);
- seti2creg(Adr6320, 2, (63L * left) / 100);
- }
-}
-
-static void
-setbass(int bass)
-{
- if (soundchip == TEA6300)
- seti2creg(Adr6300, 2, (15L * bass) / 100);
- else
- seti2creg(Adr6320, 5, max((31L * bass) / 100, 4));
-}
-
-static void
-settreble(int treble)
-{
- if (soundchip == TEA6300)
- seti2creg(Adr6300, 3, (15L * treble) / 100);
- else
- seti2creg(Adr6320, 6, max((31L * treble) / 100, 7));
-
-}
-
-static void
-setsoundsource(int source)
-{
- if (soundchip == TEA6300)
- seti2creg(Adr6300, 5, 1 << source);
- else
- seti2creg(Adr6320, 7, source);
- setbass(50);
- settreble(50);
- setvolume(left, right);
-}
-
-static void
-soundinit(void)
-{
- if (seti2creg(Adr6320, 7, 0) && seti2creg(Adr6300, 4, 0))
- print("devtv: Audio init failed\n");
-
- soundchip = AudioChip;
- setvolume(0, 0);
-}
-
-/*
- * Tuner routines
- */
-static
-long hrcfreq[] = { /* HRC CATV frequencies */
- 0, 7200, 5400, 6000, 6600, 7800, 8400, 17400,
- 18000, 18600, 19200, 19800, 20400, 21000, 12000, 12600,
- 13200, 13800, 14400, 15000, 15600, 16200, 16800, 21600,
- 22200, 22800, 23400, 24000, 24600, 25200, 25800, 26400,
- 27000, 27600, 28200, 28800, 29400, 30000, 30600, 31200,
- 31800, 32400, 33000, 33600, 34200, 34800, 35400, 36000,
- 36600, 37200, 37800, 38400, 39000, 39600, 40200, 40800,
- 41400, 42000, 42600, 43200, 43800, 44400, 45000, 45600,
- 46200, 46800, 47400, 48000, 48600, 49200, 49800, 50400,
- 51000, 51600, 52200, 52800, 53400, 54000, 54600, 55200,
- 55800, 56400, 57000, 57600, 58200, 58800, 59400, 60000,
- 60600, 61200, 61800, 62400, 63000, 63600, 64200, 9000,
- 9600, 10200, 10800, 11400, 64800, 65400, 66000, 66600,
- 67200, 67800, 68400, 69000, 69600, 70200, 70800, 71400,
- 72000, 72600, 73200, 73800, 74400, 75000, 75600, 76200,
- 76800, 77400, 78000, 78600, 79200, 79800,
-};
-
-static void
-settuner(int channel, int finetune)
-{
- static long lastfreq;
- uchar data[3];
- long freq;
- int cw2, n, sa;
-
- if (channel < 0 || channel > nelem(hrcfreq))
- error(Ebadarg);
-
- freq = hrcfreq[channel];
-
- /* these settings are all for (FS936E) USA Tuners */
- if (freq < 16025) /* low band */
- cw2 = 0xA4;
- else if (freq < 45425) /* mid band */
- cw2 = 0x94;
- else
- cw2 = 0x34;
-
- /*
- * Channels are stored are 1/100 MHz resolutions, but
- * the tuner wants stuff in MHZ, so divide by 100, we
- * then have to shift by 4 to get the prog. div. value
- */
- n = ((freq + 4575L) * 16) / 100L + finetune;
-
- if (freq > lastfreq) {
- sa = (n >> 8) & 0xFF;
- data[0] = n & 0xFF;
- data[1] = 0x8E;
- data[2] = cw2;
- } else {
- sa = 0x8E;
- data[0] = cw2;
- data[1] = (n >> 8) & 0xFF;
- data[2] = n & 0xFF;
- }
- lastfreq = freq;
- seti2cregs(AdrTuner, sa, 3, data);
-}
-
-static void
-tunerinit(void)
-{
- if (seti2creg(AdrTuner, 0, 0))
- print("devtv: Tuner init failed\n");
-}
-
-/*
- * Video routines
- */
-static int slreg1 = 0;
-static int slreg2 = 0;
-static int vcogain = 0;
-static int phdetgain = 2;
-static int plln1 = 2;
-static int pllp2 = 1;
-
-static void
-waitforretrace(void)
-{
- ushort timo;
-
- for (timo = ~0; (getreg(VideoOutIntrStatus) & 2) == 0 && timo; timo--)
- /* wait for VSync inactive */;
- for (timo = ~0; (getreg(VideoOutIntrStatus) & 2) && timo; timo--)
- /* wait for VSync active */;
-}
-
-static void
-updateshadowregs(void)
-{
- int val;
-
- setreg(InputVideoConfA, getreg(InputVideoConfA) | 0x40);
- val = getreg(OutputProcControlB);
- setreg(OutputProcControlB, val & 0x7F);
- setreg(OutputProcControlB, val | 0x80);
-}
-
-static void
-setvgareg(int data)
-{
- /* set HSync & VSync first, to make sure VSync works properly */
- setreg(VGAControl, (getreg(VGAControl) & ~0x06) | (data & 0x06));
-
- /* wait for VSync and set the whole register */
- waitforretrace();
- setreg(VGAControl, data);
-}
-
-static void
-setbt812reg(int index, int data)
-{
- outb(port+Bt812Index, index);
- outb(port+Bt812Data, data);
-}
-
-static int
-getbt812reg(int index)
-{
- outb(port+Bt812Index, index);
- return inb(port+Bt812Data);
-}
-
-static void
-setbt812regpair(int index, ushort data)
-{
- outb(port+Bt812Index, index);
- outb(port+Bt812Data, data);
- outb(port+Bt812Data, data >> 8);
-}
-
-static void
-setvideosource(int source)
-{
- int s;
-
- source &= 7;
- s = source & 3;
- setbt812reg(0, ((s << 2) | s) << 3);
- s = (source & 4) << 4;
- setbt812reg(4, (getbt812reg(4) & ~Bt4ColorBars) | s);
-}
-
-static void
-setsvideo(int enable)
-{
- if (enable)
- setbt812reg(5, getbt812reg(5) | Bt5YCFormat);
- else
- setbt812reg(5, getbt812reg(5) & ~Bt5YCFormat);
-}
-
-static int
-waitvideosignal(void)
-{
- ushort timo;
-
- for (timo = ~0; timo; timo--)
- if (getbt812reg(2) & Bt2VideoPresent)
- return 1;
- return 0;
-}
-
-/*
- * ICS1572 Programming Configuration
- *
- * R = 1
- * M = x
- * A = x
- * N1 = 4
- * N2 = internal divide ratio
- */
-static
-uchar ICSbits[7] = {
- 0x01, /* bits 8 - 1 00000001 */
- 0x05, /* bits 16 - 9 00000101 */
- 0xFF, /* bits 24 - 17 11111111 */
- 0x8C, /* bits 32 - 25 10001100 */
- 0xBF, /* bits 40 - 33 10111111 */
- 0x00, /* bits 48 - 41 00000000 */
- 0x00, /* bits 56 - 49 00000000 */
-};
-
-static void
-sendbit(int val, int hold)
-{
- slreg2 &= ~(HoldBit|DataBit|ClkBit);
- if (val) slreg2 |= DataBit;
- if (hold) slreg2 |= HoldBit;
- outb(port+SLReg2, slreg2);
- outb(port+SLReg2, slreg2|ClkBit);
- outb(port+SLReg2, slreg2);
-}
-
-static void
-load1572(int select)
-{
- int reg;
- uchar mask;
-
- if (select)
- slreg2 |= SelBit;
- else
- slreg2 &= ~SelBit;
- outb(port+SLReg2, slreg2);
-
- for (reg = 0; reg < sizeof(ICSbits); reg++) {
- for (mask = 1; mask != 0; mask <<= 1) {
- if (reg == sizeof(ICSbits)-1 && mask == 0x80) {
- sendbit(ICSbits[reg] & mask, 1);
- } else
- sendbit(ICSbits[reg] & mask, 0);
- }
- }
-}
-
-static void
-smartlockdiv(int count, int vcogain, int phdetgain, int n1, int p2)
-{
- int extdiv, intdiv;
- int nslreg2, external;
-
- nslreg2 = slreg2;
- extdiv = ((count - 1) / 512) + 1;
- intdiv = (count / extdiv);
- nslreg2 &= ~0xC0;
- switch (extdiv) {
- case 1: external = 0; break;
- case 2: external = 1; break;
- case 3: external = 1; nslreg2 |= 0x40; break;
- case 4: external = 1; nslreg2 |= 0x80; break;
- default: return;
- }
- if ((slreg1 & PixelClk) == 0) {
- slreg2 = nslreg2;
- outb(port+SLReg2, slreg2);
- }
-
- /* set PLL divider */
- ICSbits[0] &= ~0x07;
- ICSbits[0] |= n1 & 0x07;
- ICSbits[3] &= ~0xB7;
- ICSbits[3] |= vcogain & 0x07;
- ICSbits[3] |= (phdetgain & 0x03) << 4;
- ICSbits[3] |= p2 << 7;
- if (external)
- ICSbits[1] |= 0x04; /* set EXTFBKEN */
- else
- ICSbits[1] &= ~0x04; /* clear EXTFBKEN */
- intdiv--;
- ICSbits[2] = intdiv; /* set N2 */
- ICSbits[3] &= ~ 0x08;
- ICSbits[3] |= (intdiv >> 5) & 0x08;
- load1572(1);
-}
-
-static void
-disablecolorkey(void)
-{
- setreg(DisplayControl, getreg(DisplayControl) & 0xFE);
- updateshadowregs();
-}
-
-static
-uchar colorkeylimit[6] = {
- 15, /* upper limit green */
- 255, /* lower limit green */
- 63, /* upper limit red */
- 63, /* upper limit blue */
- 15, /* lower limit red */
- 15, /* lower limit blue */
-};
-
-static void
-enablecolorkey(int enable)
-{
- int i;
-
- if (enable) {
- for (i = 0; i < 6; i++)
- seti2creg(Adr8444, 0xF0 | i, colorkeylimit[i]);
- slreg1 &= ~0x1C;
- if (colorkeylimit[4] == 255)
- slreg1 |= 0x04; /* disable red lower limit */
- if (colorkeylimit[1] == 255)
- slreg1 |= 0x08; /* disable green lower limit */
- if (colorkeylimit[5] == 255)
- slreg1 |= 0x10; /* disable blue lower limit */
- } else {
- for (i = 0; i < 6; i++)
- seti2creg(Adr8444, 0xF0 | i, 63);
- slreg1 |= 0x1C;
- }
- outb(port+SLReg1, slreg1);
- disablecolorkey();
-}
-
-static void
-setcolorkey(int rl, int rh, int gl, int gh, int bl, int bh)
-{
- colorkeylimit[0] = gh;
- colorkeylimit[1] = gl;
- colorkeylimit[2] = rh;
- colorkeylimit[3] = bh;
- colorkeylimit[4] = rl;
- colorkeylimit[5] = bl;
- enablecolorkey(1);
-}
-
-static void
-waitvideoframe(void)
-{
- ushort timo;
- int val;
-
- /* clear status bits and wait for start of an even field */
- val = getreg(InputFieldPixelBufStatus);
- USED(val);
- for (timo = ~0; timo; timo--)
- if ((getreg(InputFieldPixelBufStatus) & 2) == 0)
- break;
- if (!timo) print("devtv: Wait for video frame failed\n");
-}
-
-static void
-freeze(int enable)
-{
- ushort timo;
- int reg;
-
- if (enable) {
- waitvideoframe();
- waitvideoframe();
-
- setreg(InputVideoConfB, getreg(InputVideoConfB) | 0x08);
- updateshadowregs();
-
- for (timo = ~0; timo; timo--)
- if (getreg(InputVideoConfB) & 0x80) break;
- waitvideoframe();
-
- reg = getreg(OutputProcControlB);
- if ((reg & 0x20) == 0) {
- setreg(ISAControl, 0x80);
- setreg(OutputProcControlB, getreg(OutputProcControlB) | 0x20);
- setreg(ISAControl, 0x42);
-
- reg = getreg(OutputProcControlB);
- setreg(OutputProcControlB, reg & 0x7F);
- setreg(OutputProcControlB, reg | 0x80);
- }
- } else {
- setreg(InputVideoConfB, getreg(InputVideoConfB) & ~0x08);
- updateshadowregs();
-
- for (timo = ~0; timo; timo--)
- if (getreg(InputVideoConfB) & 0x40) break;
- waitvideoframe();
- reg = getreg(InputFieldPixelBufStatus);
- USED(reg);
- }
-}
-
-static void
-enablevideo(void)
-{
- setreg(DisplayControl, 0x04);
- updateshadowregs();
-}
-
-static void
-disablevideo(void)
-{
- setreg(DisplayControl, 0x18);
- updateshadowregs();
-}
-
-static
-uchar vxp500init[] = { /* video register initialization in (index,data) hex pairs */
- 0x30, 0x82, 0x39, 0x40, 0x58, 0x0C, 0x73, 0x02, 0x80, 0x00, 0x25, 0x0F,
- 0x26, 0x0F, 0x38, 0x46, 0x30, 0x03, 0x12, 0x3B, 0x97, 0x20, 0x13, 0x00,
- 0x14, 0x34, 0x15, 0x04, 0x16, 0x00, 0x17, 0x53, 0x18, 0x04, 0x19, 0x62,
- 0x1C, 0x00, 0x1D, 0x00, 0x34, 0x3A, 0x38, 0x06, 0x3A, 0x00, 0x3B, 0x00,
- 0x3C, 0x00, 0x3D, 0x00, 0x40, 0x40, 0x41, 0x40, 0x44, 0xFF, 0x45, 0xFF,
- 0x48, 0x40, 0x49, 0x40, 0x4C, 0xFF, 0x4D, 0xFF, 0x50, 0xF0, 0x54, 0x30,
- 0x55, 0x00, 0x5C, 0x04, 0x5D, 0x00, 0x60, 0x00, 0x68, 0x00, 0x69, 0x00,
- 0x6C, 0x06, 0x6D, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x78, 0x01,
- 0x79, 0x0C, 0x80, 0x10, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00,
- 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x04, 0x89, 0x10, 0x8A, 0x00,
- 0x8B, 0x00, 0x90, 0x05, 0x91, 0x0C, 0x92, 0x18, 0x93, 0x00, 0x96, 0x18,
- 0x9A, 0x30, 0x9C, 0x2D, 0x9D, 0x00, 0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00,
- 0xA4, 0x50, 0xA5, 0x50, 0xA6, 0xF0, 0xA7, 0xF0, 0xA8, 0x19, 0xA9, 0x18,
- 0xAA, 0x64, 0xAB, 0x64, 0xB0, 0x64, 0xB1, 0x64, 0xB4, 0xA4, 0xB5, 0xA5,
- 0xB8, 0x19, 0xB9, 0x18, 0xBC, 0x09, 0xBD, 0x09, 0xC0, 0x00, 0xC1, 0x02,
- 0xC4, 0x00, 0xC5, 0x00, 0xC8, 0x00, 0xC9, 0x08, 0xCA, 0x08, 0xCE, 0x00,
- 0xCF, 0x00, 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD8, 0x00, 0xD9, 0x00,
- 0xDA, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0xDD, 0x00, 0x38, 0x46, 0x97, 0xA0,
- 0x97, 0x20, 0x97, 0xA0,
-};
-
-static
-uchar bt812init[] = { /* bt812 initializations */
- 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0xC0,
- 0x04, 0x08, 0x05, 0x00, 0x06, 0x40, 0x07, 0x00, 0x08, 0x10,
- 0x09, 0x90, 0x0A, 0x80, 0x0B, 0x00, 0x0C, 0x0C, 0x0D, 0x03,
- 0x0E, 0x66, 0x0F, 0x00, 0x10, 0x80, 0x11, 0x02, 0x12, 0x16,
- 0x13, 0x00, 0x14, 0xE5, 0x15, 0x01, 0x16, 0xAB, 0x17, 0xAA,
- 0x18, 0x12, 0x19, 0x51, 0x1A, 0x46, 0x1B, 0x00, 0x1C, 0x00,
- 0x1D, 0x37,
-};
-
-static ushort actpixs = 720;
-static ulong Hdesired = 13500000L;
-
-/* NTSC-M NTSC-443 EXTERNAL */
-static ushort horzfreq[] = { 15734, 15625, 0 };
-static ushort Vdelay[] = { 22, 25, 25 };
-static ushort s2b[] = { 90, 90, 0 };
-static ushort actlines[] = { 485, 485, 575 };
-static ulong subcarfreq[] = { 3579545, 4433619, 4433619 };
-
-static
-unsigned int framewidth[5][4] = {
- 1024, 512, 512, 512, /* mode 0 - single, double, single, quad */
- 1536, 768, 768, 384, /* mode 1 - single, double, single, quad */
- 2048, 1024, 1024, 512, /* mode 2 - single, double, single, quad */
- 1024, 512, 512, 512, /* mode 3 - single, double, single, quad */
- 1536, 768, 768, 384 /* mode 4 - single, double, single, quad */
-};
-
-static
-unsigned int frameheight[5][4] = {
- 512, 512, 1024, 512, /* mode 0 - single, double, single, quad */
- 512, 512, 1024, 512, /* mode 1 - single, double, single, quad */
- 512, 512, 1024, 512, /* mode 2 - single, double, single, quad */
- 512, 512, 1024, 512, /* mode 3 - single, double, single, quad */
- 512, 512, 1024, 256 /* mode 4 - single, double, single, quad */
-};
-
-static
-uchar horzfilter[] = { 3, 3, 2, 2, 1, 1, 0, 0 };
-
-static
-uchar interleave[] = { 2, 3, 4, 2, 3 };
-
-#define ADJUST(n) (((n) * hrsmult + hrsdiv - 1) / hrsdiv)
-
-static int q = 100;
-static int ilv = 2;
-static int hrsmult = 1;
-static int hrsdiv = 2;
-
-static ushort panmask[] = { 0xFFFE, 0xFFFC, 0xFFFF, 0xFFFF, 0xFFFE };
-
-
-static void
-cropwindow(int left, int right, int top, int bottom)
-{
- top &= 0x3FE;
- bottom &= 0x3FE;
- setreg(InputHorzCropLeftA, left);
- setreg(InputHorzCropLeftB, left >> 8);
- setreg(InputHorzCropRightA, right);
- setreg(InputHorzCropRightB, right >> 8);
- setreg(InputHorzCropTopA, top);
- setreg(InputHorzCropTopB, top >> 8);
- setreg(InputHorzCropBottomA, bottom);
- setreg(InputHorzCropBottomB, bottom >> 8);
-}
-
-static void
-setinputformat(int format)
-{
- ushort hclock, hclockdesired;
- ulong subcarrier;
- int cr7;
-
- cr7 = getbt812reg(7) & ~Bt7TriState;
- if (format == External)
- cr7 |= Bt7TriState;
- setbt812reg(7, cr7);
- setbt812reg(5, getbt812reg(5) & 2);
-
- hclock = (xtalfreq >> 1) / horzfreq[format];
- setbt812regpair(0x0C, hclock);
- setbt812regpair(0x0E,
- (ushort)(s2b[format] * (Hdesired / 10) / 1000000L) | 1);
- setbt812regpair(0x10, actpixs);
- setbt812regpair(0x12, Vdelay[format]);
- setbt812regpair(0x14, actlines[format]);
-
- subcarrier = (ulong)
- ((((long long)subcarfreq[format] * 0x1000000) / xtalfreq + 1) / 2);
- setbt812regpair(0x16, (int)(subcarrier & 0xFFFF)); /* subcarrier */
- setbt812reg(0x18, (int)(subcarrier >> 16));
-
- setbt812reg(0x19, (uchar)(((xtalfreq / 200) * 675) / 1000000L + 8));
- setbt812reg(0x1A, (uchar)((xtalfreq * 65) / 20000000L - 10));
- hclockdesired = (ushort) (Hdesired / horzfreq[format]);
- setbt812regpair(0x1B,
- (ushort)(((hclock - hclockdesired) * 65536L) / hclockdesired));
-}
-
-static ushort
-vgadivider(void)
-{
- ushort horztotal;
-
- outb(VGAIndex, VGAHorzTotal);
- horztotal = (inb(VGAData) << 3) + 40;
- if (horztotal > ScreenWidth && horztotal < ((ScreenWidth * 3 ) / 2))
- return horztotal;
- else
- return (ScreenWidth * 5) / 4;
-}
-
-static void
-videoinit(void)
-{
- int i, reg, width, tuner;
-
- /* early PLL smart lock initialization */
- if (ScreenWidth == 640) {
- slreg1 = Window|HSyncLow|VSyncLow;
- slreg2 = 0x0D;
- } else {
- slreg1 = Window;
- slreg2 = 0x0C;
- }
- outb(port+CompressReg, 2);
- outb(port+SLReg1, slreg1);
- outb(port+SLReg2, slreg2);
- smartlockdiv((vgadivider() * hrsmult)/hrsdiv, vcogain, phdetgain, 2, 1);
-
- /* program the VxP-500 chip (disables video) */
- waitforretrace();
- for (i = 0; i < sizeof(vxp500init); i += 2)
- setreg(vxp500init[i], vxp500init[i+1]);
-
- /* set memory base for frame capture */
- setreg(MemoryWindowBaseAddrA, MemAddr >> 14);
- setreg(MemoryWindowBaseAddrB, ((MemAddr >> 22) & 3) | (MemSize << 2));
- setreg(MemoryPageReg, 0);
-
- /* generic 422 decoder, mode 3 and 4 */
- setreg(MemoryConfReg, ilv+1);
-
- setreg(AcquisitionAddrA, 0);
- setreg(AcquisitionAddrB, 0);
- setreg(AcquisitionAddrC, 0);
-
- /* program VxP-500 for correct sync polarity */
- reg = ScreenWidth > 1023 ? 0x01 : 0x00;
- reg |= (vsync << 1) | (hsync << 2);
- setvgareg(reg);
- setreg(VGAControl, reg);
-
- setreg(VideoBufferLayoutControl, 0); /* for ilv = 2 */
-
- /* set sync polarities to get proper blanking */
- if (vsync)
- slreg1 |= VSyncLow;
- if (!hsync) {
- slreg1 ^= HSyncLow;
- setreg(VGAControl, reg | 4);
- }
- outb(port+SLReg1, slreg1);
-
- if ((slreg1 & PixelClk) == 0) { /* smart lock active */
- enablecolorkey(1);
- setreg(VGAControl, getreg(VGAControl) & 6);
- } else
- enablecolorkey(0);
-
- /* color key initializations */
- if ((slreg1 & PixelClk) == 0)
- setreg(VGAControl, getreg(VGAControl) & 7);
-
- /* initialize Bt812 */
- for (i = 0; i < sizeof(bt812init); i += 2)
- setbt812reg(bt812init[i], bt812init[i+1]);
-
- /* figure out clock source (Xtal or Oscillator) and revision */
- setbt812reg(6, 0x40);
- reg = getreg(InputFieldPixelBufStatus) & 3;
- if ((getreg(InputFieldPixelBufStatus) & 3) == reg) {
- /* crystal - could be revision PP if R34 is installed */
- setbt812reg(6, 0x00);
- reg = inb(port+SLReg1);
- if (reg & 0x20) {
- if ((reg & 0xE0) == 0xE0)
- boardrev = HighQ;
- else
- boardrev = RevisionA;
- } else
- boardrev = RevisionPP;
- } else /* revision A or newer with 27 MHz oscillator */
- boardrev = RevisionA;
-
- /* figure out xtal frequency */
- if (xtalfreq == 0) {
- if (boardrev == RevisionPP) {
- tuner = (inb(port+SLReg1) >> 6) & 3;
- if (tuner == 0) /* NTSC */
- xtalfreq = 24545400L;
- else
- xtalfreq = 29500000L;
- } else if (boardrev == HighQ)
- xtalfreq = 29500000L;
- else
- xtalfreq = 27000000L;
- }
-
-// print("Hauppage revision %d (xtalfreq %ld)\n", boardrev, xtalfreq);
-
- /* on RevPP boards set early sync, on rev A and newer clear it */
- if (boardrev == RevisionPP)
- setreg(InputVideoConfA, getreg(InputVideoConfA) | 4);
- else
- setreg(InputVideoConfA, getreg(InputVideoConfA) & ~4);
-
- switch (xtalfreq) {
- case 24545400L:
- actpixs = 640;
- break;
- case 29500000L:
- actpixs = 768;
- break;
- default:
- actpixs = 720;
- break;
- }
-
- /* set crop window (these values are for NTSC!) */
- if (boardrev == RevisionPP) {
- Hdesired = xtalfreq / 2;
- cropleft = (NTSCCropLeft * ((Hdesired / 10))) / 1000000L;
- cropright = (NTSCCropRight * ((Hdesired / 10))) / 1000000L;
- } else {
- cropleft = actpixs / 100;
- cropright = actpixs - cropleft;
- }
- width = ((cropright - cropleft + ilv) / ilv) * ilv;
- cropright = cropleft + width + 1;
- croptop = 26;
- cropbottom = 505;
- cropwindow(cropleft, cropright, croptop, cropbottom);
-
- /* set input format */
- setinputformat(NTSC_M);
- setsvideo(0);
-}
-
-static void
-panwindow(Point p)
-{
- int memmode, ilv, frw;
- ulong pos;
-
- memmode = getreg(MemoryConfReg) & 7;
- ilv = interleave[memmode];
- frw = framewidth[memmode][getreg(VideoBufferLayoutControl) & 3];
-
- pos = (p.y * (frw/ilv)) + ((p.x/ilv) & panmask[memmode]);
- setreg(DisplayViewPortStartAddrA, (uchar) pos);
- setreg(DisplayViewPortStartAddrB, (uchar) (pos >> 8));
- setreg(DisplayViewPortStartAddrC, (uchar) (pos >> 16) & 0x03);
- updateshadowregs();
-}
-
-static int
-testqfactor(void)
-{
- ulong timo;
- int reg;
-
- waitvideoframe();
- for (reg = 0, timo = ~0; timo; timo--) {
- reg |= getreg(InputFieldPixelBufStatus);
- if (reg & 0xE) break;
- }
- if (reg & 0xC) return 0;
-
- waitvideoframe();
- for (reg = 0, timo = ~0; timo; timo--) {
- reg |= getreg(InputFieldPixelBufStatus);
- if (reg & 0xE) break;
- }
- return (reg & 0xC) == 0;
-}
-
-static void
-newwindow(Rectangle r)
-{
- unsigned ww, wh, dx, dy, xs, ys, xe, ye;
- unsigned scalex, scaley;
- int frwidth, frheight, vidwidth, vidheight;
- int memmode, layout;
- int width, height;
- int filter, changed, val;
-
- changed = r.min.x != window.min.x || r.min.y != window.min.y ||
- r.max.x != window.max.x || r.max.y != window.max.y;
- if (changed) window = r;
-
- if (r.min.x < 0) r.min.x = 0;
- if (r.max.x > ScreenWidth) r.max.x = ScreenWidth;
- if (r.min.y < 0) r.min.y = 0;
- if (r.max.y > ScreenHeight) r.max.y = ScreenHeight;
-
- if ((dx = r.max.x - r.min.x) <= 0) dx = 1;
- if ((dy = r.max.y - r.min.y) <= 0) dy = 1;
-
- wh = dy;
- ww = dx = ADJUST(dx);
- r.min.x = (r.min.x * hrsmult) / hrsdiv;
-
- memmode = getreg(MemoryConfReg) & 7;
- layout = getreg(VideoBufferLayoutControl) & 3;
- vidwidth = cropright - cropleft + 1;
- vidheight = (cropbottom & 0x3FE) - (croptop & 0x3FE) + 1;
- frwidth = min(framewidth[memmode][layout], vidwidth);
- frheight = min(frameheight[memmode][layout], vidheight);
-
- /* round up scale width to nearest multiple of interleave factor */
- dx = ((ulong)dx * q) / 100;
- dx = ilv * ((dx + ilv - 1) / ilv);
-
- scalex = (((ulong)dx * 1024L) + vidwidth - 2) / (vidwidth - 1);
- if (dy > frheight) dy = frheight - 1;
- scaley = (((ulong)dy * 1024L) + vidheight - 2) / (vidheight - 1);
-
- setreg(InputHorzScaleControlA, (scalex << 6) & 0xC0);
- setreg(InputHorzScaleControlB, (scalex >> 2) & 0xFF);
- setreg(InputVertScaleControlA, (scaley << 6) & 0xC0);
- setreg(InputVertScaleControlB, (scaley >> 2) & 0xFF);
-
- /* turn on horizontal filtering if we are scaling down */
- setreg(InputHorzFilter, horzfilter[((scalex - 1) >> 7) & 7]);
-
- /* set vertical interpolation */
- filter = scaley > 512 ? (ScreenWidth == 640 ? 0x44 : 0xC5) : 0x46; /* magic */
- if ((getreg(InputVertInterpolControl) & 0x1F) != (filter & 0x1F)) {
- setreg(ISAControl, 0x80);
- setreg(InputVertInterpolControl, filter & 0x1F);
- setreg(ISAControl, 0x42);
- }
- setreg(AcquisitionControl, ((filter >> 6) ^ 3) | 0x04);
-
- /* set viewport position and size */
- width = ((ulong)ww * q) / 100;
- if (width >= frwidth - ilv)
- width = frwidth - ilv;
- width = ((width + ilv - 1) / ilv) + 2;
-
- height = ((ulong)wh * dy + wh - 1) / wh;
- if (height >= frheight)
- height = frheight - 3;
- height += 2;
-
- xs = r.min.x + XCorrection;
- if (xs < 0) xs = 2;
- ys = r.min.y + YCorrection;
- if (ys < 0) ys = 2;
- if (ScreenWidth > 1023) ys |= 1;
-
- setreg(DisplayViewPortWidthA, width);
- setreg(DisplayViewPortWidthB, width >> 8);
- setreg(DisplayViewPortHeightA, height);
- setreg(DisplayViewPortHeightB, height >> 8);
- setreg(DisplayViewPortOrigTopA, ys);
- setreg(DisplayViewPortOrigTopB, ys >> 8);
- setreg(DisplayViewPortOrigLeftA, xs);
- setreg(DisplayViewPortOrigLeftB, xs >> 8);
-
- xe = r.min.x + ww - 1 + XCorrection;
- if (xe < 0) xe = 2;
- ye = r.min.y + wh - 1 + YCorrection;
- if (ye < 0) ye = 2;
-
- setreg(DisplayWindowLeftA, xs);
- setreg(DisplayWindowLeftB, xs >> 8);
- setreg(DisplayWindowRightA, xe);
- setreg(DisplayWindowRightB, xe >> 8);
- setreg(DisplayWindowTopA, ys);
- setreg(DisplayWindowTopB, ys >> 8);
- setreg(DisplayWindowBottomA, ye);
- setreg(DisplayWindowBottomB, ye >> 8);
-
- if (dx < ww) { /* horizontal zoom */
- int zoom = ((ulong) (dx - 1) * 2048) / ww;
- setreg(OutputProcControlA, getreg(OutputProcControlA) | 6);
- setreg(OutputHorzZoomControlA, zoom);
- setreg(OutputHorzZoomControlB, zoom >> 8);
- } else
- setreg(OutputProcControlA, getreg(OutputProcControlA) & 0xF9);
-
- if (dy < wh) { /* vertical zoom */
- int zoom = ((ulong) (dy - 1) * 2048) / wh;
- setreg(OutputProcControlB, getreg(OutputProcControlB) | 1);
- setreg(OutputVertZoomControlA, zoom);
- setreg(OutputVertZoomControlB, zoom >> 8);
- } else
- setreg(OutputProcControlB, getreg(OutputProcControlB) & 0xFE);
-
- setreg(OutputProcControlB, getreg(OutputProcControlB) | 0x20);
- updateshadowregs();
-
- if (changed) {
- setreg(OutputProcControlA, getreg(OutputProcControlA) & 0xDF);
- } else {
- val = getreg(InputFieldPixelBufStatus);
- USED(val);
- }
-
- panwindow(Pt(0, 0));
-}
-
-static void
-createwindow(Rectangle r)
-{
- for (q = 100; q >= 30; q -= 10) {
- newwindow(r);
- if (testqfactor())
- break;
- }
- enablevideo();
-}
-
-static void
-setcontrols(int index, uchar val)
-{
- switch (index) {
- case Vxp500Brightness:
- setreg(BrightnessControl, (127L * val) / 100);
- updateshadowregs();
- break;
- case Vxp500Contrast:
- setreg(ContrastControl, (15L * val) / 100);
- updateshadowregs();
- break;
- case Vxp500Saturation:
- setreg(SaturationControl, (15L * val) / 100);
- updateshadowregs();
- break;
- case Bt812Brightness:
- setbt812reg(0x08, ((126L * val) / 100) & 0xFE);
- break;
- case Bt812Contrast:
- setbt812reg(0x09, ((254L * val) / 100) & 0xFE);
- break;
- case Bt812Saturation:
- setbt812reg(0x0A, ((254L * val) / 100) & 0xFE);
- break;
- case Bt812Hue:
- setbt812reg(0x0B, ((254L * val) / 100) & 0xFE);
- break;
- case Bt812BW:
- setbt812reg(0x05, (getbt812reg(0x5) & ~2) | ((val << 1) & 2));
- break;
- }
-}
-
-static void
-enablememwindow(void)
-{
- setreg(MemoryWindowBaseAddrB, getreg(MemoryWindowBaseAddrB) | 0x20);
-}
-
-static void
-disablememwindow(void)
-{
- setreg(MemoryWindowBaseAddrB, getreg(MemoryWindowBaseAddrB) & ~0x20);
-}
-
-volatile static ushort *fb = (ushort *)EISA(MemAddr);
-static uchar yuvpadbound[] = { 4, 12, 4, 2, 6 };
-
-/*
- * Capture a frame in UY0, VY1 format
- */
-static void *
-saveframe(int *nb)
-{
- int memmode, layout, ilv;
- int frwidth, frheight;
- int bound, n, val, toggle;
- unsigned save58, save6C;
- int x, y, w, h, width, height;
- ulong pos, size;
- char *p;
- static void *frame = 0;
- static ulong framesize = 0;
-
- width = capwindow.max.x - capwindow.min.x;
- height = capwindow.max.y - capwindow.min.y;
-
- memmode = getreg(MemoryConfReg) & 7;
- if (memmode <= 2) {
- print("devtv: cannot handle YUV411\n");
- error(Egreg); /* actually, Eleendert */
- }
- layout = getreg(VideoBufferLayoutControl) & 3;
- ilv = interleave[memmode];
- frwidth = framewidth[memmode][layout];
- frheight = frameheight[memmode][layout];
-
- pos = getreg(AcquisitionAddrA) +
- (getreg(AcquisitionAddrB) << 8) + (getreg(AcquisitionAddrC) & 3) << 16;
-
- x = capwindow.min.x + (pos % frwidth);
- y = capwindow.min.y + (pos / frwidth);
- if (x > frwidth || y > frheight)
- return 0;
- if (x + width > frwidth)
- width = frwidth - x;
- if (y + height > frheight)
- height = frheight - y;
-
- pos = y * (frwidth / ilv) + (x / ilv);
-
- /* compute padding for each scan line */
- bound = yuvpadbound[memmode];
- switch (bound) {
- case 2:
- width = (width + 1) & ~1;
- break;
- case 4:
- width = (width + 3) & ~3;
- break;
- default:
- width = (width + (bound - 1)) / bound;
- break;
- }
-
- size = width * height * sizeof(ushort);
- if (size != framesize) {
- framesize = 0;
- if (frame)
- free(frame);
- frame = malloc(size + 256);
- }
- if (frame == 0)
- return 0;
-
- memset(frame, 0, size + 256);
-
- framesize = size;
- p = (char *) frame + snprint(frame, 256,
- "TYPE=ccir601\nWINDOW=%d %d %d %d\n\n",
- capwindow.min.x, capwindow.min.y,
- capwindow.min.x+width, capwindow.min.y+height);
-
- freeze(1);
-
- save58 = getreg(InputVertInterpolControl);
- save6C = getreg(AcquisitionControl);
-
- waitforretrace();
- setreg(ISAControl, 0xC0); /* global reset */
- setreg(InputVertInterpolControl, 0x0D);
- setreg(AcquisitionControl, 0x04);
- setreg(CaptureControl, 0x80); /* set capture mode */
- setreg(VideoInputFrameBufDepthA, 0xFF);
- setreg(VideoInputFrameBufDepthB, 0x03);
- setreg(InputVideoConfA, getreg(InputVideoConfA) | 0x40);
- setreg(ISAControl, 0x44); /* tight decode, global reset off */
-
- setreg(CaptureViewPortAddrA, (int) pos & 0xFF);
- setreg(CaptureViewPortAddrB, (int) (pos >> 8) & 0xFF);
- setreg(CaptureViewPortAddrC, (int) (pos >> 16) & 0x03);
- n = (width / ilv) - 1;
- setreg(CaptureViewPortWidthA, n & 0xFF);
- setreg(CaptureViewPortWidthB, n >> 8);
- setreg(CaptureViewPortHeightA, (height-1) & 0xFF);
- setreg(CaptureViewPortHeightB, (height-1) >> 8);
- setreg(CapturePixelBufLow, 0x04); /* pix buffer low */
- setreg(CapturePixelBufHigh, 0x0E); /* pix buffer high */
- setreg(CaptureMultiBufDepthA, 0xFF); /* multi buffer depth maximum */
- setreg(CaptureMultiBufDepthB, 0x03);
- updateshadowregs();
-
- setreg(CaptureControl, 0x90); /* capture reset */
- val = getreg(InputFieldPixelBufStatus); /* clear read status */
- USED(val);
-
- toggle = !(getreg(OutputProcControlA) & 0x01) ? 0x8000 : 0x0000;
- setreg(CaptureControl, 0xC0); /* capture enable, active */
-
- while ((getreg(InputFieldPixelBufStatus) & 0x10) == 0)
- /* wait for capture FIFO to become ready */;
-
- enablememwindow();
- for (h = height; h > 0; h--) {
- for (w = width; w > 0; w -= 2) {
- ushort uy0 = swab16(fb[0]) ^ toggle;
- ushort vy1 = swab16(fb[1]) ^ toggle;
- /* unfortunately p may not be properly aligned */
- *p++ = uy0 >> 8;
- *p++ = uy0;
- *p++ = vy1 >> 8;
- *p++ = vy1;
- }
- }
- disablememwindow();
-
- waitforretrace();
- setreg(ISAControl, 0xC0); /* global reset */
- setreg(CaptureControl, 0); /* clear capture mode */
- setreg(InputVertInterpolControl, save58);
- setreg(AcquisitionControl, save6C);
- setreg(InputVideoConfA, getreg(InputVideoConfA) | 0x40);
- setreg(ISAControl, 0x40); /* clear global reset */
- updateshadowregs();
-
- freeze(0);
-
- *nb = p - (char *) frame;
- return frame;
-}
diff --git a/os/pc/devusb.c b/os/pc/devusb.c
deleted file mode 100644
index 56a3442a..00000000
--- a/os/pc/devusb.c
+++ /dev/null
@@ -1,951 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#include "usb.h"
-
-static int debug = 0;
-
-#define Chatty 1
-#define DPRINT if(Chatty)print
-#define XPRINT if(debug)iprint
-
-Usbhost* usbhost[MaxUsb];
-
-static char *devstates[] = {
- [Disabled] "Disabled",
- [Attached] "Attached",
- [Enabled] "Enabled",
- [Assigned] "Assigned",
- [Configured] "Configured",
-};
-
-static char Ebadusbmsg[] = "invalid parameters to USB ctl message";
-
-enum
-{
- Qtopdir = 0,
- Q2nd,
- Qnew,
- Qport,
- Q3rd,
- Qctl,
- Qstatus,
- Qep0,
- /* other endpoint files */
-};
-
-/*
- * Qid path is:
- * 8 bits of file type (qids above)
- * 8 bits of slot number; default address 0 used for per-controller files
- * 4 bits of controller number
- */
-enum {
- TYPEBITS = 8,
- SLOTBITS = 8,
- CTLRBITS = 4,
-
- SLOTSHIFT = TYPEBITS,
- CTLRSHIFT = SLOTSHIFT+SLOTBITS,
-
- TYPEMASK = (1<<TYPEBITS)-1,
- SLOTMASK = (1<<SLOTBITS)-1,
- CTLRMASK = (1<<CTLRBITS)-1,
-};
-
-#define TYPE(q) (((ulong)(q).path)&TYPEMASK)
-#define SLOT(q) ((((ulong)(q).path)>>SLOTSHIFT)&SLOTMASK)
-#define CTLR(q) ((((ulong)(q).path)>>CTLRSHIFT)&CTLRMASK)
-#define PATH(t, s, c) ((t)|((s)<<SLOTSHIFT)|((c)<<CTLRSHIFT))
-
-static Dirtab usbdir2[] = {
- "new", {Qnew}, 0, 0666,
- "port", {Qport}, 0, 0666,
-};
-
-static Dirtab usbdir3[]={
- "ctl", {Qctl}, 0, 0666,
- "status", {Qstatus}, 0, 0444,
- "setup", {Qep0}, 0, 0666,
- /* epNdata names are generated on demand */
-};
-
-enum
-{
- PMdisable,
- PMenable,
- PMreset,
-};
-
-enum
-{
- CMclass,
- CMdata,
- CMdebug,
- CMep,
- CMmaxpkt,
- CMadjust,
- CMspeed,
- CMunstall,
-};
-
-static Cmdtab usbportmsg[] =
-{
- PMdisable, "disable", 2,
- PMenable, "enable", 2,
- PMreset, "reset", 2,
-};
-
-static Cmdtab usbctlmsg[] =
-{
- CMclass, "class", 0,
- CMdata, "data", 3,
- CMdebug, "debug", 3,
- CMep, "ep", 6,
- CMmaxpkt, "maxpkt", 3,
- CMadjust, "adjust", 3,
- CMspeed, "speed", 2,
- CMunstall, "unstall", 2,
-};
-
-static struct
-{
- char* type;
- int (*reset)(Usbhost*);
-} usbtypes[MaxUsb+1];
-
-void
-addusbtype(char* t, int (*r)(Usbhost*))
-{
- static int ntype;
-
- if(ntype == MaxUsb)
- panic("too many USB host interface types");
- usbtypes[ntype].type = t;
- usbtypes[ntype].reset = r;
- ntype++;
-}
-
-static Udev*
-usbdeviceofslot(Usbhost *uh, int s)
-{
- if(s < 0 || s > nelem(uh->dev))
- return nil;
- return uh->dev[s];
-}
-
-static Udev*
-usbdevice(Chan *c)
-{
- int bus;
- Udev *d;
- Usbhost *uh;
-
- bus = CTLR(c->qid);
- if(bus > nelem(usbhost) || (uh = usbhost[bus]) == nil) {
- error(Egreg);
- return nil; /* for compiler */
- }
- d = usbdeviceofslot(uh, SLOT(c->qid));
- if(d == nil || d->id != c->qid.vers || d->state == Disabled)
- error(Ehungup);
- return d;
-}
-
-static Endpt *
-devendpt(Udev *d, int id, int add)
-{
- Usbhost *uh;
- Endpt *e, **p;
-
- p = &d->ep[id&0xF];
- lock(d);
- e = *p;
- if(e != nil){
- incref(e);
- XPRINT("incref(0x%p) in devendpt, new value %ld\n", e, e->ref);
- unlock(d);
- return e;
- }
- unlock(d);
- if(!add)
- return nil;
-
- e = mallocz(sizeof(*e), 1);
- e->ref = 1;
- e->x = id&0xF;
- e->id = id;
- e->sched = -1;
- e->maxpkt = 8;
- e->nbuf = 1;
- e->dev = d;
- e->active = 0;
-
- uh = d->uh;
- uh->epalloc(uh, e);
-
- lock(d);
- if(*p != nil){
- incref(*p);
- XPRINT("incref(0x%p) in devendpt, new value %ld\n", *p, (*p)->ref);
- unlock(d);
- uh->epfree(uh, e);
- free(e);
- return *p;
- }
- *p = e;
- unlock(d);
- e->rq = qopen(8*1024, 0, nil, e);
- e->wq = qopen(8*1024, 0, nil, e);
- return e;
-}
-
-static void
-freept(Endpt *e)
-{
- Usbhost *uh;
-
- if(e != nil && decref(e) == 0){
- XPRINT("freept(%d,%d)\n", e->dev->x, e->x);
- uh = e->dev->uh;
- uh->epclose(uh, e);
- e->dev->ep[e->x] = nil;
- uh->epfree(uh, e);
- free(e);
- }
-}
-
-static Udev*
-usbnewdevice(Usbhost *uh)
-{
- int i;
- Udev *d;
- Endpt *e;
-
- d = nil;
- qlock(uh);
- if(waserror()){
- qunlock(uh);
- nexterror();
- }
- for(i=0; i<nelem(uh->dev); i++)
- if(uh->dev[i] == nil){
- uh->idgen++;
- d = mallocz(sizeof(*d), 1);
- d->uh = uh;
- d->ref = 1;
- d->x = i;
- d->id = (uh->idgen << 8) | i;
- d->state = Enabled;
- XPRINT("calling devendpt in usbnewdevice\n");
- e = devendpt(d, 0, 1); /* always provide control endpoint 0 */
- e->mode = ORDWR;
- e->iso = 0;
- e->sched = -1;
- uh->dev[i] = d;
- break;
- }
- poperror();
- qunlock(uh);
- return d;
-}
-
-static void
-freedev(Udev *d, int ept)
-{
- int i;
- Endpt *e;
- Usbhost *uh;
-
- uh = d->uh;
- if(decref(d) == 0){
- XPRINT("freedev 0x%p, 0\n", d);
- for(i=0; i<nelem(d->ep); i++)
- freept(d->ep[i]);
- if(d->x >= 0)
- uh->dev[d->x] = nil;
- free(d);
- } else {
- if(ept >= 0 && ept < nelem(d->ep)){
- e = d->ep[ept];
- XPRINT("freedev, freept 0x%p\n", e);
- if(e != nil)
- uh->epclose(uh, e);
- }
- }
-}
-
-static int
-usbgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
-{
- Qid q;
- Udev *d;
- Endpt *e;
- Dirtab *tab;
- Usbhost *uh;
- int t, bus, slot, perm;
-
- /*
- * Top level directory contains the controller names.
- */
- if(c->qid.path == Qtopdir){
- if(s == DEVDOTDOT){
- mkqid(&q, Qtopdir, 0, QTDIR);
- devdir(c, q, "#U", 0, eve, 0555, dp);
- return 1;
- }
- if(s >= nelem(usbhost) || usbhost[s] == nil)
- return -1;
- mkqid(&q, PATH(Q2nd, 0, s), 0, QTDIR);
- snprint(up->genbuf, sizeof up->genbuf, "usb%d", s);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- bus = CTLR(c->qid);
- if(bus >= nelem(usbhost) || (uh = usbhost[bus]) == nil)
- return -1;
-
- /*
- * Second level contains "new", "port", and a numbered
- * directory for each enumerated device on the bus.
- */
- t = TYPE(c->qid);
- if(t < Q3rd){
- if(s == DEVDOTDOT){
- mkqid(&q, Qtopdir, 0, QTDIR);
- devdir(c, q, "#U", 0, eve, 0555, dp);
- return 1;
- }
- if(s < nelem(usbdir2)){
- d = uh->dev[0];
- if(d == nil)
- return -1;
- tab = &usbdir2[s];
- mkqid(&q, PATH(tab->qid.path, 0, bus), d->id, QTFILE);
- devdir(c, q, tab->name, tab->length, eve, tab->perm, dp);
- return 1;
- }
- s -= nelem(usbdir2);
- if(s >= 0 && s < nelem(uh->dev)) {
- d = uh->dev[s];
- if(d == nil)
- return 0;
- sprint(up->genbuf, "%d", s);
- mkqid(&q, PATH(Q3rd, s, bus), d->id, QTDIR);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- return -1;
- }
-
- /*
- * Third level.
- */
- slot = SLOT(c->qid);
- if(s == DEVDOTDOT) {
- mkqid(&q, PATH(Q2nd, 0, bus), c->qid.vers, QTDIR);
- snprint(up->genbuf, sizeof up->genbuf, "usb%d", bus);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- if(s < nelem(usbdir3)) {
- tab = &usbdir3[s];
- mkqid(&q, PATH(tab->qid.path, slot, bus), c->qid.vers, QTFILE);
- devdir(c, q, tab->name, tab->length, eve, tab->perm, dp);
- return 1;
- }
- s -= nelem(usbdir3);
-
- /* active endpoints */
- d = usbdeviceofslot(uh, slot);
- if(d == nil || s >= nelem(d->ep))
- return -1;
- if(s == 0 || (e = d->ep[s]) == nil) /* ep0data is called "setup" */
- return 0;
- sprint(up->genbuf, "ep%ddata", s);
- mkqid(&q, PATH(Qep0+s, slot, bus), c->qid.vers, QTFILE);
- switch(e->mode) {
- case OREAD:
- perm = 0444;
- break;
- case OWRITE:
- perm = 0222;
- break;
- default:
- perm = 0666;
- break;
- }
- devdir(c, q, up->genbuf, e->buffered, eve, perm, dp);
- return 1;
-}
-
-static Usbhost*
-usbprobe(int cardno, int ctlrno)
-{
- Usbhost *uh;
- char buf[128], *ebuf, name[64], *p, *type;
-
- uh = malloc(sizeof(Usbhost));
- memset(uh, 0, sizeof(Usbhost));
- uh->tbdf = BUSUNKNOWN;
-
- if(cardno < 0){
- if(isaconfig("usb", ctlrno, uh) == 0){
- free(uh);
- return nil;
- }
- for(cardno = 0; usbtypes[cardno].type; cardno++){
- type = uh->type;
- if(type==nil || *type==0)
- type = "uhci";
- if(cistrcmp(usbtypes[cardno].type, type))
- continue;
- break;
- }
- }
-
- if(cardno >= MaxUsb || usbtypes[cardno].type == nil){
- free(uh);
- return nil;
- }
- if(usbtypes[cardno].reset(uh) < 0){
- free(uh);
- return nil;
- }
-
- /*
- * IRQ2 doesn't really exist, it's used to gang the interrupt
- * controllers together. A device set to IRQ2 will appear on
- * the second interrupt controller as IRQ9.
- */
- if(uh->irq == 2)
- uh->irq = 9;
- snprint(name, sizeof(name), "usb%d", ctlrno);
- intrenable(uh->irq, uh->interrupt, uh, uh->tbdf, name);
-
- ebuf = buf + sizeof buf;
- p = seprint(buf, ebuf, "#U/usb%d: %s: port 0x%luX irq %d", ctlrno, usbtypes[cardno].type, uh->port, uh->irq);
- if(uh->mem)
- p = seprint(p, ebuf, " addr 0x%luX", PADDR(uh->mem));
- if(uh->size)
- seprint(p, ebuf, " size 0x%luX", uh->size);
- print("%s\n", buf);
-
- return uh;
-}
-
-static void
-usbreset(void)
-{
- int cardno, ctlrno;
- Usbhost *uh;
-
- for(ctlrno = 0; ctlrno < MaxUsb; ctlrno++){
- if((uh = usbprobe(-1, ctlrno)) == nil)
- continue;
- usbhost[ctlrno] = uh;
- }
-
- if(getconf("*nousbprobe"))
- return;
-
- cardno = ctlrno = 0;
- while(usbtypes[cardno].type != nil && ctlrno < MaxUsb){
- if(usbhost[ctlrno] != nil){
- ctlrno++;
- continue;
- }
- if((uh = usbprobe(cardno, ctlrno)) == nil){
- cardno++;
- continue;
- }
- usbhost[ctlrno] = uh;
- ctlrno++;
- }
-}
-
-void
-usbinit(void)
-{
- Udev *d;
- int ctlrno;
- Usbhost *uh;
-
- for(ctlrno = 0; ctlrno < MaxUsb; ctlrno++){
- uh = usbhost[ctlrno];
- if(uh == nil)
- continue;
- if(uh->init != 0)
- uh->init(uh);
-
- /* reserve device for configuration */
- d = usbnewdevice(uh);
- incref(d);
- d->state = Attached;
- }
-}
-
-Chan *
-usbattach(char *spec)
-{
- return devattach('U', spec);
-}
-
-static Walkqid*
-usbwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, nil, 0, usbgen);
-}
-
-static int
-usbstat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, nil, 0, usbgen);
-}
-
-Chan*
-usbopen(Chan *c, int omode)
-{
- Udev *d;
- Endpt *e;
- int f, s, type;
- Usbhost *uh;
-
- if(c->qid.type == QTDIR)
- return devopen(c, omode, nil, 0, usbgen);
-
- f = 0;
- type = TYPE(c->qid);
- if(type == Qnew){
- d = usbdevice(c);
- d = usbnewdevice(d->uh);
- XPRINT("usbopen, new dev 0x%p\n", d);
- if(d == nil) {
- XPRINT("usbopen failed (usbnewdevice)\n");
- error(Enodev);
- }
- type = Qctl;
- mkqid(&c->qid, PATH(type, d->x, CTLR(c->qid)), d->id, QTFILE);
- f = 1;
- }
-
- if(type < Q3rd){
- XPRINT("usbopen, devopen < Q3rd\n");
- return devopen(c, omode, nil, 0, usbgen);
- }
-
- d = usbdevice(c);
- uh = d->uh;
- qlock(uh);
- if(waserror()){
- qunlock(uh);
- nexterror();
- }
-
- switch(type){
- case Qctl:
- if(0&&d->busy)
- error(Einuse);
- d->busy = 1;
- if(!f)
- incref(d);
- XPRINT("usbopen, Qctl 0x%p\n", d);
- break;
-
- default:
- s = type - Qep0;
- XPRINT("usbopen, default 0x%p, %d\n", d, s);
- if(s >= 0 && s < nelem(d->ep)){
- if((e = d->ep[s]) == nil) {
- XPRINT("usbopen failed (endpoint)\n");
- error(Enodev);
- }
- XPRINT("usbopen: dev 0x%p, ept 0x%p\n", d, e);
- uh->epopen(uh, e);
- e->foffset = 0;
- e->toffset = 0;
- e->poffset = 0;
- e->buffered = 0;
- }
- incref(d);
- break;
- }
- poperror();
- qunlock(uh);
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-void
-usbclose(Chan *c)
-{
- Udev *d;
- int ept, type;
- Usbhost *uh;
-
- type = TYPE(c->qid);
- if(c->qid.type == QTDIR || type < Q3rd)
- return;
- d = usbdevice(c);
- uh = d->uh;
- qlock(uh);
- if(waserror()){
- qunlock(uh);
- nexterror();
- }
- if(type == Qctl)
- d->busy = 0;
- XPRINT("usbclose: dev 0x%p\n", d);
- if(c->flag & COPEN){
- ept = (type != Qctl) ? type - Qep0 : -1;
- XPRINT("usbclose: freedev 0x%p\n", d);
- freedev(d, ept);
- }
- poperror();
- qunlock(uh);
-}
-
-static char *
-epstatus(char *s, char *se, Endpt *e, int i)
-{
- char *p;
-
- p = seprint(s, se, "%2d %#6.6lux %10lud bytes %10lud blocks\n", i, e->csp, e->nbytes, e->nblocks);
- if(e->iso){
- p = seprint(p, se, "bufsize %6d buffered %6d", e->maxpkt, e->buffered);
- if(e->toffset)
- p = seprint(p, se, " offset %10lud time %19lld\n", e->toffset, e->time);
- p = seprint(p, se, "\n");
- }
- return p;
-}
-
-long
-usbread(Chan *c, void *a, long n, vlong offset)
-{
- int t, i;
- Udev *d;
- Endpt *e;
- Usbhost *uh;
- char *s, *se, *p;
-
- if(c->qid.type == QTDIR)
- return devdirread(c, a, n, nil, 0, usbgen);
-
- d = usbdevice(c);
- uh = d->uh;
- t = TYPE(c->qid);
-
- if(t >= Qep0) {
- t -= Qep0;
- if(t >= nelem(d->ep))
- error(Eio);
- e = d->ep[t];
- if(e == nil || e->mode == OWRITE)
- error(Egreg);
- if(t == 0) {
- if(e->iso)
- error(Egreg);
- e->data01 = 1;
- n = uh->read(uh, e, a, n, 0LL);
- if(e->setin){
- e->setin = 0;
- e->data01 = 1;
- uh->write(uh, e, "", 0, 0LL, TokOUT);
- }
- return n;
- }
- return uh->read(uh, e, a, n, offset);
- }
-
- s = smalloc(READSTR);
- se = s+READSTR;
- if(waserror()){
- free(s);
- nexterror();
- }
- switch(t){
- case Qport:
- uh->portinfo(uh, s, se);
- break;
-
- case Qctl:
- seprint(s, se, "%11d %11d\n", d->x, d->id);
- break;
-
- case Qstatus:
- if (d->did || d->vid)
- p = seprint(s, se, "%s %#6.6lux %#4.4ux %#4.4ux\n", devstates[d->state], d->csp, d->vid, d->did);
- else
- p = seprint(s, se, "%s %#6.6lux\n", devstates[d->state], d->csp);
- for(i=0; i<nelem(d->ep); i++) {
- e = d->ep[i];
- if(e == nil)
- continue;
- /* TO DO: freeze e */
- p = epstatus(p, se, e, i);
- }
- }
- n = readstr(offset, a, n, s);
- poperror();
- free(s);
- return n;
-}
-
-long
-usbwrite(Chan *c, void *a, long n, vlong offset)
-{
- Udev *d;
- Endpt *e;
- Cmdtab *ct;
- Cmdbuf *cb;
- Usbhost *uh;
- int id, nw, t, i;
- char cmd[50];
-
- if(c->qid.type == QTDIR)
- error(Egreg);
- d = usbdevice(c);
- uh = d->uh;
- t = TYPE(c->qid);
- switch(t){
- case Qport:
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
-
- ct = lookupcmd(cb, usbportmsg, nelem(usbportmsg));
- id = strtol(cb->f[1], nil, 0);
- switch(ct->index){
- case PMdisable:
- uh->portenable(uh, id, 0);
- break;
- case PMenable:
- uh->portenable(uh, id, 1);
- break;
- case PMreset:
- uh->portreset(uh, id);
- break;
- }
-
- poperror();
- free(cb);
- return n;
- case Qctl:
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
-
- ct = lookupcmd(cb, usbctlmsg, nelem(usbctlmsg));
- switch(ct->index){
- case CMspeed:
- d->ls = strtoul(cb->f[1], nil, 0) == 0;
- break;
- case CMclass:
- if (cb->nf != 4 && cb->nf != 6)
- cmderror(cb, Ebadusbmsg);
- /* class #ifc ept csp ( == class subclass proto) [vendor product] */
- d->npt = strtoul(cb->f[1], nil, 0); /* # of interfaces */
- i = strtoul(cb->f[2], nil, 0); /* endpoint */
- if (i < 0 || i >= nelem(d->ep)
- || d->npt > nelem(d->ep) || i >= d->npt)
- cmderror(cb, Ebadusbmsg);
- if (cb->nf == 6) {
- d->vid = strtoul(cb->f[4], nil, 0);
- d->did = strtoul(cb->f[5], nil, 0);
- }
- if (i == 0)
- d->csp = strtoul(cb->f[3], nil, 0);
- if(d->ep[i] == nil){
- XPRINT("calling devendpt in usbwrite (CMclass)\n");
- d->ep[i] = devendpt(d, i, 1);
- }
- d->ep[i]->csp = strtoul(cb->f[3], nil, 0);
- break;
- case CMdata:
- i = strtoul(cb->f[1], nil, 0);
- if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadusbmsg);
- e = d->ep[i];
- e->data01 = strtoul(cb->f[2], nil, 0) != 0;
- break;
- case CMmaxpkt:
- i = strtoul(cb->f[1], nil, 0);
- if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadusbmsg);
- e = d->ep[i];
- e->maxpkt = strtoul(cb->f[2], nil, 0);
- if(e->maxpkt > 1500)
- e->maxpkt = 1500;
- break;
- case CMadjust:
- i = strtoul(cb->f[1], nil, 0);
- if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadusbmsg);
- e = d->ep[i];
- if (e->iso == 0)
- error(Eperm);
- i = strtoul(cb->f[2], nil, 0);
- /* speed may not result in change of maxpkt */
- if (i < (e->maxpkt-1)/e->samplesz * 1000/e->pollms
- || i > e->maxpkt/e->samplesz * 1000/e->pollms){
- snprint(cmd, sizeof(cmd), "%d < %d < %d?",
- (e->maxpkt-1)/e->samplesz * 1000/e->pollms,
- i,
- e->maxpkt/e->samplesz * 1000/e->pollms);
- error(cmd);
- }
- e->hz = i;
- break;
- case CMdebug:
- i = strtoul(cb->f[1], nil, 0);
- if(i < -1 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadusbmsg);
- if (i == -1)
- debug = 0;
- else {
- debug = 1;
- e = d->ep[i];
- e->debug = strtoul(cb->f[2], nil, 0);
- }
- break;
- case CMunstall:
- i = strtoul(cb->f[1], nil, 0);
- if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadusbmsg);
- e = d->ep[i];
- e->err = nil;
- break;
- case CMep:
- /* ep n `bulk' mode maxpkt nbuf OR
- * ep n period mode samplesize Hz
- */
- i = strtoul(cb->f[1], nil, 0);
- if(i < 0 || i >= nelem(d->ep)) {
- XPRINT("field 1: 0 <= %d < %d\n", i, nelem(d->ep));
- error(Ebadarg);
- }
- if((e = d->ep[i]) == nil){
- XPRINT("calling devendpt in usbwrite (CMep)\n");
- e = devendpt(d, i, 1);
- }
- qlock(uh);
- if(waserror()){
- freept(e);
- qunlock(uh);
- nexterror();
- }
- if(e->active)
- error(Eperm);
- if(strcmp(cb->f[2], "bulk") == 0){
- /* ep n `bulk' mode maxpkt nbuf */
- e->iso = 0;
- i = strtoul(cb->f[4], nil, 0);
- if(i < 8 || i > 1023)
- i = 8;
- e->maxpkt = i;
- i = strtoul(cb->f[5], nil, 0);
- if(i >= 1 && i <= 32)
- e->nbuf = i;
- } else {
- /* ep n period mode samplesize Hz */
- i = strtoul(cb->f[2], nil, 0);
- if(i > 0 && i <= 1000){
- e->pollms = i;
- }else {
- XPRINT("field 4: 0 <= %d <= 1000\n", i);
- error(Ebadarg);
- }
- i = strtoul(cb->f[4], nil, 0);
- if(i >= 1 && i <= 8){
- e->samplesz = i;
- }else {
- XPRINT("field 4: 0 < %d <= 8\n", i);
- error(Ebadarg);
- }
- i = strtoul(cb->f[5], nil, 0);
- if(i >= 1 && i*e->samplesz <= 12*1000*1000){
- /* Hz */
- e->hz = i;
- e->remain = 0;
- }else {
- XPRINT("field 5: 1 < %d <= 100000 Hz\n", i);
- error(Ebadarg);
- }
- e->maxpkt = (e->hz * e->pollms + 999)/1000 * e->samplesz;
- e->iso = 1;
- }
- e->mode = strcmp(cb->f[3],"r") == 0? OREAD :
- strcmp(cb->f[3],"w") == 0? OWRITE : ORDWR;
- uh->epmode(uh, e);
- poperror();
- qunlock(uh);
- }
-
- poperror();
- free(cb);
- return n;
-
- case Qep0: /* SETUP endpoint 0 */
- /* should canqlock etc */
- e = d->ep[0];
- if(e == nil || e->iso)
- error(Egreg);
- if(n < 8)
- error(Eio);
- nw = *(uchar*)a & RD2H;
- e->data01 = 0;
- n = uh->write(uh, e, a, n, 0LL, TokSETUP);
- if(nw == 0) { /* host to device: use IN[DATA1] to ack */
- e->data01 = 1;
- nw = uh->read(uh, e, cmd, 0LL, 8);
- if(nw != 0)
- error(Eio); /* could provide more status */
- }else
- e->setin = 1; /* two-phase */
- break;
-
- default: /* sends DATA[01] */
- t -= Qep0;
- if(t < 0 || t >= nelem(d->ep))
- error(Egreg);
- e = d->ep[t];
- if(e == nil || e->mode == OREAD)
- error(Egreg);
- n = uh->write(uh, e, a, n, offset, TokOUT);
- break;
- }
- return n;
-}
-
-Dev usbdevtab = {
- 'U',
- "usb",
-
- usbreset,
- usbinit,
- devshutdown,
- usbattach,
- usbwalk,
- usbstat,
- usbopen,
- devcreate,
- usbclose,
- usbread,
- devbread,
- usbwrite,
- devbwrite,
- devremove,
- devwstat,
-};
diff --git a/os/pc/devvga.c b/os/pc/devvga.c
deleted file mode 100644
index 0d7a9f0d..00000000
--- a/os/pc/devvga.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * VGA controller
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-typedef struct Vgaseg Vgaseg;
-struct Vgaseg {
- QLock;
- ulong pa;
- ulong len;
- void* va;
-};
-
-enum {
- Nvgaseg = 4,
-
- Qdir = 0,
- Qvgactl,
- Qvgaovl,
- Qvgaovlctl,
-
- Qsegs,
- Qmax = Qsegs+Nvgaseg
-};
-
-static Dirtab vgadir[Qmax] = {
- ".", { Qdir, 0, QTDIR }, 0, 0550,
- "vgactl", { Qvgactl, 0 }, 0, 0660,
- "vgaovl", { Qvgaovl, 0 }, 0, 0660,
- "vgaovlctl", { Qvgaovlctl, 0 }, 0, 0660,
- /* dynamically-created memory segments are added here */
-};
-
-static Vgaseg vgasegs[Nvgaseg];
-static Lock vgadirlock;
-static int nvgadir = Qsegs;
-
-enum {
- CMactualsize,
- CMblank,
- CMblanktime,
- CMdrawinit,
- CMhwaccel,
- CMhwblank,
- CMhwgc,
- CMlinear,
- CMpalettedepth,
- CMpanning,
- CMsize,
- CMtype,
- CMunblank,
-};
-
-static Cmdtab vgactlmsg[] = {
- CMactualsize, "actualsize", 2,
- CMblank, "blank", 1,
- CMblanktime, "blanktime", 2,
- CMdrawinit, "drawinit", 1,
- CMhwaccel, "hwaccel", 2,
- CMhwblank, "hwblank", 2,
- CMhwgc, "hwgc", 2,
- CMlinear, "linear", 0,
- CMpalettedepth, "palettedepth", 2,
- CMpanning, "panning", 2,
- CMsize, "size", 3,
- CMtype, "type", 2,
- CMunblank, "unblank", 1,
-};
-
-static void
-vgareset(void)
-{
- /* reserve the 'standard' vga registers */
- if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0)
- panic("vga ports already allocated");
- if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0)
- panic("vga ports already allocated");
- conf.monitor = 1;
-}
-
-void
-addvgaseg(char *name, ulong pa, ulong size)
-{
- int i;
- Dirtab d;
- Vgaseg *s;
- ulong va;
-
- va = mmukmap(pa, 0, size);
- if(va == 0)
- return;
- memset(&d, 0, sizeof(d));
- strecpy(d.name, d.name+sizeof(name), name);
- lock(&vgadirlock);
- for(i=0; i<nvgadir; i++)
- if(strcmp(vgadir[i].name, name) == 0){
- unlock(&vgadirlock);
- print("devvga: duplicate segment %s\n", name);
- return;
- }
- if(nvgadir >= nelem(vgadir)){
- unlock(&vgadirlock);
- print("devvga: segment %s: too many segments\n", name);
- return;
- }
- d.qid.path = nvgadir;
- d.perm = 0660;
- d.length = size;
- s = &vgasegs[nvgadir-Qsegs];
- s->pa = pa;
- s->len = size;
- s->va = (void*)va;
- vgadir[nvgadir] = d;
- nvgadir++;
- unlock(&vgadirlock);
-}
-
-static long
-vgasegrd(Vgaseg *s, uchar *buf, long n, ulong offset)
-{
- int i;
- uchar *a, *d;
- ulong v;
-
- if(offset >= s->len)
- return 0;
- if(offset+n > s->len)
- n = s->len - offset;
- d = (uchar*)s->va + offset;
- qlock(s);
- if(waserror()){
- qunlock(s);
- nexterror();
- }
- a = buf;
- while(n > 0){
- i = 4 - ((ulong)d & 3);
- if(i > n)
- i = n;
- if(i == 3)
- i = 2;
- switch(i){
- case 4:
- v = (a[3]<<24) | (a[2]<<16) | (a[1]<<8) | a[0];
- *(ulong*)d = v;
- break;
- case 2:
- v = (a[1]<<8) | a[0];
- *(ushort*)d = v;
- break;
- case 1:
- *d = *a;
- break;
- }
- d += i;
- a += i;
- n -= i;
- }
- poperror();
- qunlock(s);
- return a-buf;
-}
-
-static long
-vgasegwr(Vgaseg *s, uchar *buf, long n, ulong offset)
-{
- int i;
- uchar *a, *r;
- ulong v;
-
- if(offset >= s->len)
- return 0;
- if(offset+n > s->len)
- n = s->len - offset;
- r = (uchar*)s->va + offset;
- qlock(s);
- if(waserror()){
- qunlock(s);
- nexterror();
- }
- a = buf;
- while(n > 0){
- i = 4 - ((ulong)r & 3);
- if(i > n)
- i = n;
- if(i == 3)
- i = 2;
- switch(i){
- case 4:
- v = *(ulong*)r;
- a[0] = v;
- a[1] = v>>8;
- a[2] = v>>16;
- a[3] = v>>24;
- break;
- case 2:
- v = *(ushort*)r;
- a[0] = v;
- a[1] = v>>8;
- break;
- case 1:
- *a = *r;
- break;
- }
- r += i;
- a += i;
- n -= i;
- }
- poperror();
- qunlock(s);
- return a-buf;
-}
-
-static Chan*
-vgaattach(char* spec)
-{
- if(*spec && strcmp(spec, "0"))
- error(Eio);
- return devattach('v', spec);
-}
-
-Walkqid*
-vgawalk(Chan* c, Chan *nc, char** name, int nname)
-{
- return devwalk(c, nc, name, nname, vgadir, nvgadir, devgen);
-}
-
-static int
-vgastat(Chan* c, uchar* dp, int n)
-{
- return devstat(c, dp, n, vgadir, nvgadir, devgen);
-}
-
-static Chan*
-vgaopen(Chan* c, int omode)
-{
- VGAscr *scr;
- static char *openctl = "openctl\n";
-
- scr = &vgascreen[0];
- if ((ulong)c->qid.path == Qvgaovlctl) {
- if (scr->dev && scr->dev->ovlctl)
- scr->dev->ovlctl(scr, c, openctl, strlen(openctl));
- else
- error(Enonexist);
- }
- return devopen(c, omode, vgadir, nvgadir, devgen);
-}
-
-static void
-vgaclose(Chan* c)
-{
- VGAscr *scr;
- static char *closectl = "closectl\n";
-
- scr = &vgascreen[0];
- if((ulong)c->qid.path == Qvgaovlctl)
- if(scr->dev && scr->dev->ovlctl){
- if(waserror()){
- print("ovlctl error: %s\n", up->env->errstr);
- return;
- }
- scr->dev->ovlctl(scr, c, closectl, strlen(closectl));
- poperror();
- }
-}
-
-static void
-checkport(int start, int end)
-{
- /* standard vga regs are OK */
- if(start >= 0x2b0 && end <= 0x2df+1)
- return;
- if(start >= 0x3c0 && end <= 0x3da+1)
- return;
-
- if(iounused(start, end))
- return;
- error(Eperm);
-}
-
-static long
-vgaread(Chan* c, void* a, long n, vlong off)
-{
- int len;
- char *p, *s;
- VGAscr *scr;
- ulong offset = off;
- char chbuf[30];
-
- switch((ulong)c->qid.path){
-
- case Qdir:
- return devdirread(c, a, n, vgadir, nvgadir, devgen);
-
- case Qvgactl:
- scr = &vgascreen[0];
-
- p = malloc(READSTR);
- if(waserror()){
- free(p);
- nexterror();
- }
-
- len = 0;
-
- if(scr->dev)
- s = scr->dev->name;
- else
- s = "cga";
- len += snprint(p+len, READSTR-len, "type %s\n", s);
-
- if(scr->gscreen) {
- len += snprint(p+len, READSTR-len, "size %dx%dx%d %s\n",
- scr->gscreen->r.max.x, scr->gscreen->r.max.y,
- scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan));
-
- if(Dx(scr->gscreen->r) != Dx(physgscreenr)
- || Dy(scr->gscreen->r) != Dy(physgscreenr))
- len += snprint(p+len, READSTR-len, "actualsize %dx%d\n",
- physgscreenr.max.x, physgscreenr.max.y);
- }
-
- len += snprint(p+len, READSTR-len, "blank time %lud idle %d state %s\n",
- blanktime, drawidletime(), scr->isblank ? "off" : "on");
- len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
- len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
- len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
- snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->aperture);
- n = readstr(offset, a, n, p);
- poperror();
- free(p);
-
- return n;
-
- case Qvgaovl:
- case Qvgaovlctl:
- error(Ebadusefd);
- break;
-
- default:
- if(c->qid.path < nvgadir)
- return vgasegrd(&vgasegs[c->qid.path], a, n, offset);
- error(Egreg);
- break;
- }
-
- return 0;
-}
-
-static char Ebusy[] = "vga already configured";
-
-static void
-vgactl(Cmdbuf *cb)
-{
- int align, i, size, x, y, z;
- char *chanstr, *p;
- ulong chan;
- Cmdtab *ct;
- VGAscr *scr;
- extern VGAdev *vgadev[];
- extern VGAcur *vgacur[];
-
- scr = &vgascreen[0];
- ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg));
- switch(ct->index){
- case CMhwgc:
- if(strcmp(cb->f[1], "off") == 0){
- lock(&cursor);
- if(scr->cur){
- if(scr->cur->disable)
- scr->cur->disable(scr);
- scr->cur = nil;
- }
- unlock(&cursor);
- return;
- }
-
- for(i = 0; vgacur[i]; i++){
- if(strcmp(cb->f[1], vgacur[i]->name))
- continue;
- lock(&cursor);
- if(scr->cur && scr->cur->disable)
- scr->cur->disable(scr);
- scr->cur = vgacur[i];
- if(scr->cur->enable)
- scr->cur->enable(scr);
- unlock(&cursor);
- return;
- }
- break;
-
- case CMtype:
- for(i = 0; vgadev[i]; i++){
- if(strcmp(cb->f[1], vgadev[i]->name))
- continue;
- if(scr->dev && scr->dev->disable)
- scr->dev->disable(scr);
- scr->dev = vgadev[i];
- if(scr->dev->enable)
- scr->dev->enable(scr);
- return;
- }
- break;
-
- case CMsize:
- if(drawhasclients())
- error(Ebusy);
-
- x = strtoul(cb->f[1], &p, 0);
- if(x == 0 || x > 2048)
- error(Ebadarg);
- if(*p)
- p++;
-
- y = strtoul(p, &p, 0);
- if(y == 0 || y > 2048)
- error(Ebadarg);
- if(*p)
- p++;
-
- z = strtoul(p, &p, 0);
-
- chanstr = cb->f[2];
- if((chan = strtochan(chanstr)) == 0)
- error("bad channel");
-
- if(chantodepth(chan) != z)
- error("depth, channel do not match");
-
- cursoroff(1);
- deletescreenimage();
- if(screensize(x, y, z, chan))
- error(Egreg);
- vgascreenwin(scr);
- cursoron(1);
- return;
-
- case CMactualsize:
- if(scr->gscreen == nil)
- error("set the screen size first");
-
- x = strtoul(cb->f[1], &p, 0);
- if(x == 0 || x > 2048)
- error(Ebadarg);
- if(*p)
- p++;
-
- y = strtoul(p, nil, 0);
- if(y == 0 || y > 2048)
- error(Ebadarg);
-
- if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y)
- error("physical screen bigger than virtual");
-
- physgscreenr = Rect(0,0,x,y);
- scr->gscreen->clipr = physgscreenr;
- return;
-
- case CMpalettedepth:
- x = strtoul(cb->f[1], &p, 0);
- if(x != 8 && x != 6)
- error(Ebadarg);
-
- scr->palettedepth = x;
- return;
-
- case CMdrawinit:
- memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP, S);
- if(scr && scr->dev && scr->dev->drawinit)
- scr->dev->drawinit(scr);
- return;
-
- case CMlinear:
- if(cb->nf!=2 && cb->nf!=3)
- error(Ebadarg);
- size = strtoul(cb->f[1], 0, 0);
- if(cb->nf == 2)
- align = 0;
- else
- align = strtoul(cb->f[2], 0, 0);
- if(screenaperture(size, align))
- error("not enough free address space");
- return;
-
- case CMblank:
- drawblankscreen(1);
- return;
-
- case CMunblank:
- drawblankscreen(0);
- return;
-
- case CMblanktime:
- blanktime = strtoul(cb->f[1], 0, 0);
- return;
-
- case CMpanning:
- if(strcmp(cb->f[1], "on") == 0){
- if(scr == nil || scr->cur == nil)
- error("set screen first");
- if(!scr->cur->doespanning)
- error("panning not supported");
- scr->gscreen->clipr = scr->gscreen->r;
- panning = 1;
- }
- else if(strcmp(cb->f[1], "off") == 0){
- scr->gscreen->clipr = physgscreenr;
- panning = 0;
- }else
- break;
- return;
-
- case CMhwaccel:
- if(strcmp(cb->f[1], "on") == 0)
- hwaccel = 1;
- else if(strcmp(cb->f[1], "off") == 0)
- hwaccel = 0;
- else
- break;
- return;
-
- case CMhwblank:
- if(strcmp(cb->f[1], "on") == 0)
- hwblank = 1;
- else if(strcmp(cb->f[1], "off") == 0)
- hwblank = 0;
- else
- break;
- return;
- }
-
- cmderror(cb, "bad VGA control message");
-}
-
-char Enooverlay[] = "No overlay support";
-
-static long
-vgawrite(Chan* c, void* a, long n, vlong off)
-{
- ulong offset = off;
- Cmdbuf *cb;
- VGAscr *scr;
-
- switch((ulong)c->qid.path){
-
- case Qdir:
- error(Eperm);
-
- case Qvgactl:
- if(offset || n >= READSTR)
- error(Ebadarg);
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
- vgactl(cb);
- poperror();
- free(cb);
- return n;
-
- case Qvgaovl:
- scr = &vgascreen[0];
- if (scr->dev == nil || scr->dev->ovlwrite == nil) {
- error(Enooverlay);
- break;
- }
- return scr->dev->ovlwrite(scr, a, n, off);
-
- case Qvgaovlctl:
- scr = &vgascreen[0];
- if (scr->dev == nil || scr->dev->ovlctl == nil) {
- error(Enooverlay);
- break;
- }
- scr->dev->ovlctl(scr, c, a, n);
- return n;
-
- default:
- if(c->qid.path < nvgadir)
- return vgasegwr(&vgasegs[c->qid.path], a, n, offset);
- error(Egreg);
- break;
- }
-
- return 0;
-}
-
-Dev vgadevtab = {
- 'v',
- "vga",
-
- vgareset,
- devinit,
- devshutdown,
- vgaattach,
- vgawalk,
- vgastat,
- vgaopen,
- devcreate,
- vgaclose,
- vgaread,
- devbread,
- vgawrite,
- devbwrite,
- devremove,
- devwstat,
-};
diff --git a/os/pc/devzt5512.c b/os/pc/devzt5512.c
deleted file mode 100644
index af189fff..00000000
--- a/os/pc/devzt5512.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Namespace Interface for Ziatech 5512 System Registers
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-
-enum{
- Qdir,
- Qsysid,
- Qwatchdog,
- Qledctl,
- Qpower,
- Qswitch,
- Qstat,
-};
-
-static
-Dirtab zttab[]={
- ".", {Qdir,0,QTDIR}, 0, 0555,
- "id", {Qsysid, 0}, 0, 0444,
- "watchdog", {Qwatchdog, 0}, 0, 0600,
- "ledctl", {Qledctl, 0}, 0, 0666,
- "powerstat", {Qpower, 0}, 0, 0444,
- "switch", {Qswitch, 0}, 0, 0444,
- "stat", {Qstat, 0}, 0, 0444,
-};
-
-extern int watchdog;
-void
-watchdog_strobe(void)
-{
- uchar sysreg;
-
- sysreg = inb(0x78);
- sysreg &= (~1);
- outb(0x78, sysreg); /* disable/strobe watchdog */
- sysreg |= 1;
- outb(0x78, sysreg); /* enable watchdog */
-}
-
-static void
-ztreset(void) /* default in dev.c */
-{
- uchar sysreg;
-
- if(watchdog)
- addclock0link(watchdog_strobe);
- /* clear status LEDs */
- sysreg = inb(0xe2);
- sysreg &= ~3; /* clear usr1 */
- sysreg &= ~(3 << 2); /* clear usr2 */
- outb(0xe2, sysreg);
-}
-
-static Chan*
-ztattach(char* spec)
-{
- return devattach('Z', spec);
-}
-
-static int
-ztwalk(Chan* c, char* name)
-{
- return devwalk(c, name, zttab, nelem(zttab), devgen);
-}
-
-static void
-ztstat(Chan* c, char* db)
-{
- devstat(c, db, zttab, nelem(zttab), devgen);
-}
-
-static Chan*
-ztopen(Chan* c, int omode)
-{
- return devopen(c, omode, zttab, nelem(zttab), devgen);
-}
-
-static void
-ztclose(Chan* c)
-{
- USED(c);
-}
-
-static long
-ztread(Chan* c, void* a, long n, vlong offset)
-{
- uchar sysreg;
- char buf[256];
-
- USED(offset);
-
- switch(c->qid.path & ~CHDIR) {
- case Qdir:
- return devdirread(c, a, n, zttab, nelem(zttab), devgen);
- case Qsysid: {
- ulong rev;
- sysreg = inb(0xe3);
- rev = (ulong) (sysreg & 0x7f);
- sysreg = inb(0xe2);
- sprint(buf, "Board Rev: %lud\nSerial #: %lud\n", rev, (ulong)(sysreg >> 4));
- return readstr(offset, a, n, buf);
- };
- case Qwatchdog:
- sysreg = inb(0x78);
- if((sysreg & 1) == 1) {
- n = readstr(offset, a, n, "enabled");
- } else {
- n = readstr(offset, a, n, "disabled");
- }
- return n;
- case Qledctl:
- {
- char usr1[6], usr2[6];
- sysreg = inb(0xe2);
- switch( sysreg & 3 ) {
- case 0:
- case 3:
- sprint(usr1, "off");
- break;
- case 1:
- sprint(usr1, "red");
- break;
- case 2:
- sprint(usr1, "green");
- };
- switch( (sysreg >> 2) & 3) {
- case 0:
- case 3:
- sprint(usr2, "off");
- break;
- case 1:
- sprint(usr2, "red");
- break;
- case 2:
- sprint(usr2, "green");
- };
- sprint(buf, "usr1: %s\nusr2: %s\n",usr1, usr2);
- return readstr(offset, a, n, buf);
- };
- case Qpower:
- sysreg = inb(0xe4);
- sprint(buf, "DEG#: %d\nFAL#: %d\n", (sysreg & 2), (sysreg & 1));
- return readstr(offset, a, n, buf);
- case Qswitch:
- sysreg = inb(0xe4);
- sprint(buf, "%d %d %d %d", (sysreg & (1<<6)), (sysreg & (1<<5)), (sysreg & (1<<4)), (sysreg & (1<<3)));
- return readstr(offset, a, n, buf);
- case Qstat: {
- char bus[10],cpu[20], mode[20], boot[20];
-
- sysreg = inb(0xe5);
- switch (sysreg & 0x7) {
- case 1:
- sprint(bus, "66 MHz");
- break;
- case 2:
- sprint(bus, "60 MHz");
- break;
- case 3:
- sprint(bus, "50 MHz");
- break;
- default:
- sprint(bus, "unknown");
- };
- switch ((sysreg>>3)&0x7) {
- case 0:
- sprint(cpu, "75, 90, 100 MHz");
- break;
- case 1:
- sprint(cpu, "120, 133 MHz");
- break;
- case 2:
- sprint(cpu, "180, 200 MHz");
- break;
- case 3:
- sprint(cpu, "150, 166 MHz");
- default:
- sprint(cpu, "unknown");
- };
- if(sysreg & (1<<6))
- sprint(mode, "Port 80 test mode");
- else
- sprint(mode, "Normal decode");
- if(sysreg & (1<<7))
- sprint(boot,"EEPROM");
- else
- sprint(boot,"Flash");
- sprint(buf,"Bus Frequency: %s\nPentium: %s\nTest Mode Status: %s\nBIOS Boot ROM: %s\n",
- bus, cpu, mode, boot);
- return readstr(offset, a, n, buf);
- };
- default:
- n=0;
- break;
- }
- return n;
-}
-
-
-
-static long
-ztwrite(Chan* c, void *vp, long n, vlong offset)
-{
- uchar sysreg;
- char buf[256];
- char *a;
- int nf;
- char *fields[3];
-
- a = vp;
- if(n >= sizeof(buf))
- n = sizeof(buf)-1;
- strncpy(buf, a, n);
- buf[n] = 0;
-
- USED(a, offset);
-
- switch(c->qid.path & ~CHDIR){
- case Qwatchdog:
- sysreg = inb(0x78);
-
- if(strncmp(buf, "enable", 6) == 0) {
- if((sysreg & 1) != 1)
- addclock0link(watchdog_strobe);
- break;
- }
- n = 0;
- error(Ebadarg);
- case Qledctl:
- nf = getfields(buf, fields, 3, 1, " \t\n");
- if(nf < 2) {
- error(Ebadarg);
- n = 0;
- break;
- }
- sysreg = inb(0xe2);
- USED(sysreg);
- if(strncmp(fields[0],"usr1", 4)==0) {
- sysreg &= ~3;
- if(strncmp(fields[1], "off", 3)==0) {
- outb(0xe2, sysreg);
- break;
- }
- if(strncmp(fields[1], "red", 3)==0) {
- sysreg |= 1;
- outb(0xe2, sysreg);
- break;
- }
- if(strncmp(fields[1], "green", 5)==0) {
- sysreg |= 2;
- outb(0xe2, sysreg);
- break;
- }
- }
- if(strncmp(fields[0],"usr2", 4)==0) {
- sysreg &= ~(3 << 2);
- if(strncmp(fields[1], "off", 3)==0) {
- outb(0xe2, sysreg);
- break;
- }
- if(strncmp(fields[1], "red", 3)==0) {
- sysreg |= (1 << 2);
- outb(0xe2, sysreg);
- break;
- }
- if(strncmp(fields[1], "green", 5)==0) {
- sysreg |= (2 << 2);
- outb(0xe2, sysreg);
- break;
- }
- }
- n = 0;
- error(Ebadarg);
- default:
- error(Ebadusefd);
- }
- return n;
-}
-
-
-
-Dev zt5512devtab = { /* defaults in dev.c */
- 'Z',
- "Ziatech5512",
-
- ztreset, /* devreset */
- devinit, /* devinit */
- ztattach,
- devdetach,
- devclone, /* devclone */
- ztwalk,
- ztstat,
- ztopen,
- devcreate, /* devcreate */
- ztclose,
- ztread,
- devbread, /* devbread */
- ztwrite,
- devbwrite, /* devbwrite */
- devremove, /* devremove */
- devwstat, /* devwstat */
-};
diff --git a/os/pc/dma.c b/os/pc/dma.c
deleted file mode 100644
index 9da7bddd..00000000
--- a/os/pc/dma.c
+++ /dev/null
@@ -1,237 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-typedef struct DMAport DMAport;
-typedef struct DMA DMA;
-typedef struct DMAxfer DMAxfer;
-
-/*
- * state of a dma transfer
- */
-struct DMAxfer
-{
- ulong bpa; /* bounce buffer physical address */
- void* bva; /* bounce buffer virtual address */
- int blen; /* bounce buffer length */
- void* va; /* virtual address destination/src */
- long len; /* bytes to be transferred */
- int isread;
-};
-
-/*
- * the dma controllers. the first half of this structure specifies
- * the I/O ports used by the DMA controllers.
- */
-struct DMAport
-{
- uchar addr[4]; /* current address (4 channels) */
- uchar count[4]; /* current count (4 channels) */
- uchar page[4]; /* page registers (4 channels) */
- uchar cmd; /* command status register */
- uchar req; /* request registers */
- uchar sbm; /* single bit mask register */
- uchar mode; /* mode register */
- uchar cbp; /* clear byte pointer */
- uchar mc; /* master clear */
- uchar cmask; /* clear mask register */
- uchar wam; /* write all mask register bit */
-};
-
-struct DMA
-{
- DMAport;
- int shift;
- Lock;
- DMAxfer x[4];
-};
-
-DMA dma[2] = {
- { 0x00, 0x02, 0x04, 0x06,
- 0x01, 0x03, 0x05, 0x07,
- 0x87, 0x83, 0x81, 0x82,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0 },
-
- { 0xc0, 0xc4, 0xc8, 0xcc,
- 0xc2, 0xc6, 0xca, 0xce,
- 0x8f, 0x8b, 0x89, 0x8a,
- 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
- 1 },
-};
-
-/*
- * DMA must be in the first 16MB. This gets called early by the
- * initialisation routines of any devices which require DMA to ensure
- * the allocated bounce buffers are below the 16MB limit.
- */
-int
-dmainit(int chan, int maxtransfer)
-{
- DMA *dp;
- DMAxfer *xp;
- static int once;
-
- if(once == 0){
- if(ioalloc(0x00, 0x10, 0, "dma") < 0
- || ioalloc(0x80, 0x10, 0, "dma") < 0
- || ioalloc(0xd0, 0x10, 0, "dma") < 0)
- panic("dmainit");
- once = 1;
- }
-
- if(maxtransfer > 64*1024)
- maxtransfer = 64*1024;
-
- dp = &dma[(chan>>2)&1];
- chan = chan & 3;
- xp = &dp->x[chan];
- if(xp->bva != nil){
- if(xp->blen < maxtransfer)
- return 1;
- return 0;
- }
-
- xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024);
- if(xp->bva == nil)
- return 1;
- xp->bpa = PADDR(xp->bva);
- if(xp->bpa >= 16*MB){
- /*
- * This will panic with the current
- * implementation of xspanalloc().
- xfree(xp->bva);
- */
- xp->bva = nil;
- return 1;
- }
- xp->blen = maxtransfer;
- xp->len = 0;
- xp->isread = 0;
-
- return 0;
-}
-
-/*
- * setup a dma transfer. if the destination is not in kernel
- * memory, allocate a page for the transfer.
- *
- * we assume BIOS has set up the command register before we
- * are booted.
- *
- * return the updated transfer length (we can't transfer across 64k
- * boundaries)
- */
-long
-dmasetup(int chan, void *va, long len, int isread)
-{
- DMA *dp;
- ulong pa;
- uchar mode;
- DMAxfer *xp;
-
- dp = &dma[(chan>>2)&1];
- chan = chan & 3;
- xp = &dp->x[chan];
-
- /*
- * if this isn't kernel memory or crossing 64k boundary or above 16 meg
- * use the bounce buffer.
- */
- pa = PADDR(va);
- if((((ulong)va)&0xF0000000) != KZERO
- || (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
- || pa >= 16*MB) {
- if(xp->bva == nil)
- return -1;
- if(len > xp->blen)
- len = xp->blen;
- if(!isread)
- memmove(xp->bva, va, len);
- xp->va = va;
- xp->len = len;
- xp->isread = isread;
- pa = xp->bpa;
- }
- else
- xp->len = 0;
-
- /*
- * this setup must be atomic
- */
- ilock(dp);
- mode = (isread ? 0x44 : 0x48) | chan;
- outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
- outb(dp->page[chan], pa>>16);
- outb(dp->cbp, 0); /* set count & address to their first byte */
- outb(dp->addr[chan], pa>>dp->shift); /* set address */
- outb(dp->addr[chan], pa>>(8+dp->shift));
- outb(dp->count[chan], (len>>dp->shift)-1); /* set count */
- outb(dp->count[chan], ((len>>dp->shift)-1)>>8);
- outb(dp->sbm, chan); /* enable the channel */
- iunlock(dp);
-
- return len;
-}
-
-int
-dmadone(int chan)
-{
- DMA *dp;
-
- dp = &dma[(chan>>2)&1];
- chan = chan & 3;
-
- return inb(dp->cmd) & (1<<chan);
-}
-
-/*
- * this must be called after a dma has been completed.
- *
- * if a page has been allocated for the dma,
- * copy the data into the actual destination
- * and free the page.
- */
-void
-dmaend(int chan)
-{
- DMA *dp;
- DMAxfer *xp;
-
- dp = &dma[(chan>>2)&1];
- chan = chan & 3;
-
- /*
- * disable the channel
- */
- ilock(dp);
- outb(dp->sbm, 4|chan);
- iunlock(dp);
-
- xp = &dp->x[chan];
- if(xp->len == 0 || !xp->isread)
- return;
-
- /*
- * copy out of temporary page
- */
- memmove(xp->va, xp->bva, xp->len);
- xp->len = 0;
-}
-
-/*
-int
-dmacount(int chan)
-{
- int retval;
- DMA *dp;
-
- dp = &dma[(chan>>2)&1];
- outb(dp->cbp, 0);
- retval = inb(dp->count[chan]);
- retval |= inb(dp->count[chan]) << 8;
- return((retval<<dp->shift)+1);
-}
- */
diff --git a/os/pc/ether2000.c b/os/pc/ether2000.c
deleted file mode 100644
index 8fc8911e..00000000
--- a/os/pc/ether2000.c
+++ /dev/null
@@ -1,232 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-#include "ether8390.h"
-
-/*
- * Driver written for the 'Notebook Computer Ethernet LAN Adapter',
- * a plug-in to the bus-slot on the rear of the Gateway NOMAD 425DXL
- * laptop. The manual says NE2000 compatible.
- * The interface appears to be pretty well described in the National
- * Semiconductor Local Area Network Databook (1992) as one of the
- * AT evaluation cards.
- *
- * The NE2000 is really just a DP8390[12] plus a data port
- * and a reset port.
- */
-enum {
- Data = 0x10, /* offset from I/O base of data port */
- Reset = 0x1F, /* offset from I/O base of reset port */
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- Pcidev* pcidev;
- Ctlr* next;
- int active;
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-static struct {
- char* name;
- int id;
-} ne2000pci[] = {
- { "Realtek 8029", (0x8029<<16)|0x10EC, },
- { "Winbond 89C940", (0x0940<<16)|0x1050, },
- { nil },
-};
-
-static Ctlr*
-ne2000match(Ether* edev, int id)
-{
- int port;
- Pcidev *p;
- Ctlr *ctlr;
-
- /*
- * Any adapter matches if no edev->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- p = ctlr->pcidev;
- if(((p->did<<16)|p->vid) != id)
- continue;
- port = p->mem[0].bar & ~0x01;
- if(edev->port != 0 && edev->port != port)
- continue;
-
- /*
- * It suffices to fill these in,
- * the rest is gleaned from the card.
- */
- edev->port = port;
- edev->irq = p->intl;
-
- ctlr->active = 1;
-
- return ctlr;
- }
-
- return nil;
-}
-
-static void
-ne2000pnp(Ether* edev)
-{
- int i, id;
- Pcidev *p;
- Ctlr *ctlr;
-
- /*
- * Make a list of all ethernet controllers
- * if not already done.
- */
- if(ctlrhead == nil){
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != 0x02 || p->ccru != 0)
- continue;
- ctlr = malloc(sizeof(Ctlr));
- ctlr->pcidev = p;
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- }
- }
-
- /*
- * Is it a card with an unrecognised vid+did?
- * Normally a search is made through all the found controllers
- * for one which matches any of the known vid+did pairs.
- * If a vid+did pair is specified a search is made for that
- * specific controller only.
- */
- id = 0;
- for(i = 0; i < edev->nopt; i++){
- if(cistrncmp(edev->opt[i], "id=", 3) == 0)
- id = strtol(&edev->opt[i][3], nil, 0);
- }
-
- if(id != 0)
- ne2000match(edev, id);
- else for(i = 0; ne2000pci[i].name; i++){
- if(ne2000match(edev, ne2000pci[i].id) != nil)
- break;
- }
-}
-
-static int
-ne2000reset(Ether* edev)
-{
- ushort buf[16];
- ulong port;
- Dp8390 *dp8390;
- int i;
- uchar ea[Eaddrlen];
-
- if(edev->port == 0)
- ne2000pnp(edev);
-
- /*
- * Set up the software configuration.
- * Use defaults for irq, mem and size
- * if not specified.
- * Must have a port, no more default.
- */
- if(edev->port == 0)
- return -1;
- if(edev->irq == 0)
- edev->irq = 2;
- if(edev->mem == 0)
- edev->mem = 0x4000;
- if(edev->size == 0)
- edev->size = 16*1024;
- port = edev->port;
-
- if(ioalloc(edev->port, 0x20, 0, "ne2000") < 0)
- return -1;
-
- edev->ctlr = malloc(sizeof(Dp8390));
- dp8390 = edev->ctlr;
- dp8390->width = 2;
- dp8390->ram = 0;
-
- dp8390->port = port;
- dp8390->data = port+Data;
-
- dp8390->tstart = HOWMANY(edev->mem, Dp8390BufSz);
- dp8390->pstart = dp8390->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
- dp8390->pstop = dp8390->tstart + HOWMANY(edev->size, Dp8390BufSz);
-
- dp8390->dummyrr = 1;
- for(i = 0; i < edev->nopt; i++){
- if(strcmp(edev->opt[i], "nodummyrr"))
- continue;
- dp8390->dummyrr = 0;
- break;
- }
-
- /*
- * Reset the board. This is done by doing a read
- * followed by a write to the Reset address.
- */
- buf[0] = inb(port+Reset);
- delay(2);
- outb(port+Reset, buf[0]);
- delay(2);
-
- /*
- * Init the (possible) chip, then use the (possible)
- * chip to read the (possible) PROM for ethernet address
- * and a marker byte.
- * Could just look at the DP8390 command register after
- * initialisation has been tried, but that wouldn't be
- * enough, there are other ethernet boards which could
- * match.
- * Parallels has buf[0x0E] == 0x00 whereas real hardware
- * usually has 0x57.
- */
- dp8390reset(edev);
- memset(buf, 0, sizeof(buf));
- dp8390read(dp8390, buf, 0, sizeof(buf));
- i = buf[0x0E] & 0xFF;
- if((i != 0x00 && i != 0x57) || (buf[0x0F] & 0xFF) != 0x57){
- iofree(edev->port);
- free(edev->ctlr);
- return -1;
- }
-
- /*
- * Stupid machine. Shorts were asked for,
- * shorts were delivered, although the PROM is a byte array.
- * Set the ethernet address.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, edev->ea, Eaddrlen) == 0){
- for(i = 0; i < sizeof(edev->ea); i++)
- edev->ea[i] = buf[i];
- }
- dp8390setea(edev);
-
- return 0;
-}
-
-void
-ether2000link(void)
-{
- addethercard("NE2000", ne2000reset);
-}
diff --git a/os/pc/ether2114x.c b/os/pc/ether2114x.c
deleted file mode 100644
index f71773c0..00000000
--- a/os/pc/ether2114x.c
+++ /dev/null
@@ -1,1830 +0,0 @@
-/*
- * Digital Semiconductor DECchip 2114x PCI Fast Ethernet LAN Controller.
- * To do:
- * thresholds;
- * ring sizing;
- * handle more error conditions;
- * tidy setup packet mess;
- * push initialisation back to attach;
- * full SROM decoding.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-#define DEBUG (0)
-#define debug if(DEBUG)print
-
-enum {
- Nrde = 64,
- Ntde = 64,
-};
-
-#define Rbsz ROUNDUP(sizeof(Etherpkt)+4, 4)
-
-enum { /* CRS0 - Bus Mode */
- Swr = 0x00000001, /* Software Reset */
- Bar = 0x00000002, /* Bus Arbitration */
- Dsl = 0x0000007C, /* Descriptor Skip Length (field) */
- Ble = 0x00000080, /* Big/Little Endian */
- Pbl = 0x00003F00, /* Programmable Burst Length (field) */
- Cal = 0x0000C000, /* Cache Alignment (field) */
- Cal8 = 0x00004000, /* 8 longword boundary alignment */
- Cal16 = 0x00008000, /* 16 longword boundary alignment */
- Cal32 = 0x0000C000, /* 32 longword boundary alignment */
- Tap = 0x000E0000, /* Transmit Automatic Polling (field) */
- Dbo = 0x00100000, /* Descriptor Byte Ordering Mode */
- Rml = 0x00200000, /* Read Multiple */
-};
-
-enum { /* CSR[57] - Status and Interrupt Enable */
- Ti = 0x00000001, /* Transmit Interrupt */
- Tps = 0x00000002, /* Transmit Process Stopped */
- Tu = 0x00000004, /* Transmit buffer Unavailable */
- Tjt = 0x00000008, /* Transmit Jabber Timeout */
- Unf = 0x00000020, /* transmit UNderFlow */
- Ri = 0x00000040, /* Receive Interrupt */
- Ru = 0x00000080, /* Receive buffer Unavailable */
- Rps = 0x00000100, /* Receive Process Stopped */
- Rwt = 0x00000200, /* Receive Watchdog Timeout */
- Eti = 0x00000400, /* Early Transmit Interrupt */
- Gte = 0x00000800, /* General purpose Timer Expired */
- Fbe = 0x00002000, /* Fatal Bit Error */
- Ais = 0x00008000, /* Abnormal Interrupt Summary */
- Nis = 0x00010000, /* Normal Interrupt Summary */
- Rs = 0x000E0000, /* Receive process State (field) */
- Ts = 0x00700000, /* Transmit process State (field) */
- Eb = 0x03800000, /* Error bits */
-};
-
-enum { /* CSR6 - Operating Mode */
- Hp = 0x00000001, /* Hash/Perfect receive filtering mode */
- Sr = 0x00000002, /* Start/stop Receive */
- Ho = 0x00000004, /* Hash-Only filtering mode */
- Pb = 0x00000008, /* Pass Bad frames */
- If = 0x00000010, /* Inverse Filtering */
- Sb = 0x00000020, /* Start/stop Backoff counter */
- Pr = 0x00000040, /* Promiscuous Mode */
- Pm = 0x00000080, /* Pass all Multicast */
- Fd = 0x00000200, /* Full Duplex mode */
- Om = 0x00000C00, /* Operating Mode (field) */
- Fc = 0x00001000, /* Force Collision */
- St = 0x00002000, /* Start/stop Transmission Command */
- Tr = 0x0000C000, /* ThReshold control bits (field) */
- Tr128 = 0x00000000,
- Tr256 = 0x00004000,
- Tr512 = 0x00008000,
- Tr1024 = 0x0000C000,
- Ca = 0x00020000, /* CApture effect enable */
- Ps = 0x00040000, /* Port Select */
- Hbd = 0x00080000, /* HeartBeat Disable */
- Imm = 0x00100000, /* IMMediate mode */
- Sf = 0x00200000, /* Store and Forward */
- Ttm = 0x00400000, /* Transmit Threshold Mode */
- Pcs = 0x00800000, /* PCS function */
- Scr = 0x01000000, /* SCRambler mode */
- Mbo = 0x02000000, /* Must Be One */
- Ra = 0x40000000, /* Receive All */
- Sc = 0x80000000, /* Special Capture effect enable */
-
- TrMODE = Tr512, /* default transmission threshold */
-};
-
-enum { /* CSR9 - ROM and MII Management */
- Scs = 0x00000001, /* serial ROM chip select */
- Sclk = 0x00000002, /* serial ROM clock */
- Sdi = 0x00000004, /* serial ROM data in */
- Sdo = 0x00000008, /* serial ROM data out */
- Ss = 0x00000800, /* serial ROM select */
- Wr = 0x00002000, /* write */
- Rd = 0x00004000, /* read */
-
- Mdc = 0x00010000, /* MII management clock */
- Mdo = 0x00020000, /* MII management write data */
- Mii = 0x00040000, /* MII management operation mode (W) */
- Mdi = 0x00080000, /* MII management data in */
-};
-
-enum { /* CSR12 - General-Purpose Port */
- Gpc = 0x00000100, /* General Purpose Control */
-};
-
-typedef struct Des {
- int status;
- int control;
- ulong addr;
- Block* bp;
-} Des;
-
-enum { /* status */
- Of = 0x00000001, /* Rx: OverFlow */
- Ce = 0x00000002, /* Rx: CRC Error */
- Db = 0x00000004, /* Rx: Dribbling Bit */
- Re = 0x00000008, /* Rx: Report on MII Error */
- Rw = 0x00000010, /* Rx: Receive Watchdog */
- Ft = 0x00000020, /* Rx: Frame Type */
- Cs = 0x00000040, /* Rx: Collision Seen */
- Tl = 0x00000080, /* Rx: Frame too Long */
- Ls = 0x00000100, /* Rx: Last deScriptor */
- Fs = 0x00000200, /* Rx: First deScriptor */
- Mf = 0x00000400, /* Rx: Multicast Frame */
- Rf = 0x00000800, /* Rx: Runt Frame */
- Dt = 0x00003000, /* Rx: Data Type (field) */
- De = 0x00004000, /* Rx: Descriptor Error */
- Fl = 0x3FFF0000, /* Rx: Frame Length (field) */
- Ff = 0x40000000, /* Rx: Filtering Fail */
-
- Def = 0x00000001, /* Tx: DEFerred */
- Uf = 0x00000002, /* Tx: UnderFlow error */
- Lf = 0x00000004, /* Tx: Link Fail report */
- Cc = 0x00000078, /* Tx: Collision Count (field) */
- Hf = 0x00000080, /* Tx: Heartbeat Fail */
- Ec = 0x00000100, /* Tx: Excessive Collisions */
- Lc = 0x00000200, /* Tx: Late Collision */
- Nc = 0x00000400, /* Tx: No Carrier */
- Lo = 0x00000800, /* Tx: LOss of carrier */
- To = 0x00004000, /* Tx: Transmission jabber timeOut */
-
- Es = 0x00008000, /* [RT]x: Error Summary */
- Own = 0x80000000, /* [RT]x: OWN bit */
-};
-
-enum { /* control */
- Bs1 = 0x000007FF, /* [RT]x: Buffer 1 Size */
- Bs2 = 0x003FF800, /* [RT]x: Buffer 2 Size */
-
- Ch = 0x01000000, /* [RT]x: second address CHained */
- Er = 0x02000000, /* [RT]x: End of Ring */
-
- Ft0 = 0x00400000, /* Tx: Filtering Type 0 */
- Dpd = 0x00800000, /* Tx: Disabled PaDding */
- Ac = 0x04000000, /* Tx: Add CRC disable */
- Set = 0x08000000, /* Tx: SETup packet */
- Ft1 = 0x10000000, /* Tx: Filtering Type 1 */
- Fseg = 0x20000000, /* Tx: First SEGment */
- Lseg = 0x40000000, /* Tx: Last SEGment */
- Ic = 0x80000000, /* Tx: Interrupt on Completion */
-};
-
-enum { /* PHY registers */
- Bmcr = 0, /* Basic Mode Control */
- Bmsr = 1, /* Basic Mode Status */
- Phyidr1 = 2, /* PHY Identifier #1 */
- Phyidr2 = 3, /* PHY Identifier #2 */
- Anar = 4, /* Auto-Negotiation Advertisment */
- Anlpar = 5, /* Auto-Negotiation Link Partner Ability */
- Aner = 6, /* Auto-Negotiation Expansion */
-};
-
-enum { /* Variants */
- Tulip0 = (0x0009<<16)|0x1011,
- Tulip1 = (0x0014<<16)|0x1011,
- Tulip3 = (0x0019<<16)|0x1011,
- Pnic = (0x0002<<16)|0x11AD,
- Pnic2 = (0xC115<<16)|0x11AD,
- CentaurP = (0x0985<<16)|0x1317,
- CentaurPcb = (0x1985<<16)|0x1317,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
- int id; /* (pcidev->did<<16)|pcidev->vid */
-
- uchar* srom;
- int sromsz; /* address size in bits */
- uchar* sromea; /* MAC address */
- uchar* leaf;
- int sct; /* selected connection type */
- int k; /* info block count */
- uchar* infoblock[16];
- int sctk; /* sct block index */
- int curk; /* current block index */
- uchar* type5block;
-
- int phy[32]; /* logical to physical map */
- int phyreset; /* reset bitmap */
- int curphyad;
- int fdx;
- int ttm;
-
- uchar fd; /* option */
- int medium; /* option */
-
- int csr6; /* CSR6 - operating mode */
- int mask; /* CSR[57] - interrupt mask */
- int mbps;
-
- Lock lock;
-
- Des* rdr; /* receive descriptor ring */
- int nrdr; /* size of rdr */
- int rdrx; /* index into rdr */
-
- Lock tlock;
- Des* tdr; /* transmit descriptor ring */
- int ntdr; /* size of tdr */
- int tdrh; /* host index into tdr */
- int tdri; /* interface index into tdr */
- int ntq; /* descriptors active */
- int ntqmax;
- Block* setupbp;
-
- ulong of; /* receive statistics */
- ulong ce;
- ulong cs;
- ulong tl;
- ulong rf;
- ulong de;
-
- ulong ru;
- ulong rps;
- ulong rwt;
-
- ulong uf; /* transmit statistics */
- ulong ec;
- ulong lc;
- ulong nc;
- ulong lo;
- ulong to;
-
- ulong tps;
- ulong tu;
- ulong tjt;
- ulong unf;
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-#define csr32r(c, r) (inl((c)->port+((r)*8)))
-#define csr32w(c, r, l) (outl((c)->port+((r)*8), (ulong)(l)))
-
-static void
-promiscuous(void* arg, int on)
-{
- Ctlr *ctlr;
-
- ctlr = ((Ether*)arg)->ctlr;
- ilock(&ctlr->lock);
- if(on)
- ctlr->csr6 |= Pr;
- else
- ctlr->csr6 &= ~Pr;
- csr32w(ctlr, 6, ctlr->csr6);
- iunlock(&ctlr->lock);
-}
-
-/* multicast already on, don't need to do anything */
-static void
-multicast(void*, uchar*, int)
-{
-}
-
-static void
-attach(Ether* ether)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(&ctlr->lock);
- if(!(ctlr->csr6 & Sr)){
- ctlr->csr6 |= Sr;
- csr32w(ctlr, 6, ctlr->csr6);
- }
- iunlock(&ctlr->lock);
-}
-
-static long
-ifstat(Ether* ether, void* a, long n, ulong offset)
-{
- Ctlr *ctlr;
- char *buf, *p;
- int i, l, len;
-
- ctlr = ether->ctlr;
-
- ether->crcs = ctlr->ce;
- ether->frames = ctlr->rf+ctlr->cs;
- ether->buffs = ctlr->de+ctlr->tl;
- ether->overflows = ctlr->of;
-
- if(n == 0)
- return 0;
-
- p = malloc(READSTR);
- l = snprint(p, READSTR, "Overflow: %lud\n", ctlr->of);
- l += snprint(p+l, READSTR-l, "Ru: %lud\n", ctlr->ru);
- l += snprint(p+l, READSTR-l, "Rps: %lud\n", ctlr->rps);
- l += snprint(p+l, READSTR-l, "Rwt: %lud\n", ctlr->rwt);
- l += snprint(p+l, READSTR-l, "Tps: %lud\n", ctlr->tps);
- l += snprint(p+l, READSTR-l, "Tu: %lud\n", ctlr->tu);
- l += snprint(p+l, READSTR-l, "Tjt: %lud\n", ctlr->tjt);
- l += snprint(p+l, READSTR-l, "Unf: %lud\n", ctlr->unf);
- l += snprint(p+l, READSTR-l, "CRC Error: %lud\n", ctlr->ce);
- l += snprint(p+l, READSTR-l, "Collision Seen: %lud\n", ctlr->cs);
- l += snprint(p+l, READSTR-l, "Frame Too Long: %lud\n", ctlr->tl);
- l += snprint(p+l, READSTR-l, "Runt Frame: %lud\n", ctlr->rf);
- l += snprint(p+l, READSTR-l, "Descriptor Error: %lud\n", ctlr->de);
- l += snprint(p+l, READSTR-l, "Underflow Error: %lud\n", ctlr->uf);
- l += snprint(p+l, READSTR-l, "Excessive Collisions: %lud\n", ctlr->ec);
- l += snprint(p+l, READSTR-l, "Late Collision: %lud\n", ctlr->lc);
- l += snprint(p+l, READSTR-l, "No Carrier: %lud\n", ctlr->nc);
- l += snprint(p+l, READSTR-l, "Loss of Carrier: %lud\n", ctlr->lo);
- l += snprint(p+l, READSTR-l, "Transmit Jabber Timeout: %lud\n",
- ctlr->to);
- l += snprint(p+l, READSTR-l, "csr6: %luX %uX\n", csr32r(ctlr, 6),
- ctlr->csr6);
- snprint(p+l, READSTR-l, "ntqmax: %d\n", ctlr->ntqmax);
- ctlr->ntqmax = 0;
- buf = a;
- len = readstr(offset, buf, n, p);
- if(offset > l)
- offset -= l;
- else
- offset = 0;
- buf += len;
- n -= len;
-
- l = snprint(p, READSTR, "srom:");
- for(i = 0; i < (1<<(ctlr->sromsz)*sizeof(ushort)); i++){
- if(i && ((i & 0x0F) == 0))
- l += snprint(p+l, READSTR-l, "\n ");
- l += snprint(p+l, READSTR-l, " %2.2uX", ctlr->srom[i]);
- }
-
- snprint(p+l, READSTR-l, "\n");
- len += readstr(offset, buf, n, p);
- free(p);
-
- return len;
-}
-
-static void
-txstart(Ether* ether)
-{
- Ctlr *ctlr;
- Block *bp;
- Des *des;
- int control;
-
- ctlr = ether->ctlr;
- while(ctlr->ntq < (ctlr->ntdr-1)){
- if(ctlr->setupbp){
- bp = ctlr->setupbp;
- ctlr->setupbp = 0;
- control = Ic|Set|BLEN(bp);
- }
- else{
- bp = qget(ether->oq);
- if(bp == nil)
- break;
- control = Ic|Lseg|Fseg|BLEN(bp);
- }
-
- ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
- des = &ctlr->tdr[ctlr->tdrh];
- des->bp = bp;
- des->addr = PCIWADDR(bp->rp);
- des->control |= control;
- ctlr->ntq++;
- coherence();
- des->status = Own;
- csr32w(ctlr, 1, 0);
- ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);
- }
-
- if(ctlr->ntq > ctlr->ntqmax)
- ctlr->ntqmax = ctlr->ntq;
-}
-
-static void
-transmit(Ether* ether)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(&ctlr->tlock);
- txstart(ether);
- iunlock(&ctlr->tlock);
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
- Ctlr *ctlr;
- Ether *ether;
- int len, status;
- Des *des;
- Block *bp;
-
- ether = arg;
- ctlr = ether->ctlr;
-
- while((status = csr32r(ctlr, 5)) & (Nis|Ais)){
- /*
- * Acknowledge the interrupts and mask-out
- * the ones that are implicitly handled.
- */
- csr32w(ctlr, 5, status);
- status &= (ctlr->mask & ~(Nis|Ti));
-
- if(status & Ais){
- if(status & Tps)
- ctlr->tps++;
- if(status & Tu)
- ctlr->tu++;
- if(status & Tjt)
- ctlr->tjt++;
- if(status & Ru)
- ctlr->ru++;
- if(status & Rps)
- ctlr->rps++;
- if(status & Rwt)
- ctlr->rwt++;
- status &= ~(Ais|Rwt|Rps|Ru|Tjt|Tu|Tps);
- }
-
- /*
- * Received packets.
- */
- if(status & Ri){
- des = &ctlr->rdr[ctlr->rdrx];
- while(!(des->status & Own)){
- if(des->status & Es){
- if(des->status & Of)
- ctlr->of++;
- if(des->status & Ce)
- ctlr->ce++;
- if(des->status & Cs)
- ctlr->cs++;
- if(des->status & Tl)
- ctlr->tl++;
- if(des->status & Rf)
- ctlr->rf++;
- if(des->status & De)
- ctlr->de++;
- }
- else if(bp = iallocb(Rbsz)){
- len = ((des->status & Fl)>>16)-4;
- des->bp->wp = des->bp->rp+len;
- etheriq(ether, des->bp, 1);
- des->bp = bp;
- des->addr = PCIWADDR(bp->rp);
- }
-
- des->control &= Er;
- des->control |= Rbsz;
- coherence();
- des->status = Own;
-
- ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);
- des = &ctlr->rdr[ctlr->rdrx];
- }
- status &= ~Ri;
- }
-
- /*
- * Check the transmit side:
- * check for Transmit Underflow and Adjust
- * the threshold upwards;
- * free any transmitted buffers and try to
- * top-up the ring.
- */
- if(status & Unf){
- ctlr->unf++;
- ilock(&ctlr->lock);
- csr32w(ctlr, 6, ctlr->csr6 & ~St);
- switch(ctlr->csr6 & Tr){
- case Tr128:
- len = Tr256;
- break;
- case Tr256:
- len = Tr512;
- break;
- case Tr512:
- len = Tr1024;
- break;
- default:
- case Tr1024:
- len = Sf;
- break;
- }
- ctlr->csr6 = (ctlr->csr6 & ~Tr)|len;
- csr32w(ctlr, 6, ctlr->csr6);
- iunlock(&ctlr->lock);
- csr32w(ctlr, 5, Tps);
- status &= ~(Unf|Tps);
- }
-
- ilock(&ctlr->tlock);
- while(ctlr->ntq){
- des = &ctlr->tdr[ctlr->tdri];
- if(des->status & Own)
- break;
-
- if(des->status & Es){
- if(des->status & Uf)
- ctlr->uf++;
- if(des->status & Ec)
- ctlr->ec++;
- if(des->status & Lc)
- ctlr->lc++;
- if(des->status & Nc)
- ctlr->nc++;
- if(des->status & Lo)
- ctlr->lo++;
- if(des->status & To)
- ctlr->to++;
- ether->oerrs++;
- }
-
- freeb(des->bp);
- des->control &= Er;
-
- ctlr->ntq--;
- ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr);
- }
- txstart(ether);
- iunlock(&ctlr->tlock);
-
- /*
- * Anything left not catered for?
- */
- if(status)
- panic("#l%d: status %8.8uX\n", ether->ctlrno, status);
- }
-}
-
-static void
-ctlrinit(Ether* ether)
-{
- Ctlr *ctlr;
- Des *des;
- Block *bp;
- int i;
- uchar bi[Eaddrlen*2];
-
- ctlr = ether->ctlr;
-
- /*
- * Allocate and initialise the receive ring;
- * allocate and initialise the transmit ring;
- * unmask interrupts and start the transmit side;
- * create and post a setup packet to initialise
- * the physical ethernet address.
- */
- ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0);
- for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
- des->bp = iallocb(Rbsz);
- if(des->bp == nil)
- panic("can't allocate ethernet receive ring\n");
- des->status = Own;
- des->control = Rbsz;
- des->addr = PCIWADDR(des->bp->rp);
- }
- ctlr->rdr[ctlr->nrdr-1].control |= Er;
- ctlr->rdrx = 0;
- csr32w(ctlr, 3, PCIWADDR(ctlr->rdr));
-
- ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(Des), 8*sizeof(ulong), 0);
- ctlr->tdr[ctlr->ntdr-1].control |= Er;
- ctlr->tdrh = 0;
- ctlr->tdri = 0;
- csr32w(ctlr, 4, PCIWADDR(ctlr->tdr));
-
- /*
- * Clear any bits in the Status Register (CSR5) as
- * the PNIC has a different reset value from a true 2114x.
- */
- ctlr->mask = Nis|Ais|Fbe|Rwt|Rps|Ru|Ri|Unf|Tjt|Tps|Ti;
- csr32w(ctlr, 5, ctlr->mask);
- csr32w(ctlr, 7, ctlr->mask);
- ctlr->csr6 |= St|Pm;
- csr32w(ctlr, 6, ctlr->csr6);
-
- for(i = 0; i < Eaddrlen/2; i++){
- bi[i*4] = ether->ea[i*2];
- bi[i*4+1] = ether->ea[i*2+1];
- bi[i*4+2] = ether->ea[i*2+1];
- bi[i*4+3] = ether->ea[i*2];
- }
- bp = iallocb(Eaddrlen*2*16);
- if(bp == nil)
- panic("can't allocate ethernet setup buffer\n");
- memset(bp->rp, 0xFF, sizeof(bi));
- for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi))
- memmove(bp->rp+i, bi, sizeof(bi));
- bp->wp += sizeof(bi)*16;
-
- ctlr->setupbp = bp;
- ether->oq = qopen(256*1024, Qmsg, 0, 0);
- transmit(ether);
-}
-
-static void
-csr9w(Ctlr* ctlr, int data)
-{
- csr32w(ctlr, 9, data);
- microdelay(1);
-}
-
-static int
-miimdi(Ctlr* ctlr, int n)
-{
- int data, i;
-
- /*
- * Read n bits from the MII Management Register.
- */
- data = 0;
- for(i = n-1; i >= 0; i--){
- if(csr32r(ctlr, 9) & Mdi)
- data |= (1<<i);
- csr9w(ctlr, Mii|Mdc);
- csr9w(ctlr, Mii);
- }
- csr9w(ctlr, 0);
-
- return data;
-}
-
-static void
-miimdo(Ctlr* ctlr, int bits, int n)
-{
- int i, mdo;
-
- /*
- * Write n bits to the MII Management Register.
- */
- for(i = n-1; i >= 0; i--){
- if(bits & (1<<i))
- mdo = Mdo;
- else
- mdo = 0;
- csr9w(ctlr, mdo);
- csr9w(ctlr, mdo|Mdc);
- csr9w(ctlr, mdo);
- }
-}
-
-static int
-miir(Ctlr* ctlr, int phyad, int regad)
-{
- int data, i;
-
- if(ctlr->id == Pnic){
- i = 1000;
- csr32w(ctlr, 20, 0x60020000|(phyad<<23)|(regad<<18));
- do{
- microdelay(1);
- data = csr32r(ctlr, 20);
- }while((data & 0x80000000) && --i);
-
- if(i == 0)
- return -1;
- return data & 0xFFFF;
- }
-
- /*
- * Preamble;
- * ST+OP+PHYAD+REGAD;
- * TA + 16 data bits.
- */
- miimdo(ctlr, 0xFFFFFFFF, 32);
- miimdo(ctlr, 0x1800|(phyad<<5)|regad, 14);
- data = miimdi(ctlr, 18);
-
- if(data & 0x10000)
- return -1;
-
- return data & 0xFFFF;
-}
-
-static void
-miiw(Ctlr* ctlr, int phyad, int regad, int data)
-{
- /*
- * Preamble;
- * ST+OP+PHYAD+REGAD+TA + 16 data bits;
- * Z.
- */
- miimdo(ctlr, 0xFFFFFFFF, 32);
- data &= 0xFFFF;
- data |= (0x05<<(5+5+2+16))|(phyad<<(5+2+16))|(regad<<(2+16))|(0x02<<16);
- miimdo(ctlr, data, 32);
- csr9w(ctlr, Mdc);
- csr9w(ctlr, 0);
-}
-
-static int
-sromr(Ctlr* ctlr, int r)
-{
- int i, op, data, size;
-
- if(ctlr->id == Pnic){
- i = 1000;
- csr32w(ctlr, 19, 0x600|r);
- do{
- microdelay(1);
- data = csr32r(ctlr, 19);
- }while((data & 0x80000000) && --i);
-
- if(ctlr->sromsz == 0)
- ctlr->sromsz = 6;
-
- return csr32r(ctlr, 9) & 0xFFFF;
- }
-
- /*
- * This sequence for reading a 16-bit register 'r'
- * in the EEPROM is taken (pretty much) straight from Section
- * 7.4 of the 21140 Hardware Reference Manual.
- */
-reread:
- csr9w(ctlr, Rd|Ss);
- csr9w(ctlr, Rd|Ss|Scs);
- csr9w(ctlr, Rd|Ss|Sclk|Scs);
- csr9w(ctlr, Rd|Ss);
-
- op = 0x06;
- for(i = 3-1; i >= 0; i--){
- data = Rd|Ss|(((op>>i) & 0x01)<<2)|Scs;
- csr9w(ctlr, data);
- csr9w(ctlr, data|Sclk);
- csr9w(ctlr, data);
- }
-
- /*
- * First time through must work out the EEPROM size.
- * This doesn't seem to work on the 21041 as implemented
- * in Virtual PC for the Mac, so wire any 21041 to 6,
- * it's the only 21041 this code will ever likely see.
- */
- if((size = ctlr->sromsz) == 0){
- if(ctlr->id == Tulip1)
- ctlr->sromsz = size = 6;
- else
- size = 8;
- }
-
- for(size = size-1; size >= 0; size--){
- data = Rd|Ss|(((r>>size) & 0x01)<<2)|Scs;
- csr9w(ctlr, data);
- csr9w(ctlr, data|Sclk);
- csr9w(ctlr, data);
- microdelay(1);
- if(ctlr->sromsz == 0 && !(csr32r(ctlr, 9) & Sdo))
- break;
- }
-
- data = 0;
- for(i = 16-1; i >= 0; i--){
- csr9w(ctlr, Rd|Ss|Sclk|Scs);
- if(csr32r(ctlr, 9) & Sdo)
- data |= (1<<i);
- csr9w(ctlr, Rd|Ss|Scs);
- }
-
- csr9w(ctlr, 0);
-
- if(ctlr->sromsz == 0){
- ctlr->sromsz = 8-size;
- goto reread;
- }
-
- return data & 0xFFFF;
-}
-
-static void
-shutdown(Ether* ether)
-{
- Ctlr *ctlr = ether->ctlr;
-
-print("ether2114x shutting down\n");
- csr32w(ctlr, 0, Swr);
-}
-
-static void
-softreset(Ctlr* ctlr)
-{
- /*
- * Soft-reset the controller and initialise bus mode.
- * Delay should be >= 50 PCI cycles (2×S @ 25MHz).
- */
- csr32w(ctlr, 0, Swr);
- microdelay(10);
- csr32w(ctlr, 0, Rml|Cal16);
- delay(1);
-}
-
-static int
-type5block(Ctlr* ctlr, uchar* block)
-{
- int csr15, i, len;
-
- /*
- * Reset or GPR sequence. Reset should be once only,
- * before the GPR sequence.
- * Note 'block' is not a pointer to the block head but
- * a pointer to the data in the block starting at the
- * reset length value so type5block can be used for the
- * sequences contained in type 1 and type 3 blocks.
- * The SROM docs state the 21140 type 5 block is the
- * same as that for the 21143, but the two controllers
- * use different registers and sequence-element lengths
- * so the 21140 code here is a guess for a real type 5
- * sequence.
- */
- len = *block++;
- if(ctlr->id != Tulip3){
- for(i = 0; i < len; i++){
- csr32w(ctlr, 12, *block);
- block++;
- }
- return len;
- }
-
- for(i = 0; i < len; i++){
- csr15 = *block++<<16;
- csr15 |= *block++<<24;
- csr32w(ctlr, 15, csr15);
- debug("%8.8uX ", csr15);
- }
- return 2*len;
-}
-
-static int
-typephylink(Ctlr* ctlr, uchar*)
-{
- int an, bmcr, bmsr, csr6, x;
-
- /*
- * Fail if
- * auto-negotiataion enabled but not complete;
- * no valid link established.
- */
- bmcr = miir(ctlr, ctlr->curphyad, Bmcr);
- miir(ctlr, ctlr->curphyad, Bmsr);
- bmsr = miir(ctlr, ctlr->curphyad, Bmsr);
- debug("bmcr 0x%2.2uX bmsr 0x%2.2uX\n", bmcr, bmsr);
- if(((bmcr & 0x1000) && !(bmsr & 0x0020)) || !(bmsr & 0x0004))
- return 0;
-
- if(bmcr & 0x1000){
- an = miir(ctlr, ctlr->curphyad, Anar);
- an &= miir(ctlr, ctlr->curphyad, Anlpar) & 0x3E0;
- debug("an 0x%2.uX 0x%2.2uX 0x%2.2uX\n",
- miir(ctlr, ctlr->curphyad, Anar),
- miir(ctlr, ctlr->curphyad, Anlpar),
- an);
-
- if(an & 0x0100)
- x = 0x4000;
- else if(an & 0x0080)
- x = 0x2000;
- else if(an & 0x0040)
- x = 0x1000;
- else if(an & 0x0020)
- x = 0x0800;
- else
- x = 0;
- }
- else if((bmcr & 0x2100) == 0x2100)
- x = 0x4000;
- else if(bmcr & 0x2000){
- /*
- * If FD capable, force it if necessary.
- */
- if((bmsr & 0x4000) && ctlr->fd){
- miiw(ctlr, ctlr->curphyad, Bmcr, 0x2100);
- x = 0x4000;
- }
- else
- x = 0x2000;
- }
- else if(bmcr & 0x0100)
- x = 0x1000;
- else
- x = 0x0800;
-
- csr6 = Sc|Mbo|Hbd|Ps|Ca|TrMODE|Sb;
- if(ctlr->fdx & x)
- csr6 |= Fd;
- if(ctlr->ttm & x)
- csr6 |= Ttm;
- debug("csr6 0x%8.8uX 0x%8.8uX 0x%8.8luX\n",
- csr6, ctlr->csr6, csr32r(ctlr, 6));
- if(csr6 != ctlr->csr6){
- ctlr->csr6 = csr6;
- csr32w(ctlr, 6, csr6);
- }
-
- return 1;
-}
-
-static int
-typephymode(Ctlr* ctlr, uchar* block, int wait)
-{
- uchar *p;
- int len, mc, nway, phyx, timeo;
-
- if(DEBUG){
- int i;
-
- len = (block[0] & ~0x80)+1;
- for(i = 0; i < len; i++)
- debug("%2.2uX ", block[i]);
- debug("\n");
- }
-
- if(block[1] == 1)
- len = 1;
- else if(block[1] == 3)
- len = 2;
- else
- return -1;
-
- /*
- * Snarf the media capabilities, nway advertisment,
- * FDX and TTM bitmaps.
- */
- p = &block[5+len*block[3]+len*block[4+len*block[3]]];
- mc = *p++;
- mc |= *p++<<8;
- nway = *p++;
- nway |= *p++<<8;
- ctlr->fdx = *p++;
- ctlr->fdx |= *p++<<8;
- ctlr->ttm = *p++;
- ctlr->ttm |= *p<<8;
- debug("mc %4.4uX nway %4.4uX fdx %4.4uX ttm %4.4uX\n",
- mc, nway, ctlr->fdx, ctlr->ttm);
- USED(mc);
-
- phyx = block[2];
- ctlr->curphyad = ctlr->phy[phyx];
-
- ctlr->csr6 = 0;//Sc|Mbo|Hbd|Ps|Ca|TrMODE|Sb;
- //csr32w(ctlr, 6, ctlr->csr6);
- if(typephylink(ctlr, block))
- return 0;
-
- if(!(ctlr->phyreset & (1<<phyx))){
- debug("reset seq: len %d: ", block[3]);
- if(ctlr->type5block)
- type5block(ctlr, &ctlr->type5block[2]);
- else
- type5block(ctlr, &block[4+len*block[3]]);
- debug("\n");
- ctlr->phyreset |= (1<<phyx);
- }
-
- /*
- * GPR sequence.
- */
- debug("gpr seq: len %d: ", block[3]);
- type5block(ctlr, &block[3]);
- debug("\n");
-
- ctlr->csr6 = 0;//Sc|Mbo|Hbd|Ps|Ca|TrMODE|Sb;
- //csr32w(ctlr, 6, ctlr->csr6);
- if(typephylink(ctlr, block))
- return 0;
-
- /*
- * Turn off auto-negotiation, set the auto-negotiation
- * advertisment register then start the auto-negotiation
- * process again.
- */
- miiw(ctlr, ctlr->curphyad, Bmcr, 0);
- miiw(ctlr, ctlr->curphyad, Anar, nway|1);
- miiw(ctlr, ctlr->curphyad, Bmcr, 0x1000);
-
- if(!wait)
- return 0;
-
- for(timeo = 0; timeo < 45; timeo++){
- if(typephylink(ctlr, block))
- return 0;
- delay(100);
- }
-
- return -1;
-}
-
-static int
-typesymmode(Ctlr *ctlr, uchar *block, int wait)
-{
- uint gpmode, gpdata, command;
-
- USED(wait);
- gpmode = block[3] | ((uint) block[4] << 8);
- gpdata = block[5] | ((uint) block[6] << 8);
- command = (block[7] | ((uint) block[8] << 8)) & 0x71;
- if (command & 0x8000) {
- print("ether2114x.c: FIXME: handle type 4 mode blocks where cmd.active_invalid != 0\n");
- return -1;
- }
- csr32w(ctlr, 15, gpmode);
- csr32w(ctlr, 15, gpdata);
- ctlr->csr6 = (command & 0x71) << 18;
- csr32w(ctlr, 6, ctlr->csr6);
- return 0;
-}
-
-static int
-type2mode(Ctlr* ctlr, uchar* block, int)
-{
- uchar *p;
- int csr6, csr13, csr14, csr15, gpc, gpd;
-
- csr6 = Sc|Mbo|Ca|TrMODE|Sb;
- debug("type2mode: medium 0x%2.2uX\n", block[2]);
-
- /*
- * Don't attempt full-duplex
- * unless explicitly requested.
- */
- if((block[2] & 0x3F) == 0x04){ /* 10BASE-TFD */
- if(!ctlr->fd)
- return -1;
- csr6 |= Fd;
- }
-
- /*
- * Operating mode programming values from the datasheet
- * unless media specific data is explicitly given.
- */
- p = &block[3];
- if(block[2] & 0x40){
- csr13 = (block[4]<<8)|block[3];
- csr14 = (block[6]<<8)|block[5];
- csr15 = (block[8]<<8)|block[7];
- p += 6;
- }
- else switch(block[2] & 0x3F){
- default:
- return -1;
- case 0x00: /* 10BASE-T */
- csr13 = 0x00000001;
- csr14 = 0x00007F3F;
- csr15 = 0x00000008;
- break;
- case 0x01: /* 10BASE-2 */
- csr13 = 0x00000009;
- csr14 = 0x00000705;
- csr15 = 0x00000006;
- break;
- case 0x02: /* 10BASE-5 (AUI) */
- csr13 = 0x00000009;
- csr14 = 0x00000705;
- csr15 = 0x0000000E;
- break;
- case 0x04: /* 10BASE-TFD */
- csr13 = 0x00000001;
- csr14 = 0x00007F3D;
- csr15 = 0x00000008;
- break;
- }
- gpc = *p++<<16;
- gpc |= *p++<<24;
- gpd = *p++<<16;
- gpd |= *p<<24;
-
- csr32w(ctlr, 13, 0);
- csr32w(ctlr, 14, csr14);
- csr32w(ctlr, 15, gpc|csr15);
- delay(10);
- csr32w(ctlr, 15, gpd|csr15);
- csr32w(ctlr, 13, csr13);
-
- ctlr->csr6 = csr6;
- csr32w(ctlr, 6, ctlr->csr6);
-
- debug("type2mode: csr13 %8.8uX csr14 %8.8uX csr15 %8.8uX\n",
- csr13, csr14, csr15);
- debug("type2mode: gpc %8.8uX gpd %8.8uX csr6 %8.8uX\n",
- gpc, gpd, csr6);
-
- return 0;
-}
-
-static int
-type0link(Ctlr* ctlr, uchar* block)
-{
- int m, polarity, sense;
-
- m = (block[3]<<8)|block[2];
- sense = 1<<((m & 0x000E)>>1);
- if(m & 0x0080)
- polarity = sense;
- else
- polarity = 0;
-
- return (csr32r(ctlr, 12) & sense)^polarity;
-}
-
-static int
-type0mode(Ctlr* ctlr, uchar* block, int wait)
-{
- int csr6, m, timeo;
-
- csr6 = Sc|Mbo|Hbd|Ca|TrMODE|Sb;
-debug("type0: medium 0x%uX, fd %d: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n",
- ctlr->medium, ctlr->fd, block[0], block[1], block[2], block[3]);
- switch(block[0]){
- default:
- break;
-
- case 0x04: /* 10BASE-TFD */
- case 0x05: /* 100BASE-TXFD */
- case 0x08: /* 100BASE-FXFD */
- /*
- * Don't attempt full-duplex
- * unless explicitly requested.
- */
- if(!ctlr->fd)
- return -1;
- csr6 |= Fd;
- break;
- }
-
- m = (block[3]<<8)|block[2];
- if(m & 0x0001)
- csr6 |= Ps;
- if(m & 0x0010)
- csr6 |= Ttm;
- if(m & 0x0020)
- csr6 |= Pcs;
- if(m & 0x0040)
- csr6 |= Scr;
-
- csr32w(ctlr, 12, block[1]);
- microdelay(10);
- csr32w(ctlr, 6, csr6);
- ctlr->csr6 = csr6;
-
- if(!wait)
- return 0;
-
- for(timeo = 0; timeo < 30; timeo++){
- if(type0link(ctlr, block))
- return 0;
- delay(100);
- }
-
- return -1;
-}
-
-static int
-media21041(Ether* ether, int wait)
-{
- Ctlr* ctlr;
- uchar *block;
- int csr6, csr13, csr14, csr15, medium, timeo;
-
- ctlr = ether->ctlr;
- block = ctlr->infoblock[ctlr->curk];
- debug("media21041: block[0] %2.2uX, medium %4.4uX sct %4.4uX\n",
- block[0], ctlr->medium, ctlr->sct);
-
- medium = block[0] & 0x3F;
- if(ctlr->medium >= 0 && medium != ctlr->medium)
- return 0;
- if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != medium)
- return 0;
-
- csr6 = Sc|Mbo|Ca|TrMODE|Sb;
- if(block[0] & 0x40){
- csr13 = (block[2]<<8)|block[1];
- csr14 = (block[4]<<8)|block[3];
- csr15 = (block[6]<<8)|block[5];
- }
- else switch(medium){
- default:
- return -1;
- case 0x00: /* 10BASE-T */
- csr13 = 0xEF01;
- csr14 = 0xFF3F;
- csr15 = 0x0008;
- break;
- case 0x01: /* 10BASE-2 */
- csr13 = 0xEF09;
- csr14 = 0xF73D;
- csr15 = 0x0006;
- break;
- case 0x02: /* 10BASE-5 */
- csr13 = 0xEF09;
- csr14 = 0xF73D;
- csr15 = 0x000E;
- break;
- case 0x04: /* 10BASE-TFD */
- csr13 = 0xEF01;
- csr14 = 0xFF3D;
- csr15 = 0x0008;
- break;
- }
-
- csr32w(ctlr, 13, 0);
- csr32w(ctlr, 14, csr14);
- csr32w(ctlr, 15, csr15);
- csr32w(ctlr, 13, csr13);
- delay(10);
-
- if(medium == 0x04)
- csr6 |= Fd;
- ctlr->csr6 = csr6;
- csr32w(ctlr, 6, ctlr->csr6);
-
- debug("media21041: csr6 %8.8uX csr13 %4.4uX csr14 %4.4uX csr15 %4.4uX\n",
- csr6, csr13, csr14, csr15);
-
- if(!wait)
- return 0;
-
- for(timeo = 0; timeo < 30; timeo++){
- if(!(csr32r(ctlr, 12) & 0x0002)){
- debug("media21041: ok: csr12 %4.4luX timeo %d\n",
- csr32r(ctlr, 12), timeo);
- return 10;
- }
- delay(100);
- }
- debug("media21041: !ok: csr12 %4.4luX\n", csr32r(ctlr, 12));
-
- return -1;
-}
-
-static int
-mediaxx(Ether* ether, int wait)
-{
- Ctlr* ctlr;
- uchar *block;
-
- ctlr = ether->ctlr;
- block = ctlr->infoblock[ctlr->curk];
- if(block[0] & 0x80){
- switch(block[1]){
- default:
- return -1;
- case 0:
- if(ctlr->medium >= 0 && block[2] != ctlr->medium)
- return 0;
-/* need this test? */ if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != block[2])
- return 0;
- if(type0mode(ctlr, block+2, wait))
- return 0;
- break;
- case 1:
- if(typephymode(ctlr, block, wait))
- return 0;
- break;
- case 2:
- debug("type2: medium %d block[2] %d\n",
- ctlr->medium, block[2]);
- if(ctlr->medium >= 0 && ((block[2] & 0x3F) != ctlr->medium))
- return 0;
- if(type2mode(ctlr, block, wait))
- return 0;
- break;
- case 3:
- if(typephymode(ctlr, block, wait))
- return 0;
- break;
- case 4:
- debug("type4: medium %d block[2] %d\n",
- ctlr->medium, block[2]);
- if(ctlr->medium >= 0 && ((block[2] & 0x3F) != ctlr->medium))
- return 0;
- if(typesymmode(ctlr, block, wait))
- return 0;
- break;
- }
- }
- else{
- if(ctlr->medium >= 0 && block[0] != ctlr->medium)
- return 0;
-/* need this test? */if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != block[0])
- return 0;
- if(type0mode(ctlr, block, wait))
- return 0;
- }
-
- if(ctlr->csr6){
- if(!(ctlr->csr6 & Ps) || (ctlr->csr6 & Ttm))
- return 10;
- return 100;
- }
-
- return 0;
-}
-
-static int
-media(Ether* ether, int wait)
-{
- Ctlr* ctlr;
- int k, mbps;
-
- ctlr = ether->ctlr;
- for(k = 0; k < ctlr->k; k++){
- switch(ctlr->id){
- default:
- mbps = mediaxx(ether, wait);
- break;
- case Tulip1: /* 21041 */
- mbps = media21041(ether, wait);
- break;
- }
- if(mbps > 0)
- return mbps;
- if(ctlr->curk == 0)
- ctlr->curk = ctlr->k-1;
- else
- ctlr->curk--;
- }
-
- return 0;
-}
-
-static char* mediatable[9] = {
- "10BASE-T", /* TP */
- "10BASE-2", /* BNC */
- "10BASE-5", /* AUI */
- "100BASE-TX",
- "10BASE-TFD",
- "100BASE-TXFD",
- "100BASE-T4",
- "100BASE-FX",
- "100BASE-FXFD",
-};
-
-static uchar en1207[] = { /* Accton EN1207-COMBO */
- 0x00, 0x00, 0xE8, /* [0] vendor ethernet code */
- 0x00, /* [3] spare */
-
- 0x00, 0x08, /* [4] connection (LSB+MSB = 0x0800) */
- 0x1F, /* [6] general purpose control */
- 2, /* [7] block count */
-
- 0x00, /* [8] media code (10BASE-TX) */
- 0x0B, /* [9] general purpose port data */
- 0x9E, 0x00, /* [10] command (LSB+MSB = 0x009E) */
-
- 0x03, /* [8] media code (100BASE-TX) */
- 0x1B, /* [9] general purpose port data */
- 0x6D, 0x00, /* [10] command (LSB+MSB = 0x006D) */
-
- /* There is 10BASE-2 as well, but... */
-};
-
-static uchar ana6910fx[] = { /* Adaptec (Cogent) ANA-6910FX */
- 0x00, 0x00, 0x92, /* [0] vendor ethernet code */
- 0x00, /* [3] spare */
-
- 0x00, 0x08, /* [4] connection (LSB+MSB = 0x0800) */
- 0x3F, /* [6] general purpose control */
- 1, /* [7] block count */
-
- 0x07, /* [8] media code (100BASE-FX) */
- 0x03, /* [9] general purpose port data */
- 0x2D, 0x00 /* [10] command (LSB+MSB = 0x000D) */
-};
-
-static uchar smc9332[] = { /* SMC 9332 */
- 0x00, 0x00, 0xC0, /* [0] vendor ethernet code */
- 0x00, /* [3] spare */
-
- 0x00, 0x08, /* [4] connection (LSB+MSB = 0x0800) */
- 0x1F, /* [6] general purpose control */
- 2, /* [7] block count */
-
- 0x00, /* [8] media code (10BASE-TX) */
- 0x00, /* [9] general purpose port data */
- 0x9E, 0x00, /* [10] command (LSB+MSB = 0x009E) */
-
- 0x03, /* [8] media code (100BASE-TX) */
- 0x09, /* [9] general purpose port data */
- 0x6D, 0x00, /* [10] command (LSB+MSB = 0x006D) */
-};
-
-static uchar* leaf21140[] = {
- en1207, /* Accton EN1207-COMBO */
- ana6910fx, /* Adaptec (Cogent) ANA-6910FX */
- smc9332, /* SMC 9332 */
- nil,
-};
-
-/*
- * Copied to ctlr->srom at offset 20.
- */
-static uchar leafpnic[] = {
- 0x00, 0x00, 0x00, 0x00, /* MAC address */
- 0x00, 0x00,
- 0x00, /* controller 0 device number */
- 0x1E, 0x00, /* controller 0 info leaf offset */
- 0x00, /* reserved */
- 0x00, 0x08, /* selected connection type */
- 0x00, /* general purpose control */
- 0x01, /* block count */
-
- 0x8C, /* format indicator and count */
- 0x01, /* block type */
- 0x00, /* PHY number */
- 0x00, /* GPR sequence length */
- 0x00, /* reset sequence length */
- 0x00, 0x78, /* media capabilities */
- 0xE0, 0x01, /* Nway advertisment */
- 0x00, 0x50, /* FDX bitmap */
- 0x00, 0x18, /* TTM bitmap */
-};
-
-static int
-srom(Ctlr* ctlr)
-{
- int i, k, oui, phy, x;
- uchar *p;
-
- /*
- * This is a partial decoding of the SROM format described in
- * 'Digital Semiconductor 21X4 Serial ROM Format, Version 4.05,
- * 2-Mar-98'. Only the 2114[03] are handled, support for other
- * controllers can be added as needed.
- * Do a dummy read first to get the size and allocate ctlr->srom.
- */
- sromr(ctlr, 0);
- if(ctlr->srom == nil)
- ctlr->srom = malloc((1<<ctlr->sromsz)*sizeof(ushort));
- for(i = 0; i < (1<<ctlr->sromsz); i++){
- x = sromr(ctlr, i);
- ctlr->srom[2*i] = x;
- ctlr->srom[2*i+1] = x>>8;
- }
-
- if(DEBUG){
- print("srom:");
- for(i = 0; i < ((1<<ctlr->sromsz)*sizeof(ushort)); i++){
- if(i && ((i & 0x0F) == 0))
- print("\n ");
- print(" %2.2uX", ctlr->srom[i]);
- }
- print("\n");
- }
-
- /*
- * There are at least 2 SROM layouts:
- * e.g. Digital EtherWORKS station address at offset 20;
- * this complies with the 21140A SROM
- * application note from Digital;
- * e.g. SMC9332 station address at offset 0 followed by
- * 2 additional bytes, repeated at offset
- * 6; the 8 bytes are also repeated in
- * reverse order at offset 8.
- * To check which it is, read the SROM and check for the repeating
- * patterns of the non-compliant cards; if that fails use the one at
- * offset 20.
- */
- ctlr->sromea = ctlr->srom;
- for(i = 0; i < 8; i++){
- x = ctlr->srom[i];
- if(x != ctlr->srom[15-i] || x != ctlr->srom[16+i]){
- ctlr->sromea = &ctlr->srom[20];
- break;
- }
- }
-
- /*
- * Fake up the SROM for the PNIC and AMDtek.
- * They look like a 21140 with a PHY.
- * The MAC address is byte-swapped in the orginal
- * PNIC SROM data.
- */
- if(ctlr->id == Pnic){
- memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
- for(i = 0; i < Eaddrlen; i += 2){
- ctlr->srom[20+i] = ctlr->srom[i+1];
- ctlr->srom[20+i+1] = ctlr->srom[i];
- }
- }
- if(ctlr->id == CentaurP || ctlr->id == CentaurPcb){
- memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
- for(i = 0; i < Eaddrlen; i += 2){
- ctlr->srom[20+i] = ctlr->srom[8+i];
- ctlr->srom[20+i+1] = ctlr->srom[8+i+1];
- }
- }
-
- /*
- * Next, try to find the info leaf in the SROM for media detection.
- * If it's a non-conforming card try to match the vendor ethernet code
- * and point p at a fake info leaf with compact 21140 entries.
- */
- if(ctlr->sromea == ctlr->srom){
- p = nil;
- for(i = 0; leaf21140[i] != nil; i++){
- if(memcmp(leaf21140[i], ctlr->sromea, 3) == 0){
- p = &leaf21140[i][4];
- break;
- }
- }
- if(p == nil)
- return -1;
- }
- else
- p = &ctlr->srom[(ctlr->srom[28]<<8)|ctlr->srom[27]];
-
- /*
- * Set up the info needed for later media detection.
- * For the 21140, set the general-purpose mask in CSR12.
- * The info block entries are stored in order of increasing
- * precedence, so detection will work backwards through the
- * stored indexes into ctlr->srom.
- * If an entry is found which matches the selected connection
- * type, save the index. Otherwise, start at the last entry.
- * If any MII entries are found (type 1 and 3 blocks), scan
- * for PHYs.
- */
- ctlr->leaf = p;
- ctlr->sct = *p++;
- ctlr->sct |= *p++<<8;
- if(ctlr->id != Tulip3 && ctlr->id != Tulip1){
- csr32w(ctlr, 12, Gpc|*p++);
- delay(200);
- }
- ctlr->k = *p++;
- if(ctlr->k >= nelem(ctlr->infoblock))
- ctlr->k = nelem(ctlr->infoblock)-1;
- ctlr->sctk = ctlr->k-1;
- phy = 0;
- for(k = 0; k < ctlr->k; k++){
- ctlr->infoblock[k] = p;
- if(ctlr->id == Tulip1){
- debug("type21041: 0x%2.2uX\n", p[0]);
- if(ctlr->sct != 0x0800 && *p == (ctlr->sct & 0xFF))
- ctlr->sctk = k;
- if(*p & 0x40)
- p += 7;
- else
- p += 1;
- }
- /*
- * The RAMIX PMC665 has a badly-coded SROM,
- * hence the test for 21143 and type 3.
- */
- else if((*p & 0x80) || (ctlr->id == Tulip3 && *(p+1) == 3)){
- *p |= 0x80;
- if(*(p+1) == 1 || *(p+1) == 3)
- phy = 1;
- if(*(p+1) == 5)
- ctlr->type5block = p;
- p += (*p & ~0x80)+1;
- }
- else{
- debug("type0: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n",
- p[0], p[1], p[2], p[3]);
- if(ctlr->sct != 0x0800 && *p == (ctlr->sct & 0xFF))
- ctlr->sctk = k;
- p += 4;
- }
- }
- ctlr->curk = ctlr->sctk;
- debug("sct 0x%uX medium 0x%uX k %d curk %d phy %d\n",
- ctlr->sct, ctlr->medium, ctlr->k, ctlr->curk, phy);
-
- if(phy){
- x = 0;
- for(k = 0; k < nelem(ctlr->phy); k++){
- if((ctlr->id == CentaurP || ctlr->id == CentaurPcb) && k != 1)
- continue;
- if((oui = miir(ctlr, k, 2)) == -1 || oui == 0)
- continue;
- debug("phy reg 2 %4.4uX\n", oui);
- if(DEBUG){
- oui = (oui & 0x3FF)<<6;
- oui |= miir(ctlr, k, 3)>>10;
- miir(ctlr, k, 1);
- debug("phy%d: index %d oui %uX reg1 %uX\n",
- x, k, oui, miir(ctlr, k, 1));
- USED(oui);
- }
- ctlr->phy[x] = k;
- }
- }
-
- ctlr->fd = 0;
- ctlr->medium = -1;
-
- return 0;
-}
-
-static void
-dec2114xpci(void)
-{
- Ctlr *ctlr;
- Pcidev *p;
- int x;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != 0x02 || p->ccru != 0)
- continue;
- switch((p->did<<16)|p->vid){
- default:
- continue;
-
- case Tulip3: /* 21143 */
- /*
- * Exit sleep mode.
- */
- x = pcicfgr32(p, 0x40);
- x &= ~0xC0000000;
- pcicfgw32(p, 0x40, x);
- /*FALLTHROUGH*/
-
- case Tulip0: /* 21140 */
- case Tulip1: /* 21041 */
- case Pnic: /* PNIC */
- case Pnic2: /* PNIC-II */
- case CentaurP: /* ADMtek */
- case CentaurPcb: /* ADMtek CardBus */
- break;
- }
-
- /*
- * bar[0] is the I/O port register address and
- * bar[1] is the memory-mapped register address.
- */
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = p->mem[0].bar & ~0x01;
- ctlr->pcidev = p;
- ctlr->id = (p->did<<16)|p->vid;
-
- if(ioalloc(ctlr->port, p->mem[0].size, 0, "dec2114x") < 0){
- print("dec2114x: port 0x%uX in use\n", ctlr->port);
- free(ctlr);
- continue;
- }
-
- /*
- * Some cards (e.g. ANA-6910FX) seem to need the Ps bit
- * set or they don't always work right after a hardware
- * reset.
- */
- csr32w(ctlr, 6, Mbo|Ps);
- softreset(ctlr);
-
- if(srom(ctlr)){
- iofree(ctlr->port);
- free(ctlr);
- continue;
- }
-
- switch(ctlr->id){
- default:
- break;
- case Pnic: /* PNIC */
- /*
- * Turn off the jabber timer.
- */
- csr32w(ctlr, 15, 0x00000001);
- break;
- case CentaurP:
- case CentaurPcb:
- /*
- * Nice - the register offsets change from *8 to *4
- * for CSR16 and up...
- * CSR25/26 give the MAC address read from the SROM.
- * Don't really need to use this other than as a check,
- * the SROM will be read in anyway so the value there
- * can be used directly.
- */
- debug("csr25 %8.8luX csr26 %8.8luX\n",
- inl(ctlr->port+0xA4), inl(ctlr->port+0xA8));
- debug("phyidr1 %4.4luX phyidr2 %4.4luX\n",
- inl(ctlr->port+0xBC), inl(ctlr->port+0xC0));
- break;
- }
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- }
-}
-
-static int
-reset(Ether* ether)
-{
- Ctlr *ctlr;
- int i, x;
- uchar ea[Eaddrlen];
- static int scandone;
-
- if(scandone == 0){
- dec2114xpci();
- scandone = 1;
- }
-
- /*
- * Any adapter matches if no ether->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(ether->port == 0 || ether->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- ether->ctlr = ctlr;
- ether->port = ctlr->port;
- ether->irq = ctlr->pcidev->intl;
- ether->tbdf = ctlr->pcidev->tbdf;
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the EEPROM and set in ether->ea prior to
- * loading the station address in the hardware.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, ether->ea, Eaddrlen) == 0)
- memmove(ether->ea, ctlr->sromea, Eaddrlen);
-
- /*
- * Look for a medium override in case there's no autonegotiation
- * (no MII) or the autonegotiation fails.
- */
- for(i = 0; i < ether->nopt; i++){
- if(cistrcmp(ether->opt[i], "FD") == 0){
- ctlr->fd = 1;
- continue;
- }
- for(x = 0; x < nelem(mediatable); x++){
- debug("compare <%s> <%s>\n", mediatable[x],
- ether->opt[i]);
- if(cistrcmp(mediatable[x], ether->opt[i]))
- continue;
- ctlr->medium = x;
-
- switch(ctlr->medium){
- default:
- ctlr->fd = 0;
- break;
-
- case 0x04: /* 10BASE-TFD */
- case 0x05: /* 100BASE-TXFD */
- case 0x08: /* 100BASE-FXFD */
- ctlr->fd = 1;
- break;
- }
- break;
- }
- }
-
- ether->mbps = media(ether, 1);
-
- /*
- * Initialise descriptor rings, ethernet address.
- */
- ctlr->nrdr = Nrde;
- ctlr->ntdr = Ntde;
- pcisetbme(ctlr->pcidev);
- ctlrinit(ether);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = ifstat;
-
- ether->arg = ether;
- ether->shutdown = shutdown;
- ether->multicast = multicast;
- ether->promiscuous = promiscuous;
-
- return 0;
-}
-
-void
-ether2114xlink(void)
-{
- addethercard("2114x", reset);
- addethercard("21140", reset);
-}
diff --git a/os/pc/ether589.c b/os/pc/ether589.c
deleted file mode 100644
index ef19093f..00000000
--- a/os/pc/ether589.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 3C589 and 3C562.
- * To do:
- * check xcvr10Base2 still works (is GlobalReset necessary?).
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-enum { /* all windows */
- CommandR = 0x000E,
- IntStatusR = 0x000E,
-};
-
-enum { /* Commands */
- GlobalReset = 0x0000,
- SelectRegisterWindow = 0x0001,
- RxReset = 0x0005,
- TxReset = 0x000B,
- AcknowledgeInterrupt = 0x000D,
-};
-
-enum { /* IntStatus bits */
- commandInProgress = 0x1000,
-};
-
-#define COMMAND(port, cmd, a) outs((port)+CommandR, ((cmd)<<11)|(a))
-#define STATUS(port) ins((port)+IntStatusR)
-
-enum { /* Window 0 - setup */
- Wsetup = 0x0000,
- /* registers */
- ManufacturerID = 0x0000, /* 3C5[08]*, 3C59[27] */
- ProductID = 0x0002, /* 3C5[08]*, 3C59[27] */
- ConfigControl = 0x0004, /* 3C5[08]*, 3C59[27] */
- AddressConfig = 0x0006, /* 3C5[08]*, 3C59[27] */
- ResourceConfig = 0x0008, /* 3C5[08]*, 3C59[27] */
- EepromCommand = 0x000A,
- EepromData = 0x000C,
- /* AddressConfig Bits */
- autoSelect9 = 0x0080,
- xcvrMask9 = 0xC000,
- /* ConfigControl bits */
- Ena = 0x0001,
- base10TAvailable9 = 0x0200,
- coaxAvailable9 = 0x1000,
- auiAvailable9 = 0x2000,
- /* EepromCommand bits */
- EepromReadRegister = 0x0080,
- EepromBusy = 0x8000,
-};
-
-enum { /* Window 1 - operating set */
- Wop = 0x0001,
-};
-
-enum { /* Window 3 - FIFO management */
- Wfifo = 0x0003,
- /* registers */
- InternalConfig = 0x0000, /* 3C509B, 3C589, 3C59[0257] */
- /* InternalConfig bits */
- xcvr10BaseT = 0x00000000,
- xcvr10Base2 = 0x00300000,
-};
-
-enum { /* Window 4 - diagnostic */
- Wdiagnostic = 0x0004,
- /* registers */
- MediaStatus = 0x000A,
- /* MediaStatus bits */
- linkBeatDetect = 0x0800,
-};
-
-extern int etherelnk3reset(Ether*);
-
-static char *tcmpcmcia[] = {
- "3C589", /* 3COM 589[ABCD] */
- "3C562", /* 3COM 562 */
- "589E", /* 3COM Megahertz 589E */
- nil,
-};
-
-static int
-configASIC(Ether* ether, int port, int xcvr)
-{
- int x;
-
- /* set Window 0 configuration registers */
- COMMAND(port, SelectRegisterWindow, Wsetup);
- outs(port+ConfigControl, Ena);
-
- /* IRQ must be 3 on 3C589/3C562 */
- outs(port + ResourceConfig, 0x3F00);
-
- x = ins(port+AddressConfig) & ~xcvrMask9;
- x |= (xcvr>>20)<<14;
- outs(port+AddressConfig, x);
-
- COMMAND(port, TxReset, 0);
- while(STATUS(port) & commandInProgress)
- ;
- COMMAND(port, RxReset, 0);
- while(STATUS(port) & commandInProgress)
- ;
-
- return etherelnk3reset(ether);
-}
-
-static int
-reset(Ether* ether)
-{
- int i, t, slot;
- char *type;
- int port;
- enum { WantAny, Want10BT, Want10B2 };
- int want;
- uchar ea[6];
- char *p;
-
- if(ether->irq == 0)
- ether->irq = 10;
- if(ether->port == 0)
- ether->port = 0x240;
- port = ether->port;
-
- if(ioalloc(port, 0x10, 0, "3C589") < 0)
- return -1;
-
- type = nil;
- slot = -1;
- for(i = 0; tcmpcmcia[i] != nil; i++){
- type = tcmpcmcia[i];
- if((slot = pcmspecial(type, ether)) >= 0)
- break;
- }
- if(slot < 0){
- iofree(port);
- return -1;
- }
-
- /*
- * Read Ethernet address from card memory
- * on 3C562, but only if the user has not
- * overridden it.
- */
- memset(ea, 0, sizeof ea);
- if(memcmp(ea, ether->ea, 6) == 0 && strcmp(type, "3C562") == 0) {
- if(pcmcistuple(slot, 0x88, -1, ea, 6) == 6) {
- for(i = 0; i < 6; i += 2){
- t = ea[i];
- ea[i] = ea[i+1];
- ea[i+1] = t;
- }
- memmove(ether->ea, ea, 6);
- }
- }
- /*
- * Allow user to specify desired media in plan9.ini
- */
- want = WantAny;
- for(i = 0; i < ether->nopt; i++){
- if(cistrncmp(ether->opt[i], "media=", 6) != 0)
- continue;
- p = ether->opt[i]+6;
- if(cistrcmp(p, "10base2") == 0)
- want = Want10B2;
- else if(cistrcmp(p, "10baseT") == 0)
- want = Want10BT;
- }
-
- /* try configuring as a 10BaseT */
- if(want==WantAny || want==Want10BT){
- if(configASIC(ether, port, xcvr10BaseT) < 0){
- pcmspecialclose(slot);
- iofree(port);
- return -1;
- }
- delay(100);
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- if((ins(port+MediaStatus)&linkBeatDetect) || want==Want10BT){
- COMMAND(port, SelectRegisterWindow, Wop);
- print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, type);
- return 0;
- }
- }
-
- /* try configuring as a 10base2 */
- if(want==WantAny || want==Want10B2){
- COMMAND(port, GlobalReset, 0);
- if(configASIC(ether, port, xcvr10Base2) < 0){
- pcmspecialclose(slot);
- iofree(port);
- return -1;
- }
- print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, type);
- return 0;
- }
- return -1; /* not reached */
-}
-
-void
-ether589link(void)
-{
- addethercard("3C589", reset);
- addethercard("3C562", reset);
- addethercard("589E", reset);
-}
diff --git a/os/pc/ether79c960.c b/os/pc/ether79c960.c
deleted file mode 100644
index f74574cd..00000000
--- a/os/pc/ether79c960.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * AM79C960
- * PCnet Single-Chip Ethernet Controller for ISA Bus
- * To do:
- * only issue transmit interrupt if necessary?
- * dynamically increase rings as necessary?
- * use Blocks as receive buffers?
- * currently hardwires 10Base-T
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-#define chatty 1
-#define DPRINT if(chatty)print
-
-enum {
- Lognrdre = 6,
- Nrdre = (1<<Lognrdre), /* receive descriptor ring entries */
- Logntdre = 4,
- Ntdre = (1<<Logntdre), /* transmit descriptor ring entries */
-
- Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */
-};
-
-enum { /* I/O resource map */
- Aprom = 0x0000, /* physical address */
- Rdp = 0x0010, /* register data port */
- Rap = 0x0012, /* register address port */
- Sreset = 0x0014, /* software reset */
- /*Bdp = 0x001C, /* bus configuration register data port */
- Idp = 0x0016, /* ISA data port */
-};
-
-enum { /* ISACSR2 */
- Isa10 = 0x0001, /* 10base-T */
- Isamedia = 0x0003, /* media selection mask */
- Isaawake = 0x0004, /* Auto-Wake */
-};
-
-enum { /* CSR0 */
- Init = 0x0001, /* begin initialisation */
- Strt = 0x0002, /* enable chip */
- Stop = 0x0004, /* disable chip */
- Tdmd = 0x0008, /* transmit demand */
- Txon = 0x0010, /* transmitter on */
- Rxon = 0x0020, /* receiver on */
- Iena = 0x0040, /* interrupt enable */
- Intr = 0x0080, /* interrupt flag */
- Idon = 0x0100, /* initialisation done */
- Tint = 0x0200, /* transmit interrupt */
- Rint = 0x0400, /* receive interrupt */
- Merr = 0x0800, /* memory error */
- Miss = 0x1000, /* missed frame */
- Cerr = 0x2000, /* collision */
- Babl = 0x4000, /* transmitter timeout */
- Err = 0x8000, /* Babl|Cerr|Miss|Merr */
-};
-
-enum { /* CSR3 */
- Emba = 0x0008, /* enable modified back-off algorithm */
- Dxmt2pd = 0x0010, /* disable transmit two part deferral */
- Lappen = 0x0020, /* look-ahead packet processing enable */
- Idonm = 0x0100, /* initialisation done mask */
- Tintm = 0x0200, /* transmit interrupt mask */
- Rintm = 0x0400, /* receive interrupt mask */
- Merrm = 0x0800, /* memory error mask */
- Missm = 0x1000, /* missed frame mask */
- Bablm = 0x4000, /* babl mask */
-};
-
-enum { /* CSR4 */
- ApadXmt = 0x0800, /* auto pad transmit */
-};
-
-enum { /* CSR15 */
- Prom = 0x8000, /* promiscuous mode */
- TenBaseT = 0x0080, /* 10Base-T */
-};
-
-typedef struct { /* Initialisation Block */
- ushort mode;
- uchar padr[6];
- uchar ladr[8];
- ushort rdra0; /* bits 0-15 */
- uchar rdra16; /* bits 16-23 */
- uchar rlen; /* upper 3 bits */
- ushort tdra0; /* bits 0-15 */
- uchar tdra16; /* bits 16-23 */
- uchar tlen; /* upper 3 bits */
-} Iblock;
-
-typedef struct { /* receive descriptor ring entry */
- ushort rbadr; /* buffer address 0-15 */
- ushort rmd1; /* status|buffer address 16-23 */
- ushort rmd2; /* bcnt */
- ushort rmd3; /* mcnt */
-} Rdre;
-
-typedef struct { /* transmit descriptor ring entry */
- ushort tbadr; /* buffer address 0-15 */
- ushort tmd1; /* status|buffer address 16-23 */
- ushort tmd2; /* bcnt */
- ushort tmd3; /* errors */
-} Tdre;
-
-enum { /* [RT]dre status bits */
- Enp = 0x0100, /* end of packet */
- Stp = 0x0200, /* start of packet */
- RxBuff = 0x0400, /* buffer error */
- TxDef = 0x0400, /* deferred */
- RxCrc = 0x0800, /* CRC error */
- TxOne = 0x0800, /* one retry needed */
- RxOflo = 0x1000, /* overflow error */
- TxMore = 0x1000, /* more than one retry needed */
- Fram = 0x2000, /* framing error */
- RxErr = 0x4000, /* Fram|Oflo|Crc|RxBuff */
- TxErr = 0x4000, /* Uflo|Lcol|Lcar|Rtry */
- Own = 0x8000,
-};
-
-typedef struct {
- Lock;
-
- int init; /* initialisation in progress */
- Iblock iblock;
-
- Rdre* rdr; /* receive descriptor ring */
- void* rrb; /* receive ring buffers */
- int rdrx; /* index into rdr */
-
- Tdre* tdr; /* transmit descriptor ring */
- void* trb; /* transmit ring buffers */
- int tdrx; /* index into tdr */
-} Ctlr;
-
-static void
-attach(Ether* ether)
-{
- Ctlr *ctlr;
- int port;
-
- ctlr = ether->ctlr;
- ilock(ctlr);
- if(ctlr->init){
- iunlock(ctlr);
- return;
- }
- port = ether->port;
- outs(port+Rdp, Iena|Strt);
- iunlock(ctlr);
-}
-
-static void
-ringinit(Ctlr* ctlr)
-{
- int i, x;
-
- /*
- * Initialise the receive and transmit buffer rings. The ring
- * entries must be aligned on 16-byte boundaries.
- *
- * This routine is protected by ctlr->init.
- */
- if(ctlr->rdr == 0)
- ctlr->rdr = xspanalloc(Nrdre*sizeof(Rdre), 0x10, 0);
- if(ctlr->rrb == 0)
- ctlr->rrb = xalloc(Nrdre*Rbsize);
-
- x = PADDR(ctlr->rrb);
- if ((x >> 24)&0xFF)
- panic("ether79c960: address>24bit");
- for(i = 0; i < Nrdre; i++){
- ctlr->rdr[i].rbadr = x&0xFFFF;
- ctlr->rdr[i].rmd1 = Own|(x>>16)&0xFF;
- x += Rbsize;
- ctlr->rdr[i].rmd2 = 0xF000|-Rbsize&0x0FFF;
- ctlr->rdr[i].rmd3 = 0;
- }
- ctlr->rdrx = 0;
-
- if(ctlr->tdr == 0)
- ctlr->tdr = xspanalloc(Ntdre*sizeof(Tdre), 0x10, 0);
- if(ctlr->trb == 0)
- ctlr->trb = xalloc(Ntdre*Rbsize);
-
- x = PADDR(ctlr->trb);
- if ((x >> 24)&0xFF)
- panic("ether79c960: address>24bit");
- for(i = 0; i < Ntdre; i++){
- ctlr->tdr[i].tbadr = x&0xFFFF;
- ctlr->tdr[i].tmd1 = (x>>16)&0xFF;
- x += Rbsize;
- ctlr->tdr[i].tmd2 = 0xF000|-Rbsize&0x0FFF;
- }
- ctlr->tdrx = 0;
-}
-
-static void
-promiscuous(void* arg, int on)
-{
- Ether *ether;
- int port, x;
- Ctlr *ctlr;
-
- ether = arg;
- port = ether->port;
- ctlr = ether->ctlr;
-
- /*
- * Put the chip into promiscuous mode. First we must wait until
- * anyone transmitting is done, then we can stop the chip and put
- * it in promiscuous mode. Restarting is made harder by the chip
- * reloading the transmit and receive descriptor pointers with their
- * base addresses when Strt is set (unlike the older Lance chip),
- * so the rings must be re-initialised.
- */
- ilock(ctlr);
- if(ctlr->init){
- iunlock(ctlr);
- return;
- }
- ctlr->init = 1;
- iunlock(ctlr);
-
- outs(port+Rdp, Stop);
-
- outs(port+Rap, 15);
- x = ins(port+Rdp) & ~Prom;
- if(on)
- x |= Prom; /* BUG: multicast ... */
- outs(port+Rdp, x);
- outs(port+Rap, 0);
-
- ringinit(ctlr);
-
- ilock(ctlr);
- ctlr->init = 0;
- outs(port+Rdp, Iena|Strt);
- iunlock(ctlr);
-}
-
-static int
-owntdre(void* arg)
-{
- return (((Tdre*)arg)->tmd1 & Own) == 0;
-}
-
-static void
-txstart(Ether *ether)
-{
- int port;
- Ctlr *ctlr;
- Tdre *tdre;
- Etherpkt *pkt;
- Block *bp;
- int n;
-
- port = ether->port;
- ctlr = ether->ctlr;
-
- if(ctlr->init)
- return;
-
- /*
- * Take the next transmit buffer, if it is free.
- */
- tdre = &ctlr->tdr[ctlr->tdrx];
- if(owntdre(tdre) == 0)
- return;
- bp = qget(ether->oq);
- if(bp == nil)
- return;
-
- /*
- * Copy the packet to the transmit buffer and fill in our
- * source ethernet address. There's no need to pad to ETHERMINTU
- * here as we set ApadXmit in CSR4.
- */
- n = BLEN(bp);
- pkt = KADDR(tdre->tbadr|(tdre->tmd1&0xFF)<<16);
- memmove(pkt->d, bp->rp, n);
- memmove(pkt->s, ether->ea, sizeof(pkt->s));
- freeb(bp);
-
- /*
- * Give ownership of the descriptor to the chip, increment the
- * software ring descriptor pointer and tell the chip to poll.
- */
- tdre->tmd3 = 0;
- tdre->tmd2 = 0xF000|(-n)&0x0FFF;
- tdre->tmd1 |= Own|Stp|Enp;
- ctlr->tdrx = NEXT(ctlr->tdrx, Ntdre);
- outs(port+Rdp, Iena|Tdmd);
-
- ether->outpackets++;
-}
-
-static void
-transmit(Ether *ether)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
-
- ilock(ctlr);
- txstart(ether);
- iunlock(ctlr);
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
- Ether *ether;
- int port, csr0, status;
- Ctlr *ctlr;
- Rdre *rdre;
- Etherpkt *pkt;
- Block *bp;
- int len;
-
- ether = arg;
- port = ether->port;
- ctlr = ether->ctlr;
-
- /*
- * Acknowledge all interrupts and whine about those that shouldn't
- * happen.
- */
- csr0 = ins(port+Rdp);
- outs(port+Rdp, Babl|Cerr|Miss|Merr|Rint|Tint|Iena);
- if(csr0 & (Babl|Miss|Merr))
- print("AMD70C960#%d: csr0 = 0x%uX\n", ether->ctlrno, csr0);
-
- /*
- * Receiver interrupt: run round the descriptor ring logging
- * errors and passing valid receive data up to the higher levels
- * until we encounter a descriptor still owned by the chip.
- */
- if(csr0 & Rint){
- rdre = &ctlr->rdr[ctlr->rdrx];
- while(((status = rdre->rmd1) & Own) == 0){
- if(status & RxErr){
- if(status & RxBuff)
- ether->buffs++;
- if(status & RxCrc)
- ether->crcs++;
- if(status & RxOflo)
- ether->overflows++;
- }
- else {
- len = (rdre->rmd3 & 0x0FFF)-4;
- if((bp = iallocb(len)) != nil){
- ether->inpackets++;
- pkt = KADDR(rdre->rbadr|(rdre->rmd1&0xFF)<<16);
- memmove(bp->wp, pkt, len);
- bp->wp += len;
- etheriq(ether, bp, 1);
- }
- }
-
- /*
- * Finished with this descriptor, reinitialise it,
- * give it back to the chip, then on to the next...
- */
- rdre->rmd3 = 0;
- rdre->rmd2 = 0xF000|-Rbsize&0x0FFF;
- rdre->rmd1 |= Own;
-
- ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
- rdre = &ctlr->rdr[ctlr->rdrx];
- }
- }
-
- /*
- * Transmitter interrupt: start next block if waiting for free descriptor.
- */
- if(csr0 & Tint){
- lock(ctlr);
- txstart(ether);
- unlock(ctlr);
- }
-}
-
-static int
-reset(Ether* ether)
-{
- int port, x, i;
- uchar ea[Eaddrlen];
- Ctlr *ctlr;
-
- if(ether->port == 0)
- ether->port = 0x300;
- if(ether->irq == 0)
- ether->irq = 10;
- if(ether->irq == 2)
- ether->irq = 9;
- if(ether->dma == 0)
- ether->dma = 5;
- port = ether->port;
-
- if(port == 0 || ether->dma == 0)
- return -1;
-
- /*
- * Allocate a controller structure and start to fill in the
- * initialisation block (must be DWORD aligned).
- */
- ether->ctlr = malloc(sizeof(Ctlr));
- ctlr = ether->ctlr;
-
- ilock(ctlr);
- ctlr->init = 1;
-
- /*
- * Set the auto pad transmit in CSR4.
- */
- /*outs(port+Rdp, 0x00);/**/
- ins(port+Sreset); /**/
- delay(1);
- outs(port+Rap, 0);
- outs(port+Rdp, Stop);
-
- outs(port+Rap, 4);
- x = ins(port+Rdp) & 0xFFFF;
- outs(port+Rdp, ApadXmt|x);
-
- outs(port+Rap, 0);
-
- /*
- * Check if we are going to override the adapter's station address.
- * If not, read it from the I/O-space and set in ether->ea prior to loading the
- * station address in the initialisation block.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, ether->ea, Eaddrlen) == 0){
- for(i=0; i<6; i++)
- ether->ea[i] = inb(port + Aprom + i);
- }
-
- ctlr->iblock.rlen = Lognrdre<<5;
- ctlr->iblock.tlen = Logntdre<<5;
- memmove(ctlr->iblock.padr, ether->ea, sizeof(ctlr->iblock.padr));
-
- ringinit(ctlr);
-
- x = PADDR(ctlr->rdr);
- ctlr->iblock.rdra0 = x&0xFFFF;
- ctlr->iblock.rdra16 = (x >> 16)&0xFF;
- x = PADDR(ctlr->tdr);
- ctlr->iblock.tdra0 = x&0xFFFF;
- ctlr->iblock.tdra16 = (x >> 16)&0xFF;
-
- /*
- * set the DMA controller to cascade mode for bus master
- */
- switch(ether->dma){
- case 5:
- outb(0xd6, 0xc1); outb(0xd4, 1); break;
- case 6:
- outb(0xd6, 0xc2); outb(0xd4, 2); break;
- case 7:
- outb(0xd6, 0xc3); outb(0xd4, 3); break;
- }
-
- /*
- * Ensure 10Base-T (for now)
- */
- ctlr->iblock.mode = TenBaseT;
- outs(port+Rap, 2);
- x = ins(port+Idp);
- x &= ~Isamedia;
- x |= Isa10;
- x |= Isaawake;
- outs(port+Idp, x);
-
- /*
- * Point the chip at the initialisation block and tell it to go.
- * Mask the Idon interrupt and poll for completion. Strt and interrupt
- * enables will be set later when we're ready to attach to the network.
- */
- x = PADDR(&ctlr->iblock);
- if((x>>24)&0xFF)
- panic("ether79c960: address>24bit");
- outs(port+Rap, 1);
- outs(port+Rdp, x & 0xFFFF);
- outs(port+Rap, 2);
- outs(port+Rdp, (x>>16) & 0xFF);
- outs(port+Rap, 3);
- outs(port+Rdp, Idonm);
- outs(port+Rap, 0);
- outs(port+Rdp, Init);
-
- while((ins(port+Rdp) & Idon) == 0)
- ;
- outs(port+Rdp, Idon|Stop);
- ctlr->init = 0;
- iunlock(ctlr);
-
- ether->port = port;
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = 0;
-
- ether->promiscuous = promiscuous;
- ether->arg = ether;
-
- return 0;
-}
-
-void
-ether79c960link(void)
-{
- addethercard("AMD79C960", reset);
-}
diff --git a/os/pc/ether79c970.c b/os/pc/ether79c970.c
deleted file mode 100644
index 43924a3f..00000000
--- a/os/pc/ether79c970.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * AMD79C970
- * PCnet-PCI Single-Chip Ethernet Controller for PCI Local Bus
- * To do:
- * finish this rewrite
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-enum {
- Lognrdre = 6,
- Nrdre = (1<<Lognrdre),/* receive descriptor ring entries */
- Logntdre = 4,
- Ntdre = (1<<Logntdre),/* transmit descriptor ring entries */
-
- Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */
-};
-
-enum { /* DWIO I/O resource map */
- Aprom = 0x0000, /* physical address */
- Rdp = 0x0010, /* register data port */
- Rap = 0x0014, /* register address port */
- Sreset = 0x0018, /* software reset */
- Bdp = 0x001C, /* bus configuration register data port */
-};
-
-enum { /* CSR0 */
- Init = 0x0001, /* begin initialisation */
- Strt = 0x0002, /* enable chip */
- Stop = 0x0004, /* disable chip */
- Tdmd = 0x0008, /* transmit demand */
- Txon = 0x0010, /* transmitter on */
- Rxon = 0x0020, /* receiver on */
- Iena = 0x0040, /* interrupt enable */
- Intr = 0x0080, /* interrupt flag */
- Idon = 0x0100, /* initialisation done */
- Tint = 0x0200, /* transmit interrupt */
- Rint = 0x0400, /* receive interrupt */
- Merr = 0x0800, /* memory error */
- Miss = 0x1000, /* missed frame */
- Cerr = 0x2000, /* collision */
- Babl = 0x4000, /* transmitter timeout */
- Err = 0x8000, /* Babl|Cerr|Miss|Merr */
-};
-
-enum { /* CSR3 */
- Bswp = 0x0004, /* byte swap */
- Emba = 0x0008, /* enable modified back-off algorithm */
- Dxmt2pd = 0x0010, /* disable transmit two part deferral */
- Lappen = 0x0020, /* look-ahead packet processing enable */
-};
-
-enum { /* CSR4 */
- ApadXmt = 0x0800, /* auto pad transmit */
-};
-
-enum { /* CSR15 */
- Prom = 0x8000, /* promiscuous mode */
-};
-
-typedef struct Iblock Iblock;
-struct Iblock { /* Initialisation Block */
- ushort mode;
- uchar rlen; /* upper 4 bits */
- uchar tlen; /* upper 4 bits */
- uchar padr[6];
- uchar res[2];
- uchar ladr[8];
- ulong rdra;
- ulong tdra;
-};
-
-typedef struct Dre Dre;
-struct Dre { /* descriptor ring entry */
- ulong addr;
- ulong md1; /* status|bcnt */
- ulong md2; /* rcc|rpc|mcnt */
- Block* bp;
-};
-
-enum { /* md1 */
- Enp = 0x01000000, /* end of packet */
- Stp = 0x02000000, /* start of packet */
- RxBuff = 0x04000000, /* buffer error */
- Def = 0x04000000, /* deferred */
- Crc = 0x08000000, /* CRC error */
- One = 0x08000000, /* one retry needed */
- Oflo = 0x10000000, /* overflow error */
- More = 0x10000000, /* more than one retry needed */
- Fram = 0x20000000, /* framing error */
- RxErr = 0x40000000, /* Fram|Oflo|Crc|RxBuff */
- TxErr = 0x40000000, /* Uflo|Lcol|Lcar|Rtry */
- Own = 0x80000000,
-};
-
-enum { /* md2 */
- Rtry = 0x04000000, /* failed after repeated retries */
- Lcar = 0x08000000, /* loss of carrier */
- Lcol = 0x10000000, /* late collision */
- Uflo = 0x40000000, /* underflow error */
- TxBuff = 0x80000000, /* buffer error */
-};
-
-typedef struct Ctlr Ctlr;
-struct Ctlr {
- Lock;
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
-
- int init; /* initialisation in progress */
- Iblock iblock;
-
- Dre* rdr; /* receive descriptor ring */
- int rdrx;
-
- Dre* tdr; /* transmit descriptor ring */
- int tdrh; /* host index into tdr */
- int tdri; /* interface index into tdr */
- int ntq; /* descriptors active */
-
- ulong rxbuff; /* receive statistics */
- ulong crc;
- ulong oflo;
- ulong fram;
-
- ulong rtry; /* transmit statistics */
- ulong lcar;
- ulong lcol;
- ulong uflo;
- ulong txbuff;
-
- ulong merr; /* bobf is such a whiner */
- ulong miss;
- ulong babl;
-
- int (*ior)(Ctlr*, int);
- void (*iow)(Ctlr*, int, int);
-};
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-/*
- * The Rdp, Rap, Sreset, Bdp ports are 32-bit port offset in the enumeration above.
- * To get to 16-bit offsets, scale down with 0x10 staying the same.
- */
-static int
-io16r(Ctlr *c, int r)
-{
- if(r >= Rdp)
- r = (r-Rdp)/2+Rdp;
- return ins(c->port+r);
-}
-
-static void
-io16w(Ctlr *c, int r, int v)
-{
- if(r >= Rdp)
- r = (r-Rdp)/2+Rdp;
- outs(c->port+r, v);
-}
-
-static int
-io32r(Ctlr *c, int r)
-{
- return inl(c->port+r);
-}
-
-static void
-io32w(Ctlr *c, int r, int v)
-{
- outl(c->port+r, v);
-}
-
-static void
-attach(Ether*)
-{
-}
-
-static long
-ifstat(Ether* ether, void* a, long n, ulong offset)
-{
- char *p;
- int len;
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
-
- ether->crcs = ctlr->crc;
- ether->frames = ctlr->fram;
- ether->buffs = ctlr->rxbuff+ctlr->txbuff;
- ether->overflows = ctlr->oflo;
-
- if(n == 0)
- return 0;
-
- p = malloc(READSTR);
- len = snprint(p, READSTR, "Rxbuff: %ld\n", ctlr->rxbuff);
- len += snprint(p+len, READSTR-len, "Crc: %ld\n", ctlr->crc);
- len += snprint(p+len, READSTR-len, "Oflo: %ld\n", ctlr->oflo);
- len += snprint(p+len, READSTR-len, "Fram: %ld\n", ctlr->fram);
- len += snprint(p+len, READSTR-len, "Rtry: %ld\n", ctlr->rtry);
- len += snprint(p+len, READSTR-len, "Lcar: %ld\n", ctlr->lcar);
- len += snprint(p+len, READSTR-len, "Lcol: %ld\n", ctlr->lcol);
- len += snprint(p+len, READSTR-len, "Uflo: %ld\n", ctlr->uflo);
- len += snprint(p+len, READSTR-len, "Txbuff: %ld\n", ctlr->txbuff);
- len += snprint(p+len, READSTR-len, "Merr: %ld\n", ctlr->merr);
- len += snprint(p+len, READSTR-len, "Miss: %ld\n", ctlr->miss);
- snprint(p+len, READSTR-len, "Babl: %ld\n", ctlr->babl);
-
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static void
-ringinit(Ctlr* ctlr)
-{
- Dre *dre;
-
- /*
- * Initialise the receive and transmit buffer rings.
- * The ring entries must be aligned on 16-byte boundaries.
- *
- * This routine is protected by ctlr->init.
- */
- if(ctlr->rdr == 0){
- ctlr->rdr = xspanalloc(Nrdre*sizeof(Dre), 0x10, 0);
- for(dre = ctlr->rdr; dre < &ctlr->rdr[Nrdre]; dre++){
- dre->bp = iallocb(Rbsize);
- if(dre->bp == nil)
- panic("can't allocate ethernet receive ring\n");
- dre->addr = PADDR(dre->bp->rp);
- dre->md2 = 0;
- dre->md1 = Own|(-Rbsize & 0xFFFF);
- }
- }
- ctlr->rdrx = 0;
-
- if(ctlr->tdr == 0)
- ctlr->tdr = xspanalloc(Ntdre*sizeof(Dre), 0x10, 0);
- memset(ctlr->tdr, 0, Ntdre*sizeof(Dre));
- ctlr->tdrh = ctlr->tdri = 0;
-}
-
-static void
-promiscuous(void* arg, int on)
-{
- Ether *ether;
- int x;
- Ctlr *ctlr;
-
- ether = arg;
- ctlr = ether->ctlr;
-
- /*
- * Put the chip into promiscuous mode. First must wait until
- * anyone transmitting is done, then stop the chip and put
- * it in promiscuous mode. Restarting is made harder by the chip
- * reloading the transmit and receive descriptor pointers with their
- * base addresses when Strt is set (unlike the older Lance chip),
- * so the rings must be re-initialised.
- */
- ilock(ctlr);
- if(ctlr->init){
- iunlock(ctlr);
- return;
- }
- ctlr->init = 1;
- iunlock(ctlr);
-
- while(ctlr->ntq)
- ;
-
- ctlr->iow(ctlr, Rdp, Stop);
-
- ctlr->iow(ctlr, Rap, 15);
- x = ctlr->ior(ctlr, Rdp) & ~Prom;
- if(on)
- x |= Prom;
- ctlr->iow(ctlr, Rdp, x);
- ctlr->iow(ctlr, Rap, 0);
-
- ringinit(ctlr);
-
- ilock(ctlr);
- ctlr->init = 0;
- ctlr->iow(ctlr, Rdp, Iena|Strt);
- iunlock(ctlr);
-}
-
-static void
-multicast(void* arg, uchar*, int)
-{
- promiscuous(arg, 1);
-}
-
-static void
-txstart(Ether* ether)
-{
- Ctlr *ctlr;
- Block *bp;
- Dre *dre;
-
- ctlr = ether->ctlr;
-
- if(ctlr->init)
- return;
-
- while(ctlr->ntq < (Ntdre-1)){
- bp = qget(ether->oq);
- if(bp == nil)
- break;
-
- /*
- * Give ownership of the descriptor to the chip,
- * increment the software ring descriptor pointer
- * and tell the chip to poll.
- * There's no need to pad to ETHERMINTU
- * here as ApadXmt is set in CSR4.
- */
- dre = &ctlr->tdr[ctlr->tdrh];
- dre->bp = bp;
- dre->addr = PADDR(bp->rp);
- dre->md2 = 0;
- dre->md1 = Own|Stp|Enp|(-BLEN(bp) & 0xFFFF);
- ctlr->ntq++;
- ctlr->iow(ctlr, Rdp, Iena|Tdmd);
- ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre);
- }
-}
-
-static void
-transmit(Ether* ether)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(ctlr);
- txstart(ether);
- iunlock(ctlr);
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
- Ctlr *ctlr;
- Ether *ether;
- int csr0, len;
- Dre *dre;
- Block *bp;
-
- ether = arg;
- ctlr = ether->ctlr;
-
- /*
- * Acknowledge all interrupts and whine about those that shouldn't
- * happen.
- */
-intrloop:
- csr0 = ctlr->ior(ctlr, Rdp) & 0xFFFF;
- ctlr->iow(ctlr, Rdp, Babl|Cerr|Miss|Merr|Rint|Tint|Iena);
- if(csr0 & Merr)
- ctlr->merr++;
- if(csr0 & Miss)
- ctlr->miss++;
- if(csr0 & Babl)
- ctlr->babl++;
- //if(csr0 & (Babl|Miss|Merr))
- // print("#l%d: csr0 = 0x%uX\n", ether->ctlrno, csr0);
- if(!(csr0 & (Rint|Tint)))
- return;
-
- /*
- * Receiver interrupt: run round the descriptor ring logging
- * errors and passing valid receive data up to the higher levels
- * until a descriptor is encountered still owned by the chip.
- */
- if(csr0 & Rint){
- dre = &ctlr->rdr[ctlr->rdrx];
- while(!(dre->md1 & Own)){
- if(dre->md1 & RxErr){
- if(dre->md1 & RxBuff)
- ctlr->rxbuff++;
- if(dre->md1 & Crc)
- ctlr->crc++;
- if(dre->md1 & Oflo)
- ctlr->oflo++;
- if(dre->md1 & Fram)
- ctlr->fram++;
- }
- else if(bp = iallocb(Rbsize)){
- len = (dre->md2 & 0x0FFF)-4;
- dre->bp->wp = dre->bp->rp+len;
- etheriq(ether, dre->bp, 1);
- dre->bp = bp;
- dre->addr = PADDR(bp->rp);
- }
-
- /*
- * Finished with this descriptor, reinitialise it,
- * give it back to the chip, then on to the next...
- */
- dre->md2 = 0;
- dre->md1 = Own|(-Rbsize & 0xFFFF);
-
- ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
- dre = &ctlr->rdr[ctlr->rdrx];
- }
- }
-
- /*
- * Transmitter interrupt: wakeup anyone waiting for a free descriptor.
- */
- if(csr0 & Tint){
- lock(ctlr);
- while(ctlr->ntq){
- dre = &ctlr->tdr[ctlr->tdri];
- if(dre->md1 & Own)
- break;
-
- if(dre->md1 & TxErr){
- if(dre->md2 & Rtry)
- ctlr->rtry++;
- if(dre->md2 & Lcar)
- ctlr->lcar++;
- if(dre->md2 & Lcol)
- ctlr->lcol++;
- if(dre->md2 & Uflo)
- ctlr->uflo++;
- if(dre->md2 & TxBuff)
- ctlr->txbuff++;
- ether->oerrs++;
- }
-
- freeb(dre->bp);
-
- ctlr->ntq--;
- ctlr->tdri = NEXT(ctlr->tdri, Ntdre);
- }
- txstart(ether);
- unlock(ctlr);
- }
- goto intrloop;
-}
-
-static void
-amd79c970pci(void)
-{
- int port;
- Ctlr *ctlr;
- Pcidev *p;
-
- p = nil;
- while(p = pcimatch(p, 0x1022, 0x2000)){
- port = p->mem[0].bar & ~0x01;
- if(ioalloc(port, p->mem[0].size, 0, "amd79c970") < 0){
- print("amd79c970: port 0x%uX in use\n", port);
- continue;
- }
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = p->mem[0].bar & ~0x01;
- ctlr->pcidev = p;
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- }
-}
-
-static int
-reset(Ether* ether)
-{
- int x;
- uchar ea[Eaddrlen];
- Ctlr *ctlr;
-
- if(ctlrhead == nil)
- amd79c970pci();
-
- /*
- * Any adapter matches if no port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(ether->port == 0 || ether->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- /*
- * Allocate a controller structure and start to initialise it.
- */
- ether->ctlr = ctlr;
- ether->port = ctlr->port;
- ether->irq = ctlr->pcidev->intl;
- ether->tbdf = ctlr->pcidev->tbdf;
- pcisetbme(ctlr->pcidev);
- ilock(ctlr);
- ctlr->init = 1;
-
- io32r(ctlr, Sreset);
- io16r(ctlr, Sreset);
-
- if(io16w(ctlr, Rap, 0), io16r(ctlr, Rdp) == 4){
- ctlr->ior = io16r;
- ctlr->iow = io16w;
- }else if(io32w(ctlr, Rap, 0), io32r(ctlr, Rdp) == 4){
- ctlr->ior = io32r;
- ctlr->iow = io32w;
- }else{
- print("#l%d: card doesn't talk right\n", ether->ctlrno);
- iunlock(ctlr);
- return -1;
- }
-
- ctlr->iow(ctlr, Rap, 88);
- x = ctlr->ior(ctlr, Rdp);
- ctlr->iow(ctlr, Rap, 89);
- x |= ctlr->ior(ctlr, Rdp)<<16;
-
- switch(x&0xFFFFFFF){
- case 0x2420003: /* PCnet/PCI 79C970 */
- case 0x2621003: /* PCnet/PCI II 79C970A */
- break;
- default:
- print("#l%d: unknown PCnet card version %.7ux\n",
- ether->ctlrno, x&0xFFFFFFF);
- iunlock(ctlr);
- return -1;
- }
-
- /*
- * Set the software style in BCR20 to be PCnet-PCI to ensure 32-bit access.
- * Set the auto pad transmit in CSR4.
- */
- ctlr->iow(ctlr, Rap, 20);
- ctlr->iow(ctlr, Bdp, 0x0002);
-
- ctlr->iow(ctlr, Rap, 4);
- x = ctlr->ior(ctlr, Rdp) & 0xFFFF;
- ctlr->iow(ctlr, Rdp, ApadXmt|x);
-
- ctlr->iow(ctlr, Rap, 0);
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the I/O-space and set in ether->ea prior to
- * loading the station address in the initialisation block.
- */
- memset(ea, 0, Eaddrlen);
- if(!memcmp(ea, ether->ea, Eaddrlen)){
- x = ctlr->ior(ctlr, Aprom);
- ether->ea[0] = x;
- ether->ea[1] = x>>8;
- if(ctlr->ior == io16r)
- x = ctlr->ior(ctlr, Aprom+2);
- else
- x >>= 16;
- ether->ea[2] = x;
- ether->ea[3] = x>>8;
- x = ctlr->ior(ctlr, Aprom+4);
- ether->ea[4] = x;
- ether->ea[5] = x>>8;
- }
-
- /*
- * Start to fill in the initialisation block
- * (must be DWORD aligned).
- */
- ctlr->iblock.rlen = Lognrdre<<4;
- ctlr->iblock.tlen = Logntdre<<4;
- memmove(ctlr->iblock.padr, ether->ea, sizeof(ctlr->iblock.padr));
-
- ringinit(ctlr);
- ctlr->iblock.rdra = PADDR(ctlr->rdr);
- ctlr->iblock.tdra = PADDR(ctlr->tdr);
-
- /*
- * Point the chip at the initialisation block and tell it to go.
- * Mask the Idon interrupt and poll for completion. Strt and interrupt
- * enables will be set later when attaching to the network.
- */
- x = PADDR(&ctlr->iblock);
- ctlr->iow(ctlr, Rap, 1);
- ctlr->iow(ctlr, Rdp, x & 0xFFFF);
- ctlr->iow(ctlr, Rap, 2);
- ctlr->iow(ctlr, Rdp, (x>>16) & 0xFFFF);
- ctlr->iow(ctlr, Rap, 3);
- ctlr->iow(ctlr, Rdp, Idon);
- ctlr->iow(ctlr, Rap, 0);
- ctlr->iow(ctlr, Rdp, Init);
-
- while(!(ctlr->ior(ctlr, Rdp) & Idon))
- ;
-
- /*
- * We used to set CSR0 to Idon|Stop here, and then
- * in attach change it to Iena|Strt. Apparently the simulated
- * 79C970 in VMware never enables after a write of Idon|Stop,
- * so we enable the device here now.
- */
- ctlr->iow(ctlr, Rdp, Iena|Strt);
- ctlr->init = 0;
- iunlock(ctlr);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = ifstat;
-
- ether->arg = ether;
- ether->promiscuous = promiscuous;
- ether->multicast = multicast;
-// ether->shutdown = shutdown;
-
- return 0;
-}
-
-void
-ether79c970link(void)
-{
- addethercard("AMD79C970", reset);
-}
diff --git a/os/pc/ether8003.c b/os/pc/ether8003.c
deleted file mode 100644
index 41244c09..00000000
--- a/os/pc/ether8003.c
+++ /dev/null
@@ -1,271 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-#include "ether8390.h"
-
-/*
- * Western Digital/Standard Microsystems Corporation cards (WD80[01]3).
- * Also handles 8216 cards (Elite Ultra).
- * Configuration code based on that provided by SMC a long time ago.
- */
-enum { /* 83C584 Bus Interface Controller */
- Msr = 0x00, /* Memory Select Register */
- Icr = 0x01, /* Interface Configuration Register */
- Iar = 0x02, /* I/O Address Register */
- Bio = 0x03, /* BIOS ROM Address Register */
- Ear = 0x03, /* EEROM Address Register (shared with Bio) */
- Irr = 0x04, /* Interrupt Request Register */
- Hcr = 0x04, /* 8216 hardware control */
- Laar = 0x05, /* LA Address Register */
- Ijr = 0x06, /* Initialisation Jumpers */
- Gp2 = 0x07, /* General Purpose Data Register */
- Lar = 0x08, /* LAN Address Registers */
- Id = 0x0E, /* Card ID byte */
- Cksum = 0x0F, /* Checksum */
-};
-
-enum { /* Msr */
- Rst = 0x80, /* software reset */
- Menb = 0x40, /* memory enable */
-};
-
-enum { /* Icr */
- Bit16 = 0x01, /* 16-bit bus */
- Other = 0x02, /* other register access */
- Ir2 = 0x04, /* IR2 */
- Msz = 0x08, /* SRAM size */
- Rla = 0x10, /* recall LAN address */
- Rx7 = 0x20, /* recall all but I/O and LAN address */
- Rio = 0x40, /* recall I/O address from EEROM */
- Sto = 0x80, /* non-volatile EEROM store */
-};
-
-enum { /* Laar */
- ZeroWS16 = 0x20, /* zero wait states for 16-bit ops */
- L16en = 0x40, /* enable 16-bit LAN operation */
- M16en = 0x80, /* enable 16-bit memory access */
-};
-
-enum { /* Ijr */
- Ienable = 0x01, /* 8216 interrupt enable */
-};
-
-/*
- * Mapping from configuration bits to interrupt level.
- */
-static int irq8003[8] = {
- 9, 3, 5, 7, 10, 11, 15, 4,
-};
-
-static int irq8216[8] = {
- 0, 9, 3, 5, 7, 10, 11, 15,
-};
-
-static void
-reset8003(Ether* ether, uchar ea[Eaddrlen], uchar ic[8])
-{
- Dp8390 *ctlr;
- ulong port;
-
- ctlr = ether->ctlr;
- port = ether->port;
-
- /*
- * Check for old, dumb 8003E, which doesn't have an interface
- * chip. Only Msr exists out of the 1st eight registers, reads
- * of the others just alias the 2nd eight registers, the LAN
- * address ROM. Can check Icr, Irr and Laar against the ethernet
- * address read above and if they match it's an 8003E (or an
- * 8003EBT, 8003S, 8003SH or 8003WT, doesn't matter), in which
- * case the default irq gets used.
- */
- if(memcmp(&ea[1], &ic[1], 5) == 0){
- memset(ic, 0, sizeof(ic));
- ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
- }
- else{
- /*
- * As a final sanity check for the 8013EBT, which doesn't have
- * the 83C584 interface chip, but has 2 real registers, write Gp2
- * and if it reads back the same, it's not an 8013EBT.
- */
- outb(port+Gp2, 0xAA);
- inb(port+Msr); /* wiggle bus */
- if(inb(port+Gp2) != 0xAA){
- memset(ic, 0, sizeof(ic));
- ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
- }
- else
- ether->irq = irq8003[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];
-
- /*
- * Check if 16-bit card.
- * If Bit16 is read/write, then it's an 8-bit card.
- * If Bit16 is set, it's in a 16-bit slot.
- */
- outb(port+Icr, ic[Icr]^Bit16);
- inb(port+Msr); /* wiggle bus */
- if((inb(port+Icr) & Bit16) == (ic[Icr] & Bit16)){
- ctlr->width = 2;
- ic[Icr] &= ~Bit16;
- }
- outb(port+Icr, ic[Icr]);
-
- if(ctlr->width == 2 && (inb(port+Icr) & Bit16) == 0)
- ctlr->width = 1;
- }
-
- ether->mem = (ulong)KADDR((ic[Msr] & 0x3F)<<13);
- if(ctlr->width == 2)
- ether->mem |= (ic[Laar] & 0x1F)<<19;
- else
- ether->mem |= 0x80000;
-
- if(ic[Icr] & (1<<3))
- ether->size = 32*1024;
- if(ctlr->width == 2)
- ether->size <<= 1;
-
- /*
- * Enable interface RAM, set interface width.
- */
- outb(port+Msr, ic[Msr]|Menb);
- if(ctlr->width == 2)
- outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16);
-}
-
-static void
-reset8216(Ether* ether, uchar[8])
-{
- uchar hcr, irq, x;
- ulong addr, port;
- Dp8390 *ctlr;
-
- ctlr = ether->ctlr;
- port = ether->port;
-
- ctlr->width = 2;
-
- /*
- * Switch to the alternate register set and retrieve the memory
- * and irq information.
- */
- hcr = inb(port+Hcr);
- outb(port+Hcr, 0x80|hcr);
- addr = inb(port+0x0B) & 0xFF;
- irq = inb(port+0x0D);
- outb(port+Hcr, hcr);
-
- ether->mem = (ulong)KADDR(0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13));
- ether->size = 8192*(1<<((addr>>4) & 0x03));
- ether->irq = irq8216[((irq>>4) & 0x04)|((irq>>2) & 0x03)];
-
- /*
- * Enable interface RAM, set interface width, and enable interrupts.
- */
- x = inb(port+Msr) & ~Rst;
- outb(port+Msr, Menb|x);
- x = inb(port+Laar);
- outb(port+Laar, M16en|x);
- outb(port+Ijr, Ienable);
-}
-
-/*
- * Get configuration parameters, enable memory.
- * There are opportunities here for buckets of code, try to resist.
- */
-static int
-reset(Ether* ether)
-{
- int i;
- uchar ea[Eaddrlen], ic[8], id, nullea[Eaddrlen], sum;
- ulong port;
- Dp8390 *ctlr;
-
- /*
- * Set up the software configuration.
- * Use defaults for port, irq, mem and size if not specified.
- * Defaults are set for the dumb 8003E which can't be
- * autoconfigured.
- */
- if(ether->port == 0)
- ether->port = 0x280;
- if(ether->irq == 0)
- ether->irq = 3;
- if(ether->mem == 0)
- ether->mem = 0xD0000;
- if(ether->size == 0)
- ether->size = 8*1024;
- if(ioalloc(ether->port, 0x20, 0, "wd8003") < 0)
- return -1;
-
- /*
- * Look for the interface. Read the LAN address ROM
- * and validate the checksum - the sum of all 8 bytes
- * should be 0xFF.
- * At the same time, get the (possible) interface chip
- * registers, they'll be used later to check for aliasing.
- */
- port = ether->port;
- sum = 0;
- for(i = 0; i < sizeof(ea); i++){
- ea[i] = inb(port+Lar+i);
- sum += ea[i];
- ic[i] = inb(port+i);
- }
- id = inb(port+Id);
- sum += id;
- sum += inb(port+Cksum);
- if(sum != 0xFF){
- iofree(ether->port);
- return -1;
- }
-
- ether->ctlr = malloc(sizeof(Dp8390));
- ctlr = ether->ctlr;
- ctlr->ram = 1;
-
- if((id & 0xFE) == 0x2A)
- reset8216(ether, ic);
- else
- reset8003(ether, ea, ic);
-
- /*
- * Set the DP8390 ring addresses.
- */
- ctlr->port = port+0x10;
- ctlr->tstart = 0;
- ctlr->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
- ctlr->pstop = HOWMANY(ether->size, Dp8390BufSz);
-
- /*
- * Finally, init the 8390, set the ethernet address
- * and claim the memory used.
- */
- dp8390reset(ether);
- memset(nullea, 0, Eaddrlen);
- if(memcmp(nullea, ether->ea, Eaddrlen) == 0){
- for(i = 0; i < sizeof(ether->ea); i++)
- ether->ea[i] = ea[i];
- }
- dp8390setea(ether);
-
- if(umbrwmalloc(PADDR(ether->mem), ether->size, 0) == 0)
- print("ether8003: warning - 0x%luX unavailable\n",
- PADDR(ether->mem));
-
- return 0;
-}
-
-void
-ether8003link(void)
-{
- addethercard("WD8003", reset);
-}
diff --git a/os/pc/ether8139.c b/os/pc/ether8139.c
deleted file mode 100644
index dd3653e3..00000000
--- a/os/pc/ether8139.c
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * Realtek 8139 (but not the 8129).
- * Error recovery for the various over/under -flow conditions
- * may need work.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-enum { /* registers */
- Idr0 = 0x0000, /* MAC address */
- Mar0 = 0x0008, /* Multicast address */
- Tsd0 = 0x0010, /* Transmit Status Descriptor0 */
- Tsad0 = 0x0020, /* Transmit Start Address Descriptor0 */
- Rbstart = 0x0030, /* Receive Buffer Start Address */
- Erbcr = 0x0034, /* Early Receive Byte Count */
- Ersr = 0x0036, /* Early Receive Status */
- Cr = 0x0037, /* Command Register */
- Capr = 0x0038, /* Current Address of Packet Read */
- Cbr = 0x003A, /* Current Buffer Address */
- Imr = 0x003C, /* Interrupt Mask */
- Isr = 0x003E, /* Interrupt Status */
- Tcr = 0x0040, /* Transmit Configuration */
- Rcr = 0x0044, /* Receive Configuration */
- Tctr = 0x0048, /* Timer Count */
- Mpc = 0x004C, /* Missed Packet Counter */
- Cr9346 = 0x0050, /* 9346 Command Register */
- Config0 = 0x0051, /* Configuration Register 0 */
- Config1 = 0x0052, /* Configuration Register 1 */
- TimerInt = 0x0054, /* Timer Interrupt */
- Msr = 0x0058, /* Media Status */
- Config3 = 0x0059, /* Configuration Register 3 */
- Config4 = 0x005A, /* Configuration Register 4 */
- Mulint = 0x005C, /* Multiple Interrupt Select */
- RerID = 0x005E, /* PCI Revision ID */
- Tsad = 0x0060, /* Transmit Status of all Descriptors */
-
- Bmcr = 0x0062, /* Basic Mode Control */
- Bmsr = 0x0064, /* Basic Mode Status */
- Anar = 0x0066, /* Auto-Negotiation Advertisment */
- Anlpar = 0x0068, /* Auto-Negotiation Link Partner */
- Aner = 0x006A, /* Auto-Negotiation Expansion */
- Dis = 0x006C, /* Disconnect Counter */
- Fcsc = 0x006E, /* False Carrier Sense Counter */
- Nwaytr = 0x0070, /* N-way Test */
- Rec = 0x0072, /* RX_ER Counter */
- Cscr = 0x0074, /* CS Configuration */
- Phy1parm = 0x0078, /* PHY Parameter 1 */
- Twparm = 0x007C, /* Twister Parameter */
- Phy2parm = 0x0080, /* PHY Parameter 2 */
-};
-
-enum { /* Cr */
- Bufe = 0x01, /* Rx Buffer Empty */
- Te = 0x04, /* Transmitter Enable */
- Re = 0x08, /* Receiver Enable */
- Rst = 0x10, /* Software Reset */
-};
-
-enum { /* Imr/Isr */
- Rok = 0x0001, /* Receive OK */
- Rer = 0x0002, /* Receive Error */
- Tok = 0x0004, /* Transmit OK */
- Ter = 0x0008, /* Transmit Error */
- Rxovw = 0x0010, /* Receive Buffer Overflow */
- PunLc = 0x0020, /* Packet Underrun or Link Change */
- Fovw = 0x0040, /* Receive FIFO Overflow */
- Clc = 0x2000, /* Cable Length Change */
- Timerbit = 0x4000, /* Timer */
- Serr = 0x8000, /* System Error */
-};
-
-enum { /* Tcr */
- Clrabt = 0x00000001, /* Clear Abort */
- TxrrSHIFT = 4, /* Transmit Retry Count */
- TxrrMASK = 0x000000F0,
- MtxdmaSHIFT = 8, /* Max. DMA Burst Size */
- MtxdmaMASK = 0x00000700,
- Mtxdma2048 = 0x00000700,
- Acrc = 0x00010000, /* Append CRC (not) */
- LbkSHIFT = 17, /* Loopback Test */
- LbkMASK = 0x00060000,
- Rtl8139ArevG = 0x00800000, /* RTL8139A Rev. G ID */
- IfgSHIFT = 24, /* Interframe Gap */
- IfgMASK = 0x03000000,
- HwveridSHIFT = 26, /* Hardware Version ID */
- HwveridMASK = 0x7C000000,
-};
-
-enum { /* Rcr */
- Aap = 0x00000001, /* Accept All Packets */
- Apm = 0x00000002, /* Accept Physical Match */
- Am = 0x00000004, /* Accept Multicast */
- Ab = 0x00000008, /* Accept Broadcast */
- Ar = 0x00000010, /* Accept Runt */
- Aer = 0x00000020, /* Accept Error */
- Sel9356 = 0x00000040, /* 9356 EEPROM used */
- Wrap = 0x00000080, /* Rx Buffer Wrap Control */
- MrxdmaSHIFT = 8, /* Max. DMA Burst Size */
- MrxdmaMASK = 0x00000700,
- Mrxdmaunlimited = 0x00000700,
- RblenSHIFT = 11, /* Receive Buffer Length */
- RblenMASK = 0x00001800,
- Rblen8K = 0x00000000, /* 8KB+16 */
- Rblen16K = 0x00000800, /* 16KB+16 */
- Rblen32K = 0x00001000, /* 32KB+16 */
- Rblen64K = 0x00001800, /* 64KB+16 */
- RxfthSHIFT = 13, /* Receive Buffer Length */
- RxfthMASK = 0x0000E000,
- Rxfth256 = 0x00008000,
- Rxfthnone = 0x0000E000,
- Rer8 = 0x00010000, /* Accept Error Packets > 8 bytes */
- MulERINT = 0x00020000, /* Multiple Early Interrupt Select */
- ErxthSHIFT = 24, /* Early Rx Threshold */
- ErxthMASK = 0x0F000000,
- Erxthnone = 0x00000000,
-};
-
-enum { /* Received Packet Status */
- Rcok = 0x0001, /* Receive Completed OK */
- Fae = 0x0002, /* Frame Alignment Error */
- Crc = 0x0004, /* CRC Error */
- Long = 0x0008, /* Long Packet */
- Runt = 0x0010, /* Runt Packet Received */
- Ise = 0x0020, /* Invalid Symbol Error */
- Bar = 0x2000, /* Broadcast Address Received */
- Pam = 0x4000, /* Physical Address Matched */
- Mar = 0x8000, /* Multicast Address Received */
-};
-
-enum { /* Media Status Register */
- Rxpf = 0x01, /* Pause Flag */
- Txpf = 0x02, /* Pause Flag */
- Linkb = 0x04, /* Inverse of Link Status */
- Speed10 = 0x08, /* 10Mbps */
- Auxstatus = 0x10, /* Aux. Power Present Status */
- Rxfce = 0x40, /* Receive Flow Control Enable */
- Txfce = 0x80, /* Transmit Flow Control Enable */
-};
-
-typedef struct Td Td;
-struct Td { /* Soft Transmit Descriptor */
- int tsd;
- int tsad;
- uchar* data;
- Block* bp;
-};
-
-enum { /* Tsd0 */
- SizeSHIFT = 0, /* Descriptor Size */
- SizeMASK = 0x00001FFF,
- Own = 0x00002000,
- Tun = 0x00004000, /* Transmit FIFO Underrun */
- Tcok = 0x00008000, /* Transmit COmpleted OK */
- EtxthSHIFT = 16, /* Early Tx Threshold */
- EtxthMASK = 0x001F0000,
- NccSHIFT = 24, /* Number of Collisions Count */
- NccMASK = 0x0F000000,
- Cdh = 0x10000000, /* CD Heartbeat */
- Owc = 0x20000000, /* Out of Window Collision */
- Tabt = 0x40000000, /* Transmit Abort */
- Crs = 0x80000000, /* Carrier Sense Lost */
-};
-
-enum {
- Rblen = Rblen64K, /* Receive Buffer Length */
- Ntd = 4, /* Number of Transmit Descriptors */
- Tdbsz = ROUNDUP(sizeof(Etherpkt), 4),
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
- int id;
-
- QLock alock; /* attach */
- Lock ilock; /* init */
- void* alloc; /* base of per-Ctlr allocated data */
-
- int rcr; /* receive configuration register */
- uchar* rbstart; /* receive buffer */
- int rblen; /* receive buffer length */
- int ierrs; /* receive errors */
-
- Lock tlock; /* transmit */
- Td td[Ntd];
- int ntd; /* descriptors active */
- int tdh; /* host index into td */
- int tdi; /* interface index into td */
- int etxth; /* early transmit threshold */
- int taligned; /* packet required no alignment */
- int tunaligned; /* packet required alignment */
-
- int dis; /* disconnect counter */
- int fcsc; /* false carrier sense counter */
- int rec; /* RX_ER counter */
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-#define csr8r(c, r) (inb((c)->port+(r)))
-#define csr16r(c, r) (ins((c)->port+(r)))
-#define csr32r(c, r) (inl((c)->port+(r)))
-#define csr8w(c, r, b) (outb((c)->port+(r), (int)(b)))
-#define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
-#define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
-
-static void
-rtl8139promiscuous(void* arg, int on)
-{
- Ether *edev;
- Ctlr * ctlr;
-
- edev = arg;
- ctlr = edev->ctlr;
- ilock(&ctlr->ilock);
-
- if(on)
- ctlr->rcr |= Aap;
- else
- ctlr->rcr &= ~Aap;
- csr32w(ctlr, Rcr, ctlr->rcr);
- iunlock(&ctlr->ilock);
-}
-
-static void
-rtl8139multicast(void* arg, uchar*, int)
-{
- rtl8139promiscuous(arg, 1);
-}
-
-static long
-rtl8139ifstat(Ether* edev, void* a, long n, ulong offset)
-{
- int l;
- char *p;
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
- p = malloc(READSTR);
- l = snprint(p, READSTR, "rcr %#8.8ux\n", ctlr->rcr);
- l += snprint(p+l, READSTR-l, "ierrs %d\n", ctlr->ierrs);
- l += snprint(p+l, READSTR-l, "etxth %d\n", ctlr->etxth);
- l += snprint(p+l, READSTR-l, "taligned %d\n", ctlr->taligned);
- l += snprint(p+l, READSTR-l, "tunaligned %d\n", ctlr->tunaligned);
- ctlr->dis += csr16r(ctlr, Dis);
- l += snprint(p+l, READSTR-l, "dis %d\n", ctlr->dis);
- ctlr->fcsc += csr16r(ctlr, Fcsc);
- l += snprint(p+l, READSTR-l, "fcscnt %d\n", ctlr->fcsc);
- ctlr->rec += csr16r(ctlr, Rec);
- l += snprint(p+l, READSTR-l, "rec %d\n", ctlr->rec);
-
- l += snprint(p+l, READSTR-l, "Tcr %#8.8lux\n", csr32r(ctlr, Tcr));
- l += snprint(p+l, READSTR-l, "Config0 %#2.2ux\n", csr8r(ctlr, Config0));
- l += snprint(p+l, READSTR-l, "Config1 %#2.2ux\n", csr8r(ctlr, Config1));
- l += snprint(p+l, READSTR-l, "Msr %#2.2ux\n", csr8r(ctlr, Msr));
- l += snprint(p+l, READSTR-l, "Config3 %#2.2ux\n", csr8r(ctlr, Config3));
- l += snprint(p+l, READSTR-l, "Config4 %#2.2ux\n", csr8r(ctlr, Config4));
-
- l += snprint(p+l, READSTR-l, "Bmcr %#4.4ux\n", csr16r(ctlr, Bmcr));
- l += snprint(p+l, READSTR-l, "Bmsr %#4.4ux\n", csr16r(ctlr, Bmsr));
- l += snprint(p+l, READSTR-l, "Anar %#4.4ux\n", csr16r(ctlr, Anar));
- l += snprint(p+l, READSTR-l, "Anlpar %#4.4ux\n", csr16r(ctlr, Anlpar));
- l += snprint(p+l, READSTR-l, "Aner %#4.4ux\n", csr16r(ctlr, Aner));
- l += snprint(p+l, READSTR-l, "Nwaytr %#4.4ux\n", csr16r(ctlr, Nwaytr));
- snprint(p+l, READSTR-l, "Cscr %#4.4ux\n", csr16r(ctlr, Cscr));
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static int
-rtl8139reset(Ctlr* ctlr)
-{
- int timeo;
-
- /*
- * Soft reset the controller.
- */
- csr8w(ctlr, Cr, Rst);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr8r(ctlr, Cr) & Rst))
- return 0;
- delay(1);
- }
-
- return -1;
-}
-
-static void
-rtl8139halt(Ctlr* ctlr)
-{
- int i;
-
- csr8w(ctlr, Cr, 0);
- csr16w(ctlr, Imr, 0);
- csr16w(ctlr, Isr, ~0);
-
- for(i = 0; i < Ntd; i++){
- if(ctlr->td[i].bp == nil)
- continue;
- freeb(ctlr->td[i].bp);
- ctlr->td[i].bp = nil;
- }
-}
-
-static void
-rtl8139init(Ether* edev)
-{
- int i;
- ulong r;
- Ctlr *ctlr;
- uchar *alloc;
-
- ctlr = edev->ctlr;
- ilock(&ctlr->ilock);
-
- rtl8139halt(ctlr);
-
- /*
- * MAC Address.
- */
- r = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
- csr32w(ctlr, Idr0, r);
- r = (edev->ea[5]<<8)|edev->ea[4];
- csr32w(ctlr, Idr0+4, r);
-
- /*
- * Receiver
- */
- alloc = (uchar*)ROUNDUP((ulong)ctlr->alloc, 32);
- ctlr->rbstart = alloc;
- alloc += ctlr->rblen+16;
- memset(ctlr->rbstart, 0, ctlr->rblen+16);
- csr32w(ctlr, Rbstart, PCIWADDR(ctlr->rbstart));
- ctlr->rcr = Rxfth256|Rblen|Mrxdmaunlimited|Ab|Apm;
-
- /*
- * Transmitter.
- */
- for(i = 0; i < Ntd; i++){
- ctlr->td[i].tsd = Tsd0+i*4;
- ctlr->td[i].tsad = Tsad0+i*4;
- ctlr->td[i].data = alloc;
- alloc += Tdbsz;
- ctlr->td[i].bp = nil;
- }
- ctlr->ntd = ctlr->tdh = ctlr->tdi = 0;
- ctlr->etxth = 128/32;
-
- /*
- * Interrupts.
- */
- csr32w(ctlr, TimerInt, 0);
- csr16w(ctlr, Imr, Serr|Timerbit|Fovw|PunLc|Rxovw|Ter|Tok|Rer|Rok);
- csr32w(ctlr, Mpc, 0);
-
- /*
- * Enable receiver/transmitter.
- * Need to enable before writing the Rcr or it won't take.
- */
- csr8w(ctlr, Cr, Te|Re);
- csr32w(ctlr, Tcr, Mtxdma2048);
- csr32w(ctlr, Rcr, ctlr->rcr);
-
- iunlock(&ctlr->ilock);
-}
-
-static void
-rtl8139attach(Ether* edev)
-{
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
- qlock(&ctlr->alock);
- if(ctlr->alloc == nil){
- ctlr->rblen = 1<<((Rblen>>RblenSHIFT)+13);
- ctlr->alloc = mallocz(ctlr->rblen+16 + Ntd*Tdbsz + 32, 0);
- rtl8139init(edev);
- }
- qunlock(&ctlr->alock);
-}
-
-static void
-rtl8139txstart(Ether* edev)
-{
- Td *td;
- int size;
- Block *bp;
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
- while(ctlr->ntd < Ntd){
- bp = qget(edev->oq);
- if(bp == nil)
- break;
- size = BLEN(bp);
-
- td = &ctlr->td[ctlr->tdh];
- if(((int)bp->rp) & 0x03){
- memmove(td->data, bp->rp, size);
- freeb(bp);
- csr32w(ctlr, td->tsad, PCIWADDR(td->data));
- ctlr->tunaligned++;
- }
- else{
- td->bp = bp;
- csr32w(ctlr, td->tsad, PCIWADDR(bp->rp));
- ctlr->taligned++;
- }
- csr32w(ctlr, td->tsd, (ctlr->etxth<<EtxthSHIFT)|size);
-
- ctlr->ntd++;
- ctlr->tdh = NEXT(ctlr->tdh, Ntd);
- }
-}
-
-static void
-rtl8139transmit(Ether* edev)
-{
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
- ilock(&ctlr->tlock);
- rtl8139txstart(edev);
- iunlock(&ctlr->tlock);
-}
-
-static void
-rtl8139receive(Ether* edev)
-{
- Block *bp;
- Ctlr *ctlr;
- ushort capr;
- uchar cr, *p;
- int l, length, status;
-
- ctlr = edev->ctlr;
-
- /*
- * Capr is where the host is reading from,
- * Cbr is where the NIC is currently writing.
- */
- capr = (csr16r(ctlr, Capr)+16) % ctlr->rblen;
- while(!(csr8r(ctlr, Cr) & Bufe)){
- p = ctlr->rbstart+capr;
-
- /*
- * Apparently the packet length may be 0xFFF0 if
- * the NIC is still copying the packet into memory.
- */
- length = (*(p+3)<<8)|*(p+2);
- if(length == 0xFFF0)
- break;
- status = (*(p+1)<<8)|*p;
-
- if(!(status & Rcok)){
- if(status & (Ise|Fae))
- edev->frames++;
- if(status & Crc)
- edev->crcs++;
- if(status & (Runt|Long))
- edev->buffs++;
-
- /*
- * Reset the receiver.
- * Also may have to restore the multicast list
- * here too if it ever gets used.
- */
- cr = csr8r(ctlr, Cr);
- csr8w(ctlr, Cr, cr & ~Re);
- csr32w(ctlr, Rbstart, PCIWADDR(ctlr->rbstart));
- csr8w(ctlr, Cr, cr);
- csr32w(ctlr, Rcr, ctlr->rcr);
-
- continue;
- }
-
- /*
- * Receive Completed OK.
- * Very simplistic; there are ways this could be done
- * without copying, but the juice probably isn't worth
- * the squeeze.
- * The packet length includes a 4 byte CRC on the end.
- */
- capr = (capr+4) % ctlr->rblen;
- p = ctlr->rbstart+capr;
- capr = (capr+length) % ctlr->rblen;
-
- if((bp = iallocb(length)) != nil){
- if(p+length >= ctlr->rbstart+ctlr->rblen){
- l = ctlr->rbstart+ctlr->rblen - p;
- memmove(bp->wp, p, l);
- bp->wp += l;
- length -= l;
- p = ctlr->rbstart;
- }
- if(length > 0){
- memmove(bp->wp, p, length);
- bp->wp += length;
- }
- bp->wp -= 4;
- etheriq(edev, bp, 1);
- }
-
- capr = ROUNDUP(capr, 4);
- csr16w(ctlr, Capr, capr-16);
- }
-}
-
-static void
-rtl8139interrupt(Ureg*, void* arg)
-{
- Td *td;
- Ctlr *ctlr;
- Ether *edev;
- int isr, msr, tsd;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- while((isr = csr16r(ctlr, Isr)) != 0){
- csr16w(ctlr, Isr, isr);
- if(isr & (Fovw|PunLc|Rxovw|Rer|Rok)){
- rtl8139receive(edev);
- if(!(isr & Rok))
- ctlr->ierrs++;
- isr &= ~(Fovw|Rxovw|Rer|Rok);
- }
-
- if(isr & (Ter|Tok)){
- ilock(&ctlr->tlock);
- while(ctlr->ntd){
- td = &ctlr->td[ctlr->tdi];
- tsd = csr32r(ctlr, td->tsd);
- if(!(tsd & (Tabt|Tun|Tcok)))
- break;
-
- if(!(tsd & Tcok)){
- if(tsd & Tun){
- if(ctlr->etxth < ETHERMAXTU/32)
- ctlr->etxth++;
- }
- edev->oerrs++;
- }
-
- if(td->bp != nil){
- freeb(td->bp);
- td->bp = nil;
- }
-
- ctlr->ntd--;
- ctlr->tdi = NEXT(ctlr->tdi, Ntd);
- }
- rtl8139txstart(edev);
- iunlock(&ctlr->tlock);
- isr &= ~(Ter|Tok);
- }
-
- if(isr & PunLc){
- /*
- * Maybe the link changed - do we care very much?
- */
- msr = csr8r(ctlr, Msr);
- if(!(msr & Linkb)){
- if(!(msr & Speed10) && edev->mbps != 100){
- edev->mbps = 100;
- qsetlimit(edev->oq, 256*1024);
- }
- else if((msr & Speed10) && edev->mbps != 10){
- edev->mbps = 10;
- qsetlimit(edev->oq, 65*1024);
- }
- }
- isr &= ~(Clc|PunLc);
- }
-
- /*
- * Only Serr|Timerbit should be left by now.
- * Should anything be done to tidy up? TimerInt isn't
- * used so that can be cleared. A PCI bus error is indicated
- * by Serr, that's pretty serious; is there anyhing to do
- * other than try to reinitialise the chip?
- */
- if((isr & (Serr|Timerbit)) != 0){
- iprint("rtl8139interrupt: imr %#4.4ux isr %#4.4ux\n",
- csr16r(ctlr, Imr), isr);
- if(isr & Timerbit)
- csr32w(ctlr, TimerInt, 0);
- if(isr & Serr)
- rtl8139init(edev);
- }
- }
-}
-
-static Ctlr*
-rtl8139match(Ether* edev, int id)
-{
- Pcidev *p;
- Ctlr *ctlr;
- int i, port;
-
- /*
- * Any adapter matches if no edev->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- p = ctlr->pcidev;
- if(((p->did<<16)|p->vid) != id)
- continue;
- port = p->mem[0].bar & ~0x01;
- if(edev->port != 0 && edev->port != port)
- continue;
-
- if(ioalloc(port, p->mem[0].size, 0, "rtl8139") < 0){
- print("rtl8139: port %#ux in use\n", port);
- continue;
- }
-
- if(pcigetpms(p) > 0){
- pcisetpms(p, 0);
-
- for(i = 0; i < 6; i++)
- pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
- pcicfgw8(p, PciINTL, p->intl);
- pcicfgw8(p, PciLTR, p->ltr);
- pcicfgw8(p, PciCLS, p->cls);
- pcicfgw16(p, PciPCR, p->pcr);
- }
-
- ctlr->port = port;
- if(rtl8139reset(ctlr)) {
- iofree(port);
- continue;
- }
- pcisetbme(p);
-
- ctlr->active = 1;
- return ctlr;
- }
- return nil;
-}
-
-static struct {
- char* name;
- int id;
-} rtl8139pci[] = {
- { "rtl8139", (0x8139<<16)|0x10EC, }, /* generic */
- { "smc1211", (0x1211<<16)|0x1113, }, /* SMC EZ-Card */
- { "dfe-538tx", (0x1300<<16)|0x1186, }, /* D-Link DFE-538TX */
- { "dfe-560txd", (0x1340<<16)|0x1186, }, /* D-Link DFE-560TXD */
- { nil },
-};
-
-static int
-rtl8139pnp(Ether* edev)
-{
- int i, id;
- Pcidev *p;
- Ctlr *ctlr;
- uchar ea[Eaddrlen];
-
- /*
- * Make a list of all ethernet controllers
- * if not already done.
- */
- if(ctlrhead == nil){
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != 0x02 || p->ccru != 0)
- continue;
- ctlr = malloc(sizeof(Ctlr));
- ctlr->pcidev = p;
- ctlr->id = (p->did<<16)|p->vid;
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- }
- }
-
- /*
- * Is it an RTL8139 under a different name?
- * Normally a search is made through all the found controllers
- * for one which matches any of the known vid+did pairs.
- * If a vid+did pair is specified a search is made for that
- * specific controller only.
- */
- id = 0;
- for(i = 0; i < edev->nopt; i++){
- if(cistrncmp(edev->opt[i], "id=", 3) == 0)
- id = strtol(&edev->opt[i][3], nil, 0);
- }
-
- ctlr = nil;
- if(id != 0)
- ctlr = rtl8139match(edev, id);
- else for(i = 0; rtl8139pci[i].name; i++){
- if((ctlr = rtl8139match(edev, rtl8139pci[i].id)) != nil)
- break;
- }
- if(ctlr == nil)
- return -1;
-
- edev->ctlr = ctlr;
- edev->port = ctlr->port;
- edev->irq = ctlr->pcidev->intl;
- edev->tbdf = ctlr->pcidev->tbdf;
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the device and set in edev->ea.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, edev->ea, Eaddrlen) == 0){
- i = csr32r(ctlr, Idr0);
- edev->ea[0] = i;
- edev->ea[1] = i>>8;
- edev->ea[2] = i>>16;
- edev->ea[3] = i>>24;
- i = csr32r(ctlr, Idr0+4);
- edev->ea[4] = i;
- edev->ea[5] = i>>8;
- }
-
- edev->attach = rtl8139attach;
- edev->transmit = rtl8139transmit;
- edev->interrupt = rtl8139interrupt;
- edev->ifstat = rtl8139ifstat;
-
- edev->arg = edev;
- edev->promiscuous = rtl8139promiscuous;
- edev->multicast = rtl8139multicast;
-// edev->shutdown = rtl8139shutdown;
-
- /*
- * This should be much more dynamic but will do for now.
- */
- if((csr8r(ctlr, Msr) & (Speed10|Linkb)) == 0)
- edev->mbps = 100;
-
- return 0;
-}
-
-void
-ether8139link(void)
-{
- addethercard("rtl8139", rtl8139pnp);
-}
diff --git a/os/pc/ether82543gc.c b/os/pc/ether82543gc.c
deleted file mode 100644
index 86ec7b75..00000000
--- a/os/pc/ether82543gc.c
+++ /dev/null
@@ -1,1367 +0,0 @@
-/*
- * Intel RS-82543GC Gigabit Ethernet Controller
- * as found on the Intel PRO/1000[FT] Server Adapter.
- * The older non-[FT] cards use the 82542 (LSI L2A1157) chip; no attempt
- * is made to handle the older chip although it should be possible.
- * The datasheet is not very clear about running on a big-endian system
- * and this driver assumes little-endian throughout.
- * To do:
- * GMII/MII
- * receive tuning
- * transmit tuning
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-enum {
- Ctrl = 0x00000000, /* Device Control */
- Status = 0x00000008, /* Device Status */
- Eecd = 0x00000010, /* EEPROM/Flash Control/Data */
- Ctrlext = 0x00000018, /* Extended Device Control */
- Mdic = 0x00000020, /* MDI Control */
- Fcal = 0x00000028, /* Flow Control Address Low */
- Fcah = 0x0000002C, /* Flow Control Address High */
- Fct = 0x00000030, /* Flow Control Type */
- Icr = 0x000000C0, /* Interrupt Cause Read */
- Ics = 0x000000C8, /* Interrupt Cause Set */
- Ims = 0x000000D0, /* Interrupt Mask Set/Read */
- Imc = 0x000000D8, /* Interrupt mask Clear */
- Rctl = 0x00000100, /* Receive Control */
- Fcttv = 0x00000170, /* Flow Control Transmit Timer Value */
- Txcw = 0x00000178, /* Transmit configuration word reg. */
- Rxcw = 0x00000180, /* Receive configuration word reg. */
- Tctl = 0x00000400, /* Transmit Control */
- Tipg = 0x00000410, /* Transmit IPG */
- Tbt = 0x00000448, /* Transmit Burst Timer */
- Ait = 0x00000458, /* Adaptive IFS Throttle */
- Fcrtl = 0x00002160, /* Flow Control RX Threshold Low */
- Fcrth = 0x00002168, /* Flow Control Rx Threshold High */
- Rdfh = 0x00002410, /* Receive data fifo head */
- Rdft = 0x00002418, /* Receive data fifo tail */
- Rdfhs = 0x00002420, /* Receive data fifo head saved */
- Rdfts = 0x00002428, /* Receive data fifo tail saved */
- Rdfpc = 0x00002430, /* Receive data fifo packet count */
- Rdbal = 0x00002800, /* Rdesc Base Address Low */
- Rdbah = 0x00002804, /* Rdesc Base Address High */
- Rdlen = 0x00002808, /* Receive Descriptor Length */
- Rdh = 0x00002810, /* Receive Descriptor Head */
- Rdt = 0x00002818, /* Receive Descriptor Tail */
- Rdtr = 0x00002820, /* Receive Descriptor Timer Ring */
- Rxdctl = 0x00002828, /* Receive Descriptor Control */
- Txdmac = 0x00003000, /* Transfer DMA Control */
- Ett = 0x00003008, /* Early Transmit Control */
- Tdfh = 0x00003410, /* Transmit data fifo head */
- Tdft = 0x00003418, /* Transmit data fifo tail */
- Tdfhs = 0x00003420, /* Transmit data Fifo Head saved */
- Tdfts = 0x00003428, /* Transmit data fifo tail saved */
- Tdfpc = 0x00003430, /* Trasnmit data Fifo packet count */
- Tdbal = 0x00003800, /* Tdesc Base Address Low */
- Tdbah = 0x00003804, /* Tdesc Base Address High */
- Tdlen = 0x00003808, /* Transmit Descriptor Length */
- Tdh = 0x00003810, /* Transmit Descriptor Head */
- Tdt = 0x00003818, /* Transmit Descriptor Tail */
- Tidv = 0x00003820, /* Transmit Interrupt Delay Value */
- Txdctl = 0x00003828, /* Transmit Descriptor Control */
-
- Statistics = 0x00004000, /* Start of Statistics Area */
- Gorcl = 0x88/4, /* Good Octets Received Count */
- Gotcl = 0x90/4, /* Good Octets Transmitted Count */
- Torl = 0xC0/4, /* Total Octets Received */
- Totl = 0xC8/4, /* Total Octets Transmitted */
- Nstatistics = 64,
-
- Rxcsum = 0x00005000, /* Receive Checksum Control */
- Mta = 0x00005200, /* Multicast Table Array */
- Ral = 0x00005400, /* Receive Address Low */
- Rah = 0x00005404, /* Receive Address High */
-};
-
-enum { /* Ctrl */
- Bem = 0x00000002, /* Big Endian Mode */
- Prior = 0x00000004, /* Priority on the PCI bus */
- Lrst = 0x00000008, /* Link Reset */
- Asde = 0x00000020, /* Auto-Speed Detection Enable */
- Slu = 0x00000040, /* Set Link Up */
- Ilos = 0x00000080, /* Invert Loss of Signal (LOS) */
- Frcspd = 0x00000800, /* Force Speed */
- Frcdplx = 0x00001000, /* Force Duplex */
- Swdpinslo = 0x003C0000, /* Software Defined Pins - lo nibble */
- Swdpin0 = 0x00040000,
- Swdpin1 = 0x00080000,
- Swdpin2 = 0x00100000,
- Swdpin3 = 0x00200000,
- Swdpiolo = 0x03C00000, /* Software Defined I/O Pins */
- Swdpio0 = 0x00400000,
- Swdpio1 = 0x00800000,
- Swdpio2 = 0x01000000,
- Swdpio3 = 0x02000000,
- Devrst = 0x04000000, /* Device Reset */
- Rfce = 0x08000000, /* Receive Flow Control Enable */
- Tfce = 0x10000000, /* Transmit Flow Control Enable */
- Vme = 0x40000000, /* VLAN Mode Enable */
-};
-
-enum { /* Status */
- Lu = 0x00000002, /* Link Up */
- Tckok = 0x00000004, /* Transmit clock is running */
- Rbcok = 0x00000008, /* Receive clock is running */
- Txoff = 0x00000010, /* Transmission Paused */
- Tbimode = 0x00000020, /* TBI Mode Indication */
- SpeedMASK = 0x000000C0,
- Speed10 = 0x00000000, /* 10Mb/s */
- Speed100 = 0x00000040, /* 100Mb/s */
- Speed1000 = 0x00000080, /* 1000Mb/s */
- Mtxckok = 0x00000400, /* MTX clock is running */
- Pci66 = 0x00000800, /* PCI Bus speed indication */
- Bus64 = 0x00001000, /* PCI Bus width indication */
-};
-
-enum { /* Ctrl and Status */
- Fd = 0x00000001, /* Full-Duplex */
- AsdvMASK = 0x00000300,
- Asdv10 = 0x00000000, /* 10Mb/s */
- Asdv100 = 0x00000100, /* 100Mb/s */
- Asdv1000 = 0x00000200, /* 1000Mb/s */
-};
-
-enum { /* Eecd */
- Sk = 0x00000001, /* Clock input to the EEPROM */
- Cs = 0x00000002, /* Chip Select */
- Di = 0x00000004, /* Data Input to the EEPROM */
- Do = 0x00000008, /* Data Output from the EEPROM */
-};
-
-enum { /* Ctrlext */
- Gpien = 0x0000000F, /* General Purpose Interrupt Enables */
- Swdpinshi = 0x000000F0, /* Software Defined Pins - hi nibble */
- Swdpiohi = 0x00000F00, /* Software Defined Pins - I or O */
- Asdchk = 0x00001000, /* ASD Check */
- Eerst = 0x00002000, /* EEPROM Reset */
- Ips = 0x00004000, /* Invert Power State */
- Spdbyps = 0x00008000, /* Speed Select Bypass */
-};
-
-enum { /* EEPROM content offsets */
- Ea = 0x00, /* Ethernet Address */
- Cf = 0x03, /* Compatibility Field */
- Pba = 0x08, /* Printed Board Assembly number */
- Icw1 = 0x0A, /* Initialization Control Word 1 */
- Sid = 0x0B, /* Subsystem ID */
- Svid = 0x0C, /* Subsystem Vendor ID */
- Did = 0x0D, /* Device ID */
- Vid = 0x0E, /* Vendor ID */
- Icw2 = 0x0F, /* Initialization Control Word 2 */
-};
-
-enum { /* Mdic */
- MDIdMASK = 0x0000FFFF, /* Data */
- MDIdSHIFT = 0,
- MDIrMASK = 0x001F0000, /* PHY Register Address */
- MDIrSHIFT = 16,
- MDIpMASK = 0x03E00000, /* PHY Address */
- MDIpSHIFT = 21,
- MDIwop = 0x04000000, /* Write Operation */
- MDIrop = 0x08000000, /* Read Operation */
- MDIready = 0x10000000, /* End of Transaction */
- MDIie = 0x20000000, /* Interrupt Enable */
- MDIe = 0x40000000, /* Error */
-};
-
-enum { /* Icr, Ics, Ims, Imc */
- Txdw = 0x00000001, /* Transmit Descriptor Written Back */
- Txqe = 0x00000002, /* Transmit Queue Empty */
- Lsc = 0x00000004, /* Link Status Change */
- Rxseq = 0x00000008, /* Receive Sequence Error */
- Rxdmt0 = 0x00000010, /* Rdesc Minimum Threshold Reached */
- Rxo = 0x00000040, /* Receiver Overrun */
- Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
- Mdac = 0x00000200, /* MDIO Access Completed */
- Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
- Gpi0 = 0x00000800, /* General Purpose Interrupts */
- Gpi1 = 0x00001000,
- Gpi2 = 0x00002000,
- Gpi3 = 0x00004000,
-};
-
-enum { /* Txcw */
- Ane = 0x80000000, /* Autonegotiate enable */
- Np = 0x00008000, /* Next Page */
- As = 0x00000100, /* Asymmetric Flow control desired */
- Ps = 0x00000080, /* Pause supported */
- Hd = 0x00000040, /* Half duplex supported */
- TxcwFd = 0x00000020, /* Full Duplex supported */
-};
-
-enum { /* Rxcw */
- Rxword = 0x0000FFFF, /* Data from auto-negotiation process */
- Rxnocarrier = 0x04000000, /* Carrier Sense indication */
- Rxinvalid = 0x08000000, /* Invalid Symbol during configuration */
- Rxchange = 0x10000000, /* Change to the Rxword indication */
- Rxconfig = 0x20000000, /* /C/ order set reception indication */
- Rxsync = 0x40000000, /* Lost bit synchronization indication */
- Anc = 0x80000000, /* Auto Negotiation Complete */
-};
-
-enum { /* Rctl */
- Rrst = 0x00000001, /* Receiver Software Reset */
- Ren = 0x00000002, /* Receiver Enable */
- Sbp = 0x00000004, /* Store Bad Packets */
- Upe = 0x00000008, /* Unicast Promiscuous Enable */
- Mpe = 0x00000010, /* Multicast Promiscuous Enable */
- Lpe = 0x00000020, /* Long Packet Reception Enable */
- LbmMASK = 0x000000C0, /* Loopback Mode */
- LbmOFF = 0x00000000, /* No Loopback */
- LbmTBI = 0x00000040, /* TBI Loopback */
- LbmMII = 0x00000080, /* GMII/MII Loopback */
- LbmXCVR = 0x000000C0, /* Transceiver Loopback */
- RdtmsMASK = 0x00000300, /* Rdesc Minimum Threshold Size */
- RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
- RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
- RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
- MoMASK = 0x00003000, /* Multicast Offset */
- Bam = 0x00008000, /* Broadcast Accept Mode */
- BsizeMASK = 0x00030000, /* Receive Buffer Size */
- Bsize2048 = 0x00000000, /* Bsex = 0 */
- Bsize1024 = 0x00010000, /* Bsex = 0 */
- Bsize512 = 0x00020000, /* Bsex = 0 */
- Bsize256 = 0x00030000, /* Bsex = 0 */
- Bsize16384 = 0x00010000, /* Bsex = 1 */
- Vfe = 0x00040000, /* VLAN Filter Enable */
- Cfien = 0x00080000, /* Canonical Form Indicator Enable */
- Cfi = 0x00100000, /* Canonical Form Indicator value */
- Dpf = 0x00400000, /* Discard Pause Frames */
- Pmcf = 0x00800000, /* Pass MAC Control Frames */
- Bsex = 0x02000000, /* Buffer Size Extension */
- Secrc = 0x04000000, /* Strip CRC from incoming packet */
-};
-
-enum { /* Tctl */
- Trst = 0x00000001, /* Transmitter Software Reset */
- Ten = 0x00000002, /* Transmit Enable */
- Psp = 0x00000008, /* Pad Short Packets */
- CtMASK = 0x00000FF0, /* Collision Threshold */
- CtSHIFT = 4,
- ColdMASK = 0x003FF000, /* Collision Distance */
- ColdSHIFT = 12,
- Swxoff = 0x00400000, /* Sofware XOFF Transmission */
- Pbe = 0x00800000, /* Packet Burst Enable */
- Rtlc = 0x01000000, /* Re-transmit on Late Collision */
- Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
-};
-
-enum { /* [RT]xdctl */
- PthreshMASK = 0x0000003F, /* Prefetch Threshold */
- PthreshSHIFT = 0,
- HthreshMASK = 0x00003F00, /* Host Threshold */
- HthreshSHIFT = 8,
- WthreshMASK = 0x003F0000, /* Writeback Threshold */
- WthreshSHIFT = 16,
- Gran = 0x00000000, /* Granularity */
- RxGran = 0x01000000, /* Granularity */
-};
-
-enum { /* Rxcsum */
- PcssMASK = 0x000000FF, /* Packet Checksum Start */
- PcssSHIFT = 0,
- Ipofl = 0x00000100, /* IP Checksum Off-load Enable */
- Tuofl = 0x00000200, /* TCP/UDP Checksum Off-load Enable */
-};
-
-enum { /* Receive Delay Timer Ring */
- Fpd = 0x80000000, /* Flush partial Descriptor Block */
-};
-
-typedef struct Rdesc { /* Receive Descriptor */
- uint addr[2];
- ushort length;
- ushort checksum;
- uchar status;
- uchar errors;
- ushort special;
-} Rdesc;
-
-enum { /* Rdesc status */
- Rdd = 0x01, /* Descriptor Done */
- Reop = 0x02, /* End of Packet */
- Ixsm = 0x04, /* Ignore Checksum Indication */
- Vp = 0x08, /* Packet is 802.1Q (matched VET) */
- Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
- Ipcs = 0x40, /* IP Checksum Calculated on Packet */
- Pif = 0x80, /* Passed in-exact filter */
-};
-
-enum { /* Rdesc errors */
- Ce = 0x01, /* CRC Error or Alignment Error */
- Se = 0x02, /* Symbol Error */
- Seq = 0x04, /* Sequence Error */
- Cxe = 0x10, /* Carrier Extension Error */
- Tcpe = 0x20, /* TCP/UDP Checksum Error */
- Ipe = 0x40, /* IP Checksum Error */
- Rxe = 0x80, /* RX Data Error */
-};
-
-typedef struct Tdesc { /* Legacy+Normal Transmit Descriptor */
- uint addr[2];
- uint control; /* varies with descriptor type */
- uint status; /* varies with descriptor type */
-} Tdesc;
-
-enum { /* Tdesc control */
- CsoMASK = 0x00000F00, /* Checksum Offset */
- CsoSHIFT = 16,
- Teop = 0x01000000, /* End of Packet */
- Ifcs = 0x02000000, /* Insert FCS */
- Ic = 0x04000000, /* Insert Checksum (Dext == 0) */
- Tse = 0x04000000, /* TCP Segmentaion Enable (Dext == 1) */
- Rs = 0x08000000, /* Report Status */
- Rps = 0x10000000, /* Report Status Sent */
- Dext = 0x20000000, /* Extension (!legacy) */
- Vle = 0x40000000, /* VLAN Packet Enable */
- Ide = 0x80000000, /* Interrupt Delay Enable */
-};
-
-enum { /* Tdesc status */
- Tdd = 0x00000001, /* Descriptor Done */
- Ec = 0x00000002, /* Excess Collisions */
- Lc = 0x00000004, /* Late Collision */
- Tu = 0x00000008, /* Transmit Underrun */
- CssMASK = 0x0000FF00, /* Checksum Start Field */
- CssSHIFT = 8,
-};
-
-enum {
- Nrdesc = 256, /* multiple of 8 */
- Ntdesc = 256, /* multiple of 8 */
- Nblocks = 4098, /* total number of blocks to use */
-
- SBLOCKSIZE = 2048,
- JBLOCKSIZE = 16384,
-
- NORMAL = 1,
- JUMBO = 2,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
- int started;
- int id;
- ushort eeprom[0x40];
-
- int* nic;
- int im; /* interrupt mask */
-
- Lock slock;
- uint statistics[Nstatistics];
-
- Lock rdlock;
- Rdesc* rdba; /* receive descriptor base address */
- Block* rb[Nrdesc]; /* receive buffers */
- int rdh; /* receive descriptor head */
- int rdt; /* receive descriptor tail */
- Block** freehead; /* points to long or short head */
-
- Lock tdlock;
- Tdesc* tdba; /* transmit descriptor base address */
- Block* tb[Ntdesc]; /* transmit buffers */
- int tdh; /* transmit descriptor head */
- int tdt; /* transmit descriptor tail */
- int txstalled; /* count of times unable to send */
-
- int txcw;
- int fcrtl;
- int fcrth;
-
- ulong multimask[128]; /* bit mask for multicast addresses */
-} Ctlr;
-
-static Ctlr* gc82543ctlrhead;
-static Ctlr* gc82543ctlrtail;
-
-static Lock freelistlock;
-static Block* freeShortHead;
-static Block* freeJumboHead;
-
-#define csr32r(c, r) (*((c)->nic+((r)/4)))
-#define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
-
-static void gc82543watchdog(void* arg);
-
-static void
-gc82543attach(Ether* edev)
-{
- int ctl;
- Ctlr *ctlr;
- char name[KNAMELEN];
-
- /*
- * To do here:
- * one-time stuff;
- * adjust queue length depending on speed;
- * flow control.
- * more needed here...
- */
- ctlr = edev->ctlr;
- lock(&ctlr->slock);
- if(ctlr->started == 0){
- ctlr->started = 1;
- snprint(name, KNAMELEN, "#l%d82543", edev->ctlrno);
- kproc(name, gc82543watchdog, edev, 0);
- }
- unlock(&ctlr->slock);
-
- ctl = csr32r(ctlr, Rctl)|Ren;
- csr32w(ctlr, Rctl, ctl);
- ctl = csr32r(ctlr, Tctl)|Ten;
- csr32w(ctlr, Tctl, ctl);
-
- csr32w(ctlr, Ims, ctlr->im);
-}
-
-static char* statistics[Nstatistics] = {
- "CRC Error",
- "Alignment Error",
- "Symbol Error",
- "RX Error",
- "Missed Packets",
- "Single Collision",
- "Excessive Collisions",
- "Multiple Collision",
- "Late Collisions",
- nil,
- "Collision",
- "Transmit Underrun",
- "Defer",
- "Transmit - No CRS",
- "Sequence Error",
- "Carrier Extension Error",
- "Receive Error Length",
- nil,
- "XON Received",
- "XON Transmitted",
- "XOFF Received",
- "XOFF Transmitted",
- "FC Received Unsupported",
- "Packets Received (64 Bytes)",
- "Packets Received (65-127 Bytes)",
- "Packets Received (128-255 Bytes)",
- "Packets Received (256-511 Bytes)",
- "Packets Received (512-1023 Bytes)",
- "Packets Received (1024-1522 Bytes)",
- "Good Packets Received",
- "Broadcast Packets Received",
- "Multicast Packets Received",
- "Good Packets Transmitted",
- nil,
- "Good Octets Received",
- nil,
- "Good Octets Transmitted",
- nil,
- nil,
- nil,
- "Receive No Buffers",
- "Receive Undersize",
- "Receive Fragment",
- "Receive Oversize",
- "Receive Jabber",
- nil,
- nil,
- nil,
- "Total Octets Received",
- nil,
- "Total Octets Transmitted",
- nil,
- "Total Packets Received",
- "Total Packets Transmitted",
- "Packets Transmitted (64 Bytes)",
- "Packets Transmitted (65-127 Bytes)",
- "Packets Transmitted (128-255 Bytes)",
- "Packets Transmitted (256-511 Bytes)",
- "Packets Transmitted (512-1023 Bytes)",
- "Packets Transmitted (1024-1522 Bytes)",
- "Multicast Packets Transmitted",
- "Broadcast Packets Transmitted",
- "TCP Segmentation Context Transmitted",
- "TCP Segmentation Context Fail",
-};
-
-static long
-gc82543ifstat(Ether* edev, void* a, long n, ulong offset)
-{
- Ctlr *ctlr;
- char *p, *s;
- int i, l, r;
- uvlong tuvl, ruvl;
-
- ctlr = edev->ctlr;
- lock(&ctlr->slock);
- p = malloc(2*READSTR);
- l = 0;
- for(i = 0; i < Nstatistics; i++){
- r = csr32r(ctlr, Statistics+i*4);
- if((s = statistics[i]) == nil)
- continue;
- switch(i){
- case Gorcl:
- case Gotcl:
- case Torl:
- case Totl:
- ruvl = r;
- ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
- tuvl = ruvl;
- tuvl += ctlr->statistics[i];
- tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
- if(tuvl == 0)
- continue;
- ctlr->statistics[i] = tuvl;
- ctlr->statistics[i+1] = tuvl>>32;
- l += snprint(p+l, 2*READSTR-l, "%s: %llud %llud\n",
- s, tuvl, ruvl);
- i++;
- break;
-
- default:
- ctlr->statistics[i] += r;
- if(ctlr->statistics[i] == 0)
- continue;
- l += snprint(p+l, 2*READSTR-l, "%s: %ud %ud\n",
- s, ctlr->statistics[i], r);
- break;
- }
- }
-
- l += snprint(p+l, 2*READSTR-l, "eeprom:");
- for(i = 0; i < 0x40; i++){
- if(i && ((i & 0x07) == 0))
- l += snprint(p+l, 2*READSTR-l, "\n ");
- l += snprint(p+l, 2*READSTR-l, " %4.4uX", ctlr->eeprom[i]);
- }
-
- snprint(p+l, 2*READSTR-l, "\ntxstalled %d\n", ctlr->txstalled);
- n = readstr(offset, a, n, p);
- free(p);
- unlock(&ctlr->slock);
-
- return n;
-}
-
-static void
-gc82543promiscuous(void* arg, int on)
-{
- int rctl;
- Ctlr *ctlr;
- Ether *edev;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- rctl = csr32r(ctlr, Rctl);
- rctl &= ~MoMASK; /* make sure we're using bits 47:36 */
- if(on)
- rctl |= Upe|Mpe;
- else
- rctl &= ~(Upe|Mpe);
- csr32w(ctlr, Rctl, rctl);
-}
-
-static void
-gc82543multicast(void* arg, uchar* addr, int on)
-{
- int bit, x;
- Ctlr *ctlr;
- Ether *edev;
-
- edev = arg;
- ctlr = edev->ctlr;
- x = addr[5]>>1;
- bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
- if(on)
- ctlr->multimask[x] |= 1<<bit;
- else
- ctlr->multimask[x] &= ~(1<<bit);
-
- csr32w(ctlr, Mta+x*4, ctlr->multimask[x]);
-}
-
-static long
-gc82543ctl(Ether* edev, void* buf, long n)
-{
- Cmdbuf *cb;
- Ctlr *ctlr;
- int ctrl, i, r;
-
- ctlr = edev->ctlr;
- if(ctlr == nil)
- error(Enonexist);
-
- lock(&ctlr->slock);
- r = 0;
- cb = parsecmd(buf, n);
- if(cb->nf < 2)
- r = -1;
- else if(cistrcmp(cb->f[0], "auto") == 0){
- ctrl = csr32r(ctlr, Ctrl);
- if(cistrcmp(cb->f[1], "off") == 0){
- csr32w(ctlr, Txcw, ctlr->txcw & ~Ane);
- ctrl |= (Slu|Fd);
- if(ctlr->txcw & As)
- ctrl |= Rfce;
- if(ctlr->txcw & Ps)
- ctrl |= Tfce;
- csr32w(ctlr, Ctrl, ctrl);
- }
- else if(cistrcmp(cb->f[1], "on") == 0){
- csr32w(ctlr, Txcw, ctlr->txcw);
- ctrl &= ~(Slu|Fd);
- csr32w(ctlr, Ctrl, ctrl);
- }
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "clear") == 0){
- if(cistrcmp(cb->f[1], "stats") == 0){
- for(i = 0; i < Nstatistics; i++)
- ctlr->statistics[i] = 0;
- }
- else
- r = -1;
- }
- else
- r = -1;
- unlock(&ctlr->slock);
-
- free(cb);
- return (r == 0) ? n : r;
-}
-
-static void
-gc82543txinit(Ctlr* ctlr)
-{
- int i;
- int tdsize;
- Block *bp, **bpp;
-
- tdsize = ROUND(Ntdesc*sizeof(Tdesc), 4096);
-
- if(ctlr->tdba == nil)
- ctlr->tdba = xspanalloc(tdsize, 32, 0);
-
- for(i = 0; i < Ntdesc; i++){
- bpp = &ctlr->tb[i];
- bp = *bpp;
- if(bp != nil){
- *bpp = nil;
- freeb(bp);
- }
- memset(&ctlr->tdba[i], 0, sizeof(Tdesc));
- }
-
- csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
- csr32w(ctlr, Tdbah, 0);
- csr32w(ctlr, Tdlen, Ntdesc*sizeof(Tdesc));
-
- /*
- * set the ring head and tail pointers.
- */
- ctlr->tdh = 0;
- csr32w(ctlr, Tdh, ctlr->tdh);
- ctlr->tdt = 0;
- csr32w(ctlr, Tdt, ctlr->tdt);
-
- csr32w(ctlr, Tipg, (6<<20)|(8<<10)|6);
- csr32w(ctlr, Tidv, 128);
- csr32w(ctlr, Ait, 0);
- csr32w(ctlr, Txdmac, 0);
- csr32w(ctlr, Txdctl, Gran|(4<<WthreshSHIFT)|(1<<HthreshSHIFT)|16);
- csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(6<<ColdSHIFT));
-
- ctlr->im |= Txdw;
-}
-
-static void
-gc82543transmit(Ether* edev)
-{
- Block *bp, **bpp;
- Ctlr *ctlr;
- Tdesc *tdesc;
- int tdh, tdt, s;
-
- ctlr = edev->ctlr;
-
- ilock(&ctlr->tdlock);
- tdh = ctlr->tdh;
- for(;;){
- /*
- * Free any completed packets
- */
- tdesc = &ctlr->tdba[tdh];
- if(!(tdesc->status & Tdd))
- break;
- memset(tdesc, 0, sizeof(Tdesc));
- bpp = &ctlr->tb[tdh];
- bp = *bpp;
- if(bp != nil){
- *bpp = nil;
- freeb(bp);
- }
- tdh = NEXT(tdh, Ntdesc);
- }
- ctlr->tdh = tdh;
- s = csr32r(ctlr, Status);
-
- /*
- * Try to fill the ring back up
- * but only if link is up and transmission isn't paused.
- */
- if((s & (Txoff|Lu)) == Lu){
- tdt = ctlr->tdt;
- while(NEXT(tdt, Ntdesc) != tdh){
- if((bp = qget(edev->oq)) == nil)
- break;
-
- tdesc = &ctlr->tdba[tdt];
- tdesc->addr[0] = PCIWADDR(bp->rp);
- tdesc->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
- ctlr->tb[tdt] = bp;
- tdt = NEXT(tdt, Ntdesc);
- }
-
- if(tdt != ctlr->tdt){
- ctlr->tdt = tdt;
- csr32w(ctlr, Tdt, tdt);
- }
- }
- else
- ctlr->txstalled++;
-
- iunlock(&ctlr->tdlock);
-}
-
-static Block *
-gc82543allocb(Ctlr* ctlr)
-{
- Block *bp;
-
- ilock(&freelistlock);
- if((bp = *(ctlr->freehead)) != nil){
- *(ctlr->freehead) = bp->next;
- bp->next = nil;
- }
- iunlock(&freelistlock);
- return bp;
-}
-
-static void
-gc82543replenish(Ctlr* ctlr)
-{
- int rdt;
- Block *bp;
- Rdesc *rdesc;
-
- ilock(&ctlr->rdlock);
- rdt = ctlr->rdt;
- while(NEXT(rdt, Nrdesc) != ctlr->rdh){
- rdesc = &ctlr->rdba[rdt];
- if(ctlr->rb[rdt] == nil){
- bp = gc82543allocb(ctlr);
- if(bp == nil){
- iprint("no available buffers\n");
- break;
- }
- ctlr->rb[rdt] = bp;
- rdesc->addr[0] = PCIWADDR(bp->rp);
- rdesc->addr[1] = 0;
- }
- coherence();
- rdesc->status = 0;
- rdt = NEXT(rdt, Nrdesc);
- }
- ctlr->rdt = rdt;
- csr32w(ctlr, Rdt, rdt);
- iunlock(&ctlr->rdlock);
-}
-
-static void
-gc82543rxinit(Ctlr* ctlr)
-{
- int rdsize, i;
-
- csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
-
- /*
- * Allocate the descriptor ring and load its
- * address and length into the NIC.
- */
- rdsize = ROUND(Nrdesc*sizeof(Rdesc), 4096);
- if(ctlr->rdba == nil)
- ctlr->rdba = xspanalloc(rdsize, 32, 0);
- memset(ctlr->rdba, 0, rdsize);
-
- ctlr->rdh = 0;
- ctlr->rdt = 0;
-
- csr32w(ctlr, Rdtr, Fpd|64);
- csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
- csr32w(ctlr, Rdbah, 0);
- csr32w(ctlr, Rdlen, Nrdesc*sizeof(Rdesc));
- csr32w(ctlr, Rdh, 0);
- csr32w(ctlr, Rdt, 0);
- for(i = 0; i < Nrdesc; i++){
- if(ctlr->rb[i] != nil){
- freeb(ctlr->rb[i]);
- ctlr->rb[i] = nil;
- }
- }
- gc82543replenish(ctlr);
-
- csr32w(ctlr, Rxdctl, RxGran|(8<<WthreshSHIFT)|(4<<HthreshSHIFT)|1);
- ctlr->im |= Rxt0|Rxo|Rxdmt0|Rxseq;
-}
-
-static void
-gc82543recv(Ether* edev, int icr)
-{
- Block *bp;
- Ctlr *ctlr;
- Rdesc *rdesc;
- int rdh;
-
- ctlr = edev->ctlr;
-
- rdh = ctlr->rdh;
- for(;;){
- rdesc = &ctlr->rdba[rdh];
-
- if(!(rdesc->status & Rdd))
- break;
-
- if((rdesc->status & Reop) && rdesc->errors == 0){
- bp = ctlr->rb[rdh];
- ctlr->rb[rdh] = nil;
- bp->wp += rdesc->length;
- bp->next = nil;
- etheriq(edev, bp, 1);
- }
-
- if(ctlr->rb[rdh] != nil){
- /* either non eop packet, or error */
- freeb(ctlr->rb[rdh]);
- ctlr->rb[rdh] = nil;
- }
- memset(rdesc, 0, sizeof(Rdesc));
- coherence();
- rdh = NEXT(rdh, Nrdesc);
- }
- ctlr->rdh = rdh;
-
- if(icr & Rxdmt0)
- gc82543replenish(ctlr);
-}
-
-static void
-freegc82543short(Block *bp)
-{
- ilock(&freelistlock);
- /* reset read/write pointer to proper positions */
- bp->rp = bp->lim - ROUND(SBLOCKSIZE, BLOCKALIGN);
- bp->wp = bp->rp;
- bp->next = freeShortHead;
- freeShortHead = bp;
- iunlock(&freelistlock);
-}
-
-static void
-freegc82532jumbo(Block *bp)
-{
- ilock(&freelistlock);
- /* reset read/write pointer to proper positions */
- bp->rp = bp->lim - ROUND(JBLOCKSIZE, BLOCKALIGN);
- bp->wp = bp->rp;
- bp->next = freeJumboHead;
- freeJumboHead = bp;
- iunlock(&freelistlock);
-}
-
-static void
-linkintr(Ctlr* ctlr)
-{
- int ctrl;
-
- ctrl = csr32r(ctlr, Ctrl);
-
- if((ctrl & Swdpin1) ||
- ((csr32r(ctlr, Rxcw) & Rxconfig) && !(csr32r(ctlr, Txcw) & Ane))){
- csr32w(ctlr, Txcw, ctlr->txcw);
- ctrl &= ~(Slu|Fd|Frcdplx);
- csr32w(ctlr, Ctrl, ctrl);
- }
-}
-
-static void
-gc82543interrupt(Ureg*, void* arg)
-{
- Ctlr *ctlr;
- Ether *edev;
- int icr;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
- /*
- * Link status changed.
- */
- if(icr & (Lsc|Rxseq))
- linkintr(ctlr);
-
- /*
- * Process recv buffers.
- */
- gc82543recv(edev, icr);
-
- /*
- * Refill transmit ring and free packets.
- */
- gc82543transmit(edev);
- }
-}
-
-static int
-gc82543init(Ether* edev)
-{
- int csr, i;
- Block *bp;
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
-
- /*
- * Allocate private buffer pool to use for receiving packets.
- */
- ilock(&freelistlock);
- if (ctlr->freehead == nil){
- for(i = 0; i < Nblocks; i++){
- bp = iallocb(SBLOCKSIZE);
- if(bp != nil){
- bp->next = freeShortHead;
- bp->free = freegc82543short;
- freeShortHead = bp;
- }
- else{
- print("82543gc: no memory\n");
- break;
- }
- }
- ctlr->freehead = &freeShortHead;
- }
- iunlock(&freelistlock);
-
- /*
- * Set up the receive addresses.
- * There are 16 addresses. The first should be the MAC address.
- * The others are cleared and not marked valid (MS bit of Rah).
- */
- csr = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
- csr32w(ctlr, Ral, csr);
- csr = 0x80000000|(edev->ea[5]<<8)|edev->ea[4];
- csr32w(ctlr, Rah, csr);
- for(i = 1; i < 16; i++){
- csr32w(ctlr, Ral+i*8, 0);
- csr32w(ctlr, Rah+i*8, 0);
- }
-
- /*
- * Clear the Multicast Table Array.
- * It's a 4096 bit vector accessed as 128 32-bit registers.
- */
- for(i = 0; i < 128; i++)
- csr32w(ctlr, Mta+i*4, 0);
-
- gc82543txinit(ctlr);
- gc82543rxinit(ctlr);
-
- return 0;
-}
-
-static int
-at93c46io(Ctlr* ctlr, char* op, int data)
-{
- char *lp, *p;
- int i, loop, eecd, r;
-
- eecd = csr32r(ctlr, Eecd);
-
- r = 0;
- loop = -1;
- lp = nil;
- for(p = op; *p != '\0'; p++){
- switch(*p){
- default:
- return -1;
- case ' ':
- continue;
- case ':': /* start of loop */
- if(lp != nil){
- if(p != (lp+1) || loop != 7)
- return -1;
- lp = p;
- loop = 15;
- continue;
- }
- lp = p;
- loop = 7;
- continue;
- case ';': /* end of loop */
- if(lp == nil)
- return -1;
- loop--;
- if(loop >= 0)
- p = lp;
- else
- lp = nil;
- continue;
- case 'C': /* assert clock */
- eecd |= Sk;
- break;
- case 'c': /* deassert clock */
- eecd &= ~Sk;
- break;
- case 'D': /* next bit in 'data' byte */
- if(loop < 0)
- return -1;
- if(data & (1<<loop))
- eecd |= Di;
- else
- eecd &= ~Di;
- break;
- case 'O': /* collect data output */
- i = (csr32r(ctlr, Eecd) & Do) != 0;
- if(loop >= 0)
- r |= (i<<loop);
- else
- r = i;
- continue;
- case 'I': /* assert data input */
- eecd |= Di;
- break;
- case 'i': /* deassert data input */
- eecd &= ~Di;
- break;
- case 'S': /* enable chip select */
- eecd |= Cs;
- break;
- case 's': /* disable chip select */
- eecd &= ~Cs;
- break;
- }
- csr32w(ctlr, Eecd, eecd);
- microdelay(1);
- }
- if(loop >= 0)
- return -1;
- return r;
-}
-
-static int
-at93c46r(Ctlr* ctlr)
-{
- ushort sum;
- int addr, data;
-
- sum = 0;
- for(addr = 0; addr < 0x40; addr++){
- /*
- * Read a word at address 'addr' from the Atmel AT93C46
- * 3-Wire Serial EEPROM or compatible. The EEPROM access is
- * controlled by 4 bits in Eecd. See the AT93C46 datasheet
- * for protocol details.
- */
- if(at93c46io(ctlr, "S ICc :DCc;", (0x02<<6)|addr) != 0)
- break;
- data = at93c46io(ctlr, "::COc;", 0);
- at93c46io(ctlr, "sic", 0);
- ctlr->eeprom[addr] = data;
- sum += data;
- }
-
- return sum;
-}
-
-static void
-gc82543detach(Ctlr* ctlr)
-{
- /*
- * Perform a device reset to get the chip back to the
- * power-on state, followed by an EEPROM reset to read
- * the defaults for some internal registers.
- */
- csr32w(ctlr, Imc, ~0);
- csr32w(ctlr, Rctl, 0);
- csr32w(ctlr, Tctl, 0);
-
- delay(10);
-
- csr32w(ctlr, Ctrl, Devrst);
- while(csr32r(ctlr, Ctrl) & Devrst)
- ;
-
- csr32w(ctlr, Ctrlext, Eerst);
- while(csr32r(ctlr, Ctrlext) & Eerst)
- ;
-
- csr32w(ctlr, Imc, ~0);
- while(csr32r(ctlr, Icr))
- ;
-}
-
-static void
-gc82543checklink(Ctlr* ctlr)
-{
- int ctrl, status, rxcw;
-
- ctrl = csr32r(ctlr, Ctrl);
- status = csr32r(ctlr, Status);
- rxcw = csr32r(ctlr, Rxcw);
-
- if(!(status & Lu)){
- if(!(ctrl & (Swdpin1|Slu)) && !(rxcw & Rxconfig)){
- csr32w(ctlr, Txcw, ctlr->txcw & ~Ane);
- ctrl |= (Slu|Fd);
- if(ctlr->txcw & As)
- ctrl |= Rfce;
- if(ctlr->txcw & Ps)
- ctrl |= Tfce;
- csr32w(ctlr, Ctrl, ctrl);
- }
- }
- else if((ctrl & Slu) && (rxcw & Rxconfig)){
- csr32w(ctlr, Txcw, ctlr->txcw);
- ctrl &= ~(Slu|Fd);
- csr32w(ctlr, Ctrl, ctrl);
- }
-}
-
-static void
-gc82543shutdown(Ether* ether)
-{
- gc82543detach(ether->ctlr);
-}
-
-static int
-gc82543reset(Ctlr* ctlr)
-{
- int ctl;
- int te;
-
- /*
- * Read the EEPROM, validate the checksum
- * then get the device back to a power-on state.
- */
- if(at93c46r(ctlr) != 0xBABA)
- return -1;
-
- gc82543detach(ctlr);
-
- te = ctlr->eeprom[Icw2];
- if((te & 0x3000) == 0){
- ctlr->fcrtl = 0x00002000;
- ctlr->fcrth = 0x00004000;
- ctlr->txcw = Ane|TxcwFd;
- }
- else if((te & 0x3000) == 0x2000){
- ctlr->fcrtl = 0;
- ctlr->fcrth = 0;
- ctlr->txcw = Ane|TxcwFd|As;
- }
- else{
- ctlr->fcrtl = 0x00002000;
- ctlr->fcrth = 0x00004000;
- ctlr->txcw = Ane|TxcwFd|As|Ps;
- }
-
- csr32w(ctlr, Txcw, ctlr->txcw);
-
- csr32w(ctlr, Ctrlext, (te & 0x00f0)<<4);
-
- csr32w(ctlr, Tctl, csr32r(ctlr, Tctl)|(64<<ColdSHIFT));
-
- te = ctlr->eeprom[Icw1];
- ctl = ((te & 0x01E0)<<17)|(te & 0x0010)<<3;
- csr32w(ctlr, Ctrl, ctl);
-
- delay(10);
-
- /*
- * Flow control - values from the datasheet.
- */
- csr32w(ctlr, Fcal, 0x00C28001);
- csr32w(ctlr, Fcah, 0x00000100);
- csr32w(ctlr, Fct, 0x00008808);
- csr32w(ctlr, Fcttv, 0x00000100);
-
- csr32w(ctlr, Fcrtl, ctlr->fcrtl);
- csr32w(ctlr, Fcrth, ctlr->fcrth);
-
- ctlr->im = Lsc;
- gc82543checklink(ctlr);
-
- return 0;
-}
-
-static void
-gc82543watchdog(void* arg)
-{
- Ether *edev;
- Ctlr *ctlr;
-
- edev = arg;
- for(;;){
- tsleep(&up->sleep, return0, 0, 1000);
-
- ctlr = edev->ctlr;
- if(ctlr == nil){
- print("%s: exiting\n", up->text);
- pexit("disabled", 0);
- }
-
- gc82543checklink(ctlr);
- gc82543replenish(ctlr);
- }
-}
-
-static void
-gc82543pci(void)
-{
- int cls;
- void *mem;
- Pcidev *p;
- Ctlr *ctlr;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != 0x02 || p->ccru != 0)
- continue;
-
- switch((p->did<<16)|p->vid){
- case (0x1000<<16)|0x8086: /* LSI L2A1157 (82542) */
- case (0x1004<<16)|0x8086: /* Intel PRO/1000 T */
- case (0x1008<<16)|0x8086: /* Intel PRO/1000 XT */
- default:
- continue;
- case (0x1001<<16)|0x8086: /* Intel PRO/1000 F */
- break;
- }
-
- mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
- if(mem == 0){
- print("gc82543: can't map %8.8luX\n", p->mem[0].bar);
- continue;
- }
- cls = pcicfgr8(p, PciCLS);
- switch(cls){
- case 0x00:
- case 0xFF:
- print("82543gc: unusable cache line size\n");
- continue;
- case 0x08:
- break;
- default:
- print("82543gc: cache line size %d, expected 32\n",
- cls*4);
- }
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = p->mem[0].bar & ~0x0F;
- ctlr->pcidev = p;
- ctlr->id = (p->did<<16)|p->vid;
- ctlr->nic = mem;
-
- if(gc82543reset(ctlr)){
- free(ctlr);
- continue;
- }
-
- if(gc82543ctlrhead != nil)
- gc82543ctlrtail->next = ctlr;
- else
- gc82543ctlrhead = ctlr;
- gc82543ctlrtail = ctlr;
- }
-}
-
-static int
-gc82543pnp(Ether* edev)
-{
- int i;
- Ctlr *ctlr;
- uchar ea[Eaddrlen];
-
- if(gc82543ctlrhead == nil)
- gc82543pci();
-
- /*
- * Any adapter matches if no edev->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = gc82543ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(edev->port == 0 || edev->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- edev->ctlr = ctlr;
- edev->port = ctlr->port;
- edev->irq = ctlr->pcidev->intl;
- edev->tbdf = ctlr->pcidev->tbdf;
- edev->mbps = 1000;
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the EEPROM and set in ether->ea prior to
- * loading the station address in the hardware.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, edev->ea, Eaddrlen) == 0){
- for(i = Ea; i < Eaddrlen/2; i++){
- edev->ea[2*i] = ctlr->eeprom[i];
- edev->ea[2*i+1] = ctlr->eeprom[i]>>8;
- }
- }
- gc82543init(edev);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- edev->attach = gc82543attach;
- edev->transmit = gc82543transmit;
- edev->interrupt = gc82543interrupt;
- edev->ifstat = gc82543ifstat;
- edev->shutdown = gc82543shutdown;
- edev->ctl = gc82543ctl;
- edev->arg = edev;
- edev->promiscuous = gc82543promiscuous;
- edev->multicast = gc82543multicast;
-
- return 0;
-}
-
-void
-ether82543gclink(void)
-{
- addethercard("82543GC", gc82543pnp);
-}
diff --git a/os/pc/ether82557.c b/os/pc/ether82557.c
deleted file mode 100644
index 4dba07bd..00000000
--- a/os/pc/ether82557.c
+++ /dev/null
@@ -1,1327 +0,0 @@
-/*
- * Intel 82557 Fast Ethernet PCI Bus LAN Controller
- * as found on the Intel EtherExpress PRO/100B. This chip is full
- * of smarts, unfortunately they're not all in the right place.
- * To do:
- * the PCI scanning code could be made common to other adapters;
- * auto-negotiation, full-duplex;
- * optionally use memory-mapped registers;
- * detach for PCI reset problems (also towards loadable drivers).
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-enum {
- Nrfd = 64, /* receive frame area */
- Ncb = 64, /* maximum control blocks queued */
-
- NullPointer = 0xFFFFFFFF, /* 82557 NULL pointer */
-};
-
-enum { /* CSR */
- Status = 0x00, /* byte or word (word includes Ack) */
- Ack = 0x01, /* byte */
- CommandR = 0x02, /* byte or word (word includes Interrupt) */
- Interrupt = 0x03, /* byte */
- General = 0x04, /* dword */
- Port = 0x08, /* dword */
- Fcr = 0x0C, /* Flash control register */
- Ecr = 0x0E, /* EEPROM control register */
- Mcr = 0x10, /* MDI control register */
- Gstatus = 0x1D, /* General status register */
-};
-
-enum { /* Status */
- RUidle = 0x0000,
- RUsuspended = 0x0004,
- RUnoresources = 0x0008,
- RUready = 0x0010,
- RUrbd = 0x0020, /* bit */
- RUstatus = 0x003F, /* mask */
-
- CUidle = 0x0000,
- CUsuspended = 0x0040,
- CUactive = 0x0080,
- CUstatus = 0x00C0, /* mask */
-
- StatSWI = 0x0400, /* SoftWare generated Interrupt */
- StatMDI = 0x0800, /* MDI r/w done */
- StatRNR = 0x1000, /* Receive unit Not Ready */
- StatCNA = 0x2000, /* Command unit Not Active (Active->Idle) */
- StatFR = 0x4000, /* Finished Receiving */
- StatCX = 0x8000, /* Command eXecuted */
- StatTNO = 0x8000, /* Transmit NOT OK */
-};
-
-enum { /* Command (byte) */
- CUnop = 0x00,
- CUstart = 0x10,
- CUresume = 0x20,
- LoadDCA = 0x40, /* Load Dump Counters Address */
- DumpSC = 0x50, /* Dump Statistical Counters */
- LoadCUB = 0x60, /* Load CU Base */
- ResetSA = 0x70, /* Dump and Reset Statistical Counters */
-
- RUstart = 0x01,
- RUresume = 0x02,
- RUabort = 0x04,
- LoadHDS = 0x05, /* Load Header Data Size */
- LoadRUB = 0x06, /* Load RU Base */
- RBDresume = 0x07, /* Resume frame reception */
-};
-
-enum { /* Interrupt (byte) */
- InterruptM = 0x01, /* interrupt Mask */
- InterruptSI = 0x02, /* Software generated Interrupt */
-};
-
-enum { /* Ecr */
- EEsk = 0x01, /* serial clock */
- EEcs = 0x02, /* chip select */
- EEdi = 0x04, /* serial data in */
- EEdo = 0x08, /* serial data out */
-
- EEstart = 0x04, /* start bit */
- EEread = 0x02, /* read opcode */
-};
-
-enum { /* Mcr */
- MDIread = 0x08000000, /* read opcode */
- MDIwrite = 0x04000000, /* write opcode */
- MDIready = 0x10000000, /* ready bit */
- MDIie = 0x20000000, /* interrupt enable */
-};
-
-typedef struct Rfd {
- int field;
- ulong link;
- ulong rbd;
- ushort count;
- ushort size;
-
- uchar data[1700];
-} Rfd;
-
-enum { /* field */
- RfdCollision = 0x00000001,
- RfdIA = 0x00000002, /* IA match */
- RfdRxerr = 0x00000010, /* PHY character error */
- RfdType = 0x00000020, /* Type frame */
- RfdRunt = 0x00000080,
- RfdOverrun = 0x00000100,
- RfdBuffer = 0x00000200,
- RfdAlignment = 0x00000400,
- RfdCRC = 0x00000800,
-
- RfdOK = 0x00002000, /* frame received OK */
- RfdC = 0x00008000, /* reception Complete */
- RfdSF = 0x00080000, /* Simplified or Flexible (1) Rfd */
- RfdH = 0x00100000, /* Header RFD */
-
- RfdI = 0x20000000, /* Interrupt after completion */
- RfdS = 0x40000000, /* Suspend after completion */
- RfdEL = 0x80000000, /* End of List */
-};
-
-enum { /* count */
- RfdF = 0x4000,
- RfdEOF = 0x8000,
-};
-
-typedef struct Cb Cb;
-typedef struct Cb {
- ushort status;
- ushort command;
- ulong link;
- union {
- uchar data[24]; /* CbIAS + CbConfigure */
- struct {
- ulong tbd;
- ushort count;
- uchar threshold;
- uchar number;
-
- ulong tba;
- ushort tbasz;
- ushort pad;
- };
- };
-
- Block* bp;
- Cb* next;
-} Cb;
-
-enum { /* action command */
- CbU = 0x1000, /* transmit underrun */
- CbOK = 0x2000, /* DMA completed OK */
- CbC = 0x8000, /* execution Complete */
-
- CbNOP = 0x0000,
- CbIAS = 0x0001, /* Individual Address Setup */
- CbConfigure = 0x0002,
- CbMAS = 0x0003, /* Multicast Address Setup */
- CbTransmit = 0x0004,
- CbDump = 0x0006,
- CbDiagnose = 0x0007,
- CbCommand = 0x0007, /* mask */
-
- CbSF = 0x0008, /* Flexible-mode CbTransmit */
-
- CbI = 0x2000, /* Interrupt after completion */
- CbS = 0x4000, /* Suspend after completion */
- CbEL = 0x8000, /* End of List */
-};
-
-enum { /* CbTransmit count */
- CbEOF = 0x8000,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- Lock slock; /* attach */
- int state;
-
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
-
- int eepromsz; /* address size in bits */
- ushort* eeprom;
-
- Lock miilock;
-
- int tick;
-
- Lock rlock; /* registers */
- int command; /* last command issued */
-
- Block* rfdhead; /* receive side */
- Block* rfdtail;
- int nrfd;
-
- Lock cblock; /* transmit side */
- int action;
- int nop;
- uchar configdata[24];
- int threshold;
- int ncb;
- Cb* cbr;
- Cb* cbhead;
- Cb* cbtail;
- int cbq;
- int cbqmax;
- int cbqmaxhw;
-
- Lock dlock; /* dump statistical counters */
- ulong dump[17];
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-static uchar configdata[24] = {
- 0x16, /* byte count */
- 0x08, /* Rx/Tx FIFO limit */
- 0x00, /* adaptive IFS */
- 0x00,
- 0x00, /* Rx DMA maximum byte count */
-// 0x80, /* Tx DMA maximum byte count */
- 0x00, /* Tx DMA maximum byte count */
- 0x32, /* !late SCB, CNA interrupts */
- 0x03, /* discard short Rx frames */
- 0x00, /* 503/MII */
-
- 0x00,
- 0x2E, /* normal operation, NSAI */
- 0x00, /* linear priority */
- 0x60, /* inter-frame spacing */
- 0x00,
- 0xF2,
- 0xC8, /* 503, promiscuous mode off */
- 0x00,
- 0x40,
- 0xF3, /* transmit padding enable */
- 0x80, /* full duplex pin enable */
- 0x3F, /* no Multi IA */
- 0x05, /* no Multi Cast ALL */
-};
-
-#define csr8r(c, r) (inb((c)->port+(r)))
-#define csr16r(c, r) (ins((c)->port+(r)))
-#define csr32r(c, r) (inl((c)->port+(r)))
-#define csr8w(c, r, b) (outb((c)->port+(r), (int)(b)))
-#define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
-#define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
-
-static void
-command(Ctlr* ctlr, int c, int v)
-{
- int timeo;
-
- ilock(&ctlr->rlock);
-
- /*
- * Only back-to-back CUresume can be done
- * without waiting for any previous command to complete.
- * This should be the common case.
- * Unfortunately there's a chip errata where back-to-back
- * CUresumes can be lost, the fix is to always wait.
- if(c == CUresume && ctlr->command == CUresume){
- csr8w(ctlr, CommandR, c);
- iunlock(&ctlr->rlock);
- return;
- }
- */
-
- for(timeo = 0; timeo < 100; timeo++){
- if(!csr8r(ctlr, CommandR))
- break;
- microdelay(1);
- }
- if(timeo >= 100){
- ctlr->command = -1;
- iunlock(&ctlr->rlock);
- iprint("i82557: command %#ux %#ux timeout\n", c, v);
- return;
- }
-
- switch(c){
-
- case CUstart:
- case LoadDCA:
- case LoadCUB:
- case RUstart:
- case LoadHDS:
- case LoadRUB:
- csr32w(ctlr, General, v);
- break;
-
- /*
- case CUnop:
- case CUresume:
- case DumpSC:
- case ResetSA:
- case RUresume:
- case RUabort:
- */
- default:
- break;
- }
- csr8w(ctlr, CommandR, c);
- ctlr->command = c;
-
- iunlock(&ctlr->rlock);
-}
-
-static Block*
-rfdalloc(ulong link)
-{
- Block *bp;
- Rfd *rfd;
-
- if(bp = iallocb(sizeof(Rfd))){
- rfd = (Rfd*)bp->rp;
- rfd->field = 0;
- rfd->link = link;
- rfd->rbd = NullPointer;
- rfd->count = 0;
- rfd->size = sizeof(Etherpkt);
- }
-
- return bp;
-}
-
-static void
-watchdog(void* arg)
-{
- Ether *ether;
- Ctlr *ctlr;
- static void txstart(Ether*);
-
- ether = arg;
- for(;;){
- tsleep(&up->sleep, return0, 0, 4000);
-
- /*
- * Hmmm. This doesn't seem right. Currently
- * the device can't be disabled but it may be in
- * the future.
- */
- ctlr = ether->ctlr;
- if(ctlr == nil || ctlr->state == 0){
- print("%s: exiting\n", up->text);
- pexit("disabled", 0);
- }
-
- ilock(&ctlr->cblock);
- if(ctlr->tick++){
- ctlr->action = CbMAS;
- txstart(ether);
- }
- iunlock(&ctlr->cblock);
- }
-}
-
-static void
-attach(Ether* ether)
-{
- Ctlr *ctlr;
- char name[KNAMELEN];
-
- ctlr = ether->ctlr;
- lock(&ctlr->slock);
- if(ctlr->state == 0){
- ilock(&ctlr->rlock);
- csr8w(ctlr, Interrupt, 0);
- iunlock(&ctlr->rlock);
- command(ctlr, RUstart, PADDR(ctlr->rfdhead->rp));
- ctlr->state = 1;
-
- /*
- * Start the watchdog timer for the receive lockup errata
- * unless the EEPROM compatibility word indicates it may be
- * omitted.
- */
- if((ctlr->eeprom[0x03] & 0x0003) != 0x0003){
- snprint(name, KNAMELEN, "#l%dwatchdog", ether->ctlrno);
- kproc(name, watchdog, ether, 0);
- }
- }
- unlock(&ctlr->slock);
-}
-
-static long
-ifstat(Ether* ether, void* a, long n, ulong offset)
-{
- char *p;
- int i, len, phyaddr;
- Ctlr *ctlr;
- ulong dump[17];
-
- ctlr = ether->ctlr;
- lock(&ctlr->dlock);
-
- /*
- * Start the command then
- * wait for completion status,
- * should be 0xA005.
- */
- ctlr->dump[16] = 0;
- command(ctlr, DumpSC, 0);
- while(ctlr->dump[16] == 0)
- ;
-
- ether->oerrs = ctlr->dump[1]+ctlr->dump[2]+ctlr->dump[3];
- ether->crcs = ctlr->dump[10];
- ether->frames = ctlr->dump[11];
- ether->buffs = ctlr->dump[12]+ctlr->dump[15];
- ether->overflows = ctlr->dump[13];
-
- if(n == 0){
- unlock(&ctlr->dlock);
- return 0;
- }
-
- memmove(dump, ctlr->dump, sizeof(dump));
- unlock(&ctlr->dlock);
-
- p = malloc(READSTR);
- len = snprint(p, READSTR, "transmit good frames: %lud\n", dump[0]);
- len += snprint(p+len, READSTR-len, "transmit maximum collisions errors: %lud\n", dump[1]);
- len += snprint(p+len, READSTR-len, "transmit late collisions errors: %lud\n", dump[2]);
- len += snprint(p+len, READSTR-len, "transmit underrun errors: %lud\n", dump[3]);
- len += snprint(p+len, READSTR-len, "transmit lost carrier sense: %lud\n", dump[4]);
- len += snprint(p+len, READSTR-len, "transmit deferred: %lud\n", dump[5]);
- len += snprint(p+len, READSTR-len, "transmit single collisions: %lud\n", dump[6]);
- len += snprint(p+len, READSTR-len, "transmit multiple collisions: %lud\n", dump[7]);
- len += snprint(p+len, READSTR-len, "transmit total collisions: %lud\n", dump[8]);
- len += snprint(p+len, READSTR-len, "receive good frames: %lud\n", dump[9]);
- len += snprint(p+len, READSTR-len, "receive CRC errors: %lud\n", dump[10]);
- len += snprint(p+len, READSTR-len, "receive alignment errors: %lud\n", dump[11]);
- len += snprint(p+len, READSTR-len, "receive resource errors: %lud\n", dump[12]);
- len += snprint(p+len, READSTR-len, "receive overrun errors: %lud\n", dump[13]);
- len += snprint(p+len, READSTR-len, "receive collision detect errors: %lud\n", dump[14]);
- len += snprint(p+len, READSTR-len, "receive short frame errors: %lud\n", dump[15]);
- len += snprint(p+len, READSTR-len, "nop: %d\n", ctlr->nop);
- if(ctlr->cbqmax > ctlr->cbqmaxhw)
- ctlr->cbqmaxhw = ctlr->cbqmax;
- len += snprint(p+len, READSTR-len, "cbqmax: %d\n", ctlr->cbqmax);
- ctlr->cbqmax = 0;
- len += snprint(p+len, READSTR-len, "threshold: %d\n", ctlr->threshold);
-
- len += snprint(p+len, READSTR-len, "eeprom:");
- for(i = 0; i < (1<<ctlr->eepromsz); i++){
- if(i && ((i & 0x07) == 0))
- len += snprint(p+len, READSTR-len, "\n ");
- len += snprint(p+len, READSTR-len, " %4.4ux", ctlr->eeprom[i]);
- }
-
- if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000)){
- phyaddr = ctlr->eeprom[6] & 0x00FF;
- len += snprint(p+len, READSTR-len, "\nphy %2d:", phyaddr);
- for(i = 0; i < 6; i++){
- static int miir(Ctlr*, int, int);
-
- len += snprint(p+len, READSTR-len, " %4.4ux",
- miir(ctlr, phyaddr, i));
- }
- }
-
- snprint(p+len, READSTR-len, "\n");
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static void
-txstart(Ether* ether)
-{
- Ctlr *ctlr;
- Block *bp;
- Cb *cb;
-
- ctlr = ether->ctlr;
- while(ctlr->cbq < (ctlr->ncb-1)){
- cb = ctlr->cbhead->next;
- if(ctlr->action == 0){
- bp = qget(ether->oq);
- if(bp == nil)
- break;
-
- cb->command = CbS|CbSF|CbTransmit;
- cb->tbd = PADDR(&cb->tba);
- cb->count = 0;
- cb->threshold = ctlr->threshold;
- cb->number = 1;
- cb->tba = PADDR(bp->rp);
- cb->bp = bp;
- cb->tbasz = BLEN(bp);
- }
- else if(ctlr->action == CbConfigure){
- cb->command = CbS|CbConfigure;
- memmove(cb->data, ctlr->configdata, sizeof(ctlr->configdata));
- ctlr->action = 0;
- }
- else if(ctlr->action == CbIAS){
- cb->command = CbS|CbIAS;
- memmove(cb->data, ether->ea, Eaddrlen);
- ctlr->action = 0;
- }
- else if(ctlr->action == CbMAS){
- cb->command = CbS|CbMAS;
- memset(cb->data, 0, sizeof(cb->data));
- ctlr->action = 0;
- }
- else{
- print("#l%d: action %#ux\n", ether->ctlrno, ctlr->action);
- ctlr->action = 0;
- break;
- }
- cb->status = 0;
-
- coherence();
- ctlr->cbhead->command &= ~CbS;
- ctlr->cbhead = cb;
- ctlr->cbq++;
- }
-
- /*
- * Workaround for some broken HUB chips
- * when connected at 10Mb/s half-duplex.
- */
- if(ctlr->nop){
- command(ctlr, CUnop, 0);
- microdelay(1);
- }
- command(ctlr, CUresume, 0);
-
- if(ctlr->cbq > ctlr->cbqmax)
- ctlr->cbqmax = ctlr->cbq;
-}
-
-static void
-configure(Ether* ether, int promiscuous)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(&ctlr->cblock);
- if(promiscuous){
- ctlr->configdata[6] |= 0x80; /* Save Bad Frames */
- //ctlr->configdata[6] &= ~0x40; /* !Discard Overrun Rx Frames */
- ctlr->configdata[7] &= ~0x01; /* !Discard Short Rx Frames */
- ctlr->configdata[15] |= 0x01; /* Promiscuous mode */
- ctlr->configdata[18] &= ~0x01; /* (!Padding enable?), !stripping enable */
- ctlr->configdata[21] |= 0x08; /* Multi Cast ALL */
- }
- else{
- ctlr->configdata[6] &= ~0x80;
- //ctlr->configdata[6] |= 0x40;
- ctlr->configdata[7] |= 0x01;
- ctlr->configdata[15] &= ~0x01;
- ctlr->configdata[18] |= 0x01; /* 0x03? */
- ctlr->configdata[21] &= ~0x08;
- }
- ctlr->action = CbConfigure;
- txstart(ether);
- iunlock(&ctlr->cblock);
-}
-
-static void
-promiscuous(void* arg, int on)
-{
- configure(arg, on);
-}
-
-static void
-multicast(void* arg, uchar *addr, int on)
-{
- USED(addr, on);
- configure(arg, 1);
-}
-
-static void
-transmit(Ether* ether)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(&ctlr->cblock);
- txstart(ether);
- iunlock(&ctlr->cblock);
-}
-
-static void
-receive(Ether* ether)
-{
- Rfd *rfd;
- Ctlr *ctlr;
- int count;
- Block *bp, *pbp, *xbp;
-
- ctlr = ether->ctlr;
- bp = ctlr->rfdhead;
- for(rfd = (Rfd*)bp->rp; rfd->field & RfdC; rfd = (Rfd*)bp->rp){
- /*
- * If it's an OK receive frame
- * 1) save the count
- * 2) if it's small, try to allocate a block and copy
- * the data, then adjust the necessary fields for reuse;
- * 3) if it's big, try to allocate a new Rfd and if
- * successful
- * adjust the received buffer pointers for the
- * actual data received;
- * initialise the replacement buffer to point to
- * the next in the ring;
- * initialise bp to point to the replacement;
- * 4) if there's a good packet, pass it on for disposal.
- */
- if(rfd->field & RfdOK){
- pbp = nil;
- count = rfd->count & 0x3FFF;
- if((count < ETHERMAXTU/4) && (pbp = iallocb(count))){
- memmove(pbp->rp, bp->rp+offsetof(Rfd, data[0]), count);
- pbp->wp = pbp->rp + count;
-
- rfd->count = 0;
- rfd->field = 0;
- }
- else if(xbp = rfdalloc(rfd->link)){
- bp->rp += offsetof(Rfd, data[0]);
- bp->wp = bp->rp + count;
-
- xbp->next = bp->next;
- bp->next = 0;
-
- pbp = bp;
- bp = xbp;
- }
- if(pbp != nil)
- etheriq(ether, pbp, 1);
- }
- else{
- rfd->count = 0;
- rfd->field = 0;
- }
-
- /*
- * The ring tail pointer follows the head with with one
- * unused buffer in between to defeat hardware prefetch;
- * once the tail pointer has been bumped on to the next
- * and the new tail has the Suspend bit set, it can be
- * removed from the old tail buffer.
- * As a replacement for the current head buffer may have
- * been allocated above, ensure that the new tail points
- * to it (next and link).
- */
- rfd = (Rfd*)ctlr->rfdtail->rp;
- ctlr->rfdtail = ctlr->rfdtail->next;
- ctlr->rfdtail->next = bp;
- ((Rfd*)ctlr->rfdtail->rp)->link = PADDR(bp->rp);
- ((Rfd*)ctlr->rfdtail->rp)->field |= RfdS;
- coherence();
- rfd->field &= ~RfdS;
-
- /*
- * Finally done with the current (possibly replaced)
- * head, move on to the next and maintain the sentinel
- * between tail and head.
- */
- ctlr->rfdhead = bp->next;
- bp = ctlr->rfdhead;
- }
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
- Cb* cb;
- Ctlr *ctlr;
- Ether *ether;
- int status;
-
- ether = arg;
- ctlr = ether->ctlr;
-
- for(;;){
- ilock(&ctlr->rlock);
- status = csr16r(ctlr, Status);
- csr8w(ctlr, Ack, (status>>8) & 0xFF);
- iunlock(&ctlr->rlock);
-
- if(!(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI)))
- break;
-
- /*
- * If the watchdog timer for the receiver lockup errata is running,
- * let it know the receiver is active.
- */
- if(status & (StatFR|StatRNR)){
- ilock(&ctlr->cblock);
- ctlr->tick = 0;
- iunlock(&ctlr->cblock);
- }
-
- if(status & StatFR){
- receive(ether);
- status &= ~StatFR;
- }
-
- if(status & StatRNR){
- command(ctlr, RUresume, 0);
- status &= ~StatRNR;
- }
-
- if(status & StatCNA){
- ilock(&ctlr->cblock);
-
- cb = ctlr->cbtail;
- while(ctlr->cbq){
- if(!(cb->status & CbC))
- break;
- if(cb->bp){
- freeb(cb->bp);
- cb->bp = nil;
- }
- if((cb->status & CbU) && ctlr->threshold < 0xE0)
- ctlr->threshold++;
-
- ctlr->cbq--;
- cb = cb->next;
- }
- ctlr->cbtail = cb;
-
- txstart(ether);
- iunlock(&ctlr->cblock);
-
- status &= ~StatCNA;
- }
-
- if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
- panic("#l%d: status %#ux\n", ether->ctlrno, status);
- }
-}
-
-static void
-ctlrinit(Ctlr* ctlr)
-{
- int i;
- Block *bp;
- Rfd *rfd;
- ulong link;
-
- /*
- * Create the Receive Frame Area (RFA) as a ring of allocated
- * buffers.
- * A sentinel buffer is maintained between the last buffer in
- * the ring (marked with RfdS) and the head buffer to defeat the
- * hardware prefetch of the next RFD and allow dynamic buffer
- * allocation.
- */
- link = NullPointer;
- for(i = 0; i < Nrfd; i++){
- bp = rfdalloc(link);
- if(ctlr->rfdhead == nil)
- ctlr->rfdtail = bp;
- bp->next = ctlr->rfdhead;
- ctlr->rfdhead = bp;
- link = PADDR(bp->rp);
- }
- ctlr->rfdtail->next = ctlr->rfdhead;
- rfd = (Rfd*)ctlr->rfdtail->rp;
- rfd->link = PADDR(ctlr->rfdhead->rp);
- rfd->field |= RfdS;
- ctlr->rfdhead = ctlr->rfdhead->next;
-
- /*
- * Create a ring of control blocks for the
- * transmit side.
- */
- ilock(&ctlr->cblock);
- ctlr->cbr = malloc(ctlr->ncb*sizeof(Cb));
- for(i = 0; i < ctlr->ncb; i++){
- ctlr->cbr[i].status = CbC|CbOK;
- ctlr->cbr[i].command = CbS|CbNOP;
- ctlr->cbr[i].link = PADDR(&ctlr->cbr[NEXT(i, ctlr->ncb)].status);
- ctlr->cbr[i].next = &ctlr->cbr[NEXT(i, ctlr->ncb)];
- }
- ctlr->cbhead = ctlr->cbr;
- ctlr->cbtail = ctlr->cbr;
- ctlr->cbq = 0;
-
- memmove(ctlr->configdata, configdata, sizeof(configdata));
- ctlr->threshold = 80;
- ctlr->tick = 0;
-
- iunlock(&ctlr->cblock);
-}
-
-static int
-miir(Ctlr* ctlr, int phyadd, int regadd)
-{
- int mcr, timo;
-
- lock(&ctlr->miilock);
- csr32w(ctlr, Mcr, MDIread|(phyadd<<21)|(regadd<<16));
- mcr = 0;
- for(timo = 64; timo; timo--){
- mcr = csr32r(ctlr, Mcr);
- if(mcr & MDIready)
- break;
- microdelay(1);
- }
- unlock(&ctlr->miilock);
-
- if(mcr & MDIready)
- return mcr & 0xFFFF;
-
- return -1;
-}
-
-static int
-miiw(Ctlr* ctlr, int phyadd, int regadd, int data)
-{
- int mcr, timo;
-
- lock(&ctlr->miilock);
- csr32w(ctlr, Mcr, MDIwrite|(phyadd<<21)|(regadd<<16)|(data & 0xFFFF));
- mcr = 0;
- for(timo = 64; timo; timo--){
- mcr = csr32r(ctlr, Mcr);
- if(mcr & MDIready)
- break;
- microdelay(1);
- }
- unlock(&ctlr->miilock);
-
- if(mcr & MDIready)
- return 0;
-
- return -1;
-}
-
-static int
-hy93c46r(Ctlr* ctlr, int r)
-{
- int data, i, op, size;
-
- /*
- * Hyundai HY93C46 or equivalent serial EEPROM.
- * This sequence for reading a 16-bit register 'r'
- * in the EEPROM is taken straight from Section
- * 3.3.4.2 of the Intel 82557 User's Guide.
- */
-reread:
- csr16w(ctlr, Ecr, EEcs);
- op = EEstart|EEread;
- for(i = 2; i >= 0; i--){
- data = (((op>>i) & 0x01)<<2)|EEcs;
- csr16w(ctlr, Ecr, data);
- csr16w(ctlr, Ecr, data|EEsk);
- microdelay(1);
- csr16w(ctlr, Ecr, data);
- microdelay(1);
- }
-
- /*
- * First time through must work out the EEPROM size.
- */
- if((size = ctlr->eepromsz) == 0)
- size = 8;
-
- for(size = size-1; size >= 0; size--){
- data = (((r>>size) & 0x01)<<2)|EEcs;
- csr16w(ctlr, Ecr, data);
- csr16w(ctlr, Ecr, data|EEsk);
- delay(1);
- csr16w(ctlr, Ecr, data);
- microdelay(1);
- if(!(csr16r(ctlr, Ecr) & EEdo))
- break;
- }
-
- data = 0;
- for(i = 15; i >= 0; i--){
- csr16w(ctlr, Ecr, EEcs|EEsk);
- microdelay(1);
- if(csr16r(ctlr, Ecr) & EEdo)
- data |= (1<<i);
- csr16w(ctlr, Ecr, EEcs);
- microdelay(1);
- }
-
- csr16w(ctlr, Ecr, 0);
-
- if(ctlr->eepromsz == 0){
- ctlr->eepromsz = 8-size;
- ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
- goto reread;
- }
-
- return data;
-}
-
-static void
-i82557pci(void)
-{
- Pcidev *p;
- Ctlr *ctlr;
- int i, nop, port;
-
- p = nil;
- nop = 0;
- while(p = pcimatch(p, 0x8086, 0)){
- switch(p->did){
- default:
- continue;
- case 0x1031: /* Intel 82562EM */
- case 0x1050: /* Intel 82562EZ */
- case 0x1039: /* Intel 82801BD PRO/100 VE */
- case 0x103A: /* Intel 82562 PRO/100 VE */
- case 0x103D: /* Intel 82562 PRO/100 VE */
- case 0x1064: /* Intel 82562 PRO/100 VE */
- case 0x2449: /* Intel 82562ET */
- nop = 1;
- /*FALLTHROUGH*/
- case 0x1209: /* Intel 82559ER */
- case 0x1229: /* Intel 8255[789] */
- case 0x1030: /* Intel 82559 InBusiness 10/100 */
- break;
- }
-
- if(pcigetpms(p) > 0){
- pcisetpms(p, 0);
-
- for(i = 0; i < 6; i++)
- pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
- pcicfgw8(p, PciINTL, p->intl);
- pcicfgw8(p, PciLTR, p->ltr);
- pcicfgw8(p, PciCLS, p->cls);
- pcicfgw16(p, PciPCR, p->pcr);
- }
-
- /*
- * bar[0] is the memory-mapped register address (4KB),
- * bar[1] is the I/O port register address (32 bytes) and
- * bar[2] is for the flash ROM (1MB).
- */
- port = p->mem[1].bar & ~0x01;
- if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
- print("i82557: port %#ux in use\n", port);
- continue;
- }
-
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = port;
- ctlr->pcidev = p;
- ctlr->nop = nop;
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
-
- pcisetbme(p);
- }
-}
-
-static char* mediatable[9] = {
- "10BASE-T", /* TP */
- "10BASE-2", /* BNC */
- "10BASE-5", /* AUI */
- "100BASE-TX",
- "10BASE-TFD",
- "100BASE-TXFD",
- "100BASE-T4",
- "100BASE-FX",
- "100BASE-FXFD",
-};
-
-static int
-scanphy(Ctlr* ctlr)
-{
- int i, oui, x;
-
- for(i = 0; i < 32; i++){
- if((oui = miir(ctlr, i, 2)) == -1 || oui == 0 || oui == 0xFFFF)
- continue;
- oui <<= 6;
- x = miir(ctlr, i, 3);
- oui |= x>>10;
- //print("phy%d: oui %#ux reg1 %#ux\n", i, oui, miir(ctlr, i, 1));
-
- ctlr->eeprom[6] = i;
- if(oui == 0xAA00)
- ctlr->eeprom[6] |= 0x07<<8;
- else if(oui == 0x80017){
- if(x & 0x01)
- ctlr->eeprom[6] |= 0x0A<<8;
- else
- ctlr->eeprom[6] |= 0x04<<8;
- }
- return i;
- }
- return -1;
-}
-
-static void
-shutdown(Ether* ether)
-{
- Ctlr *ctlr = ether->ctlr;
-
-print("ether82557 shutting down\n");
- csr32w(ctlr, Port, 0);
- delay(1);
- csr8w(ctlr, Interrupt, InterruptM);
-}
-
-
-static int
-reset(Ether* ether)
-{
- int anar, anlpar, bmcr, bmsr, i, k, medium, phyaddr, x;
- unsigned short sum;
- uchar ea[Eaddrlen];
- Ctlr *ctlr;
-
- if(ctlrhead == nil)
- i82557pci();
-
- /*
- * Any adapter matches if no ether->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(ether->port == 0 || ether->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- /*
- * Initialise the Ctlr structure.
- * Perform a software reset after which should ensure busmastering
- * is still enabled. The EtherExpress PRO/100B appears to leave
- * the PCI configuration alone (see the 'To do' list above) so punt
- * for now.
- * Load the RUB and CUB registers for linear addressing (0).
- */
- ether->ctlr = ctlr;
- ether->port = ctlr->port;
- ether->irq = ctlr->pcidev->intl;
- ether->tbdf = ctlr->pcidev->tbdf;
-
- ilock(&ctlr->rlock);
- csr32w(ctlr, Port, 0);
- delay(1);
- csr8w(ctlr, Interrupt, InterruptM);
- iunlock(&ctlr->rlock);
-
- command(ctlr, LoadRUB, 0);
- command(ctlr, LoadCUB, 0);
- command(ctlr, LoadDCA, PADDR(ctlr->dump));
-
- /*
- * Initialise the receive frame, transmit ring and configuration areas.
- */
- ctlr->ncb = Ncb;
- ctlrinit(ctlr);
-
- /*
- * Read the EEPROM.
- * Do a dummy read first to get the size
- * and allocate ctlr->eeprom.
- */
- hy93c46r(ctlr, 0);
- sum = 0;
- for(i = 0; i < (1<<ctlr->eepromsz); i++){
- x = hy93c46r(ctlr, i);
- ctlr->eeprom[i] = x;
- sum += x;
- }
- if(sum != 0xBABA)
- print("#l%d: EEPROM checksum - %#4.4ux\n", ether->ctlrno, sum);
-
- /*
- * Eeprom[6] indicates whether there is a PHY and whether
- * it's not 10Mb-only, in which case use the given PHY address
- * to set any PHY specific options and determine the speed.
- * Unfortunately, sometimes the EEPROM is blank except for
- * the ether address and checksum; in this case look at the
- * controller type and if it's am 82558 or 82559 it has an
- * embedded PHY so scan for that.
- * If no PHY, assume 82503 (serial) operation.
- */
- if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000))
- phyaddr = ctlr->eeprom[6] & 0x00FF;
- else
- switch(ctlr->pcidev->rid){
- case 0x01: /* 82557 A-step */
- case 0x02: /* 82557 B-step */
- case 0x03: /* 82557 C-step */
- default:
- phyaddr = -1;
- break;
- case 0x04: /* 82558 A-step */
- case 0x05: /* 82558 B-step */
- case 0x06: /* 82559 A-step */
- case 0x07: /* 82559 B-step */
- case 0x08: /* 82559 C-step */
- case 0x09: /* 82559ER A-step */
- phyaddr = scanphy(ctlr);
- break;
- }
- if(phyaddr >= 0){
- /*
- * Resolve the highest common ability of the two
- * link partners. In descending order:
- * 0x0100 100BASE-TX Full Duplex
- * 0x0200 100BASE-T4
- * 0x0080 100BASE-TX
- * 0x0040 10BASE-T Full Duplex
- * 0x0020 10BASE-T
- */
- anar = miir(ctlr, phyaddr, 0x04);
- anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
- anar &= anlpar;
- bmcr = 0;
- if(anar & 0x380)
- bmcr = 0x2000;
- if(anar & 0x0140)
- bmcr |= 0x0100;
-
- switch((ctlr->eeprom[6]>>8) & 0x001F){
-
- case 0x04: /* DP83840 */
- case 0x0A: /* DP83840A */
- /*
- * The DP83840[A] requires some tweaking for
- * reliable operation.
- * The manual says bit 10 should be unconditionally
- * set although it supposedly only affects full-duplex
- * operation (an & 0x0140).
- */
- x = miir(ctlr, phyaddr, 0x17) & ~0x0520;
- x |= 0x0420;
- for(i = 0; i < ether->nopt; i++){
- if(cistrcmp(ether->opt[i], "congestioncontrol"))
- continue;
- x |= 0x0100;
- break;
- }
- miiw(ctlr, phyaddr, 0x17, x);
-
- /*
- * If the link partner can't autonegotiate, determine
- * the speed from elsewhere.
- */
- if(anlpar == 0){
- miir(ctlr, phyaddr, 0x01);
- bmsr = miir(ctlr, phyaddr, 0x01);
- x = miir(ctlr, phyaddr, 0x19);
- if((bmsr & 0x0004) && !(x & 0x0040))
- bmcr = 0x2000;
- }
- break;
-
- case 0x07: /* Intel 82555 */
- /*
- * Auto-negotiation may fail if the other end is
- * a DP83840A and the cable is short.
- */
- miir(ctlr, phyaddr, 0x01);
- bmsr = miir(ctlr, phyaddr, 0x01);
- if((miir(ctlr, phyaddr, 0) & 0x1000) && !(bmsr & 0x0020)){
- miiw(ctlr, phyaddr, 0x1A, 0x2010);
- x = miir(ctlr, phyaddr, 0);
- miiw(ctlr, phyaddr, 0, 0x0200|x);
- for(i = 0; i < 3000; i++){
- delay(1);
- if(miir(ctlr, phyaddr, 0x01) & 0x0020)
- break;
- }
- miiw(ctlr, phyaddr, 0x1A, 0x2000);
-
- anar = miir(ctlr, phyaddr, 0x04);
- anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
- anar &= anlpar;
- bmcr = 0;
- if(anar & 0x380)
- bmcr = 0x2000;
- if(anar & 0x0140)
- bmcr |= 0x0100;
- }
- break;
- }
-
- /*
- * Force speed and duplex if no auto-negotiation.
- */
- if(anlpar == 0){
- medium = -1;
- for(i = 0; i < ether->nopt; i++){
- for(k = 0; k < nelem(mediatable); k++){
- if(cistrcmp(mediatable[k], ether->opt[i]))
- continue;
- medium = k;
- break;
- }
-
- switch(medium){
- default:
- break;
-
- case 0x00: /* 10BASE-T */
- case 0x01: /* 10BASE-2 */
- case 0x02: /* 10BASE-5 */
- bmcr &= ~(0x2000|0x0100);
- ctlr->configdata[19] &= ~0x40;
- break;
-
- case 0x03: /* 100BASE-TX */
- case 0x06: /* 100BASE-T4 */
- case 0x07: /* 100BASE-FX */
- ctlr->configdata[19] &= ~0x40;
- bmcr |= 0x2000;
- break;
-
- case 0x04: /* 10BASE-TFD */
- bmcr = (bmcr & ~0x2000)|0x0100;
- ctlr->configdata[19] |= 0x40;
- break;
-
- case 0x05: /* 100BASE-TXFD */
- case 0x08: /* 100BASE-FXFD */
- bmcr |= 0x2000|0x0100;
- ctlr->configdata[19] |= 0x40;
- break;
- }
- }
- if(medium != -1)
- miiw(ctlr, phyaddr, 0x00, bmcr);
- }
-
- if(bmcr & 0x2000)
- ether->mbps = 100;
-
- ctlr->configdata[8] = 1;
- ctlr->configdata[15] &= ~0x80;
- }
- else{
- ctlr->configdata[8] = 0;
- ctlr->configdata[15] |= 0x80;
- }
-
- /*
- * Workaround for some broken HUB chips when connected at 10Mb/s
- * half-duplex.
- * This is a band-aid, but as there's no dynamic auto-negotiation
- * code at the moment, only deactivate the workaround code in txstart
- * if the link is 100Mb/s.
- */
- if(ether->mbps != 10)
- ctlr->nop = 0;
-
- /*
- * Load the chip configuration and start it off.
- */
- if(ether->oq == 0)
- ether->oq = qopen(256*1024, Qmsg, 0, 0);
- configure(ether, 0);
- command(ctlr, CUstart, PADDR(&ctlr->cbr->status));
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the EEPROM and set in ether->ea prior to loading
- * the station address with the Individual Address Setup command.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, ether->ea, Eaddrlen) == 0){
- for(i = 0; i < Eaddrlen/2; i++){
- x = ctlr->eeprom[i];
- ether->ea[2*i] = x;
- ether->ea[2*i+1] = x>>8;
- }
- }
-
- ilock(&ctlr->cblock);
- ctlr->action = CbIAS;
- txstart(ether);
- iunlock(&ctlr->cblock);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = ifstat;
- ether->shutdown = shutdown;
-
- ether->promiscuous = promiscuous;
- ether->multicast = multicast;
- ether->arg = ether;
-
- return 0;
-}
-
-void
-ether82557link(void)
-{
- addethercard("i82557", reset);
-}
diff --git a/os/pc/ether83815.c b/os/pc/ether83815.c
deleted file mode 100644
index 3d2d9d76..00000000
--- a/os/pc/ether83815.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * National Semiconductor DP83815
- *
- * Supports only internal PHY and has been tested on:
- * Netgear FA311TX (using Netgear DS108 10/100 hub)
- * To do:
- * check Ethernet address;
- * test autonegotiation on 10 Mbit, and 100 Mbit full duplex;
- * external PHY via MII (should be common code for MII);
- * thresholds;
- * ring sizing;
- * physical link changes/disconnect;
- * push initialisation back to attach.
- *
- * C H Forsyth, forsyth@vitanuova.com, 18th June 2001.
- */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-#define DEBUG (0)
-#define debug if(DEBUG)print
-
-enum {
- Nrde = 64,
- Ntde = 64,
-};
-
-#define Rbsz ROUNDUP(sizeof(Etherpkt)+4, 4)
-
-typedef struct Des {
- ulong next;
- int cmdsts;
- ulong addr;
- Block* bp;
-} Des;
-
-enum { /* cmdsts */
- Own = 1<<31, /* set by data producer to hand to consumer */
- More = 1<<30, /* more of packet in next descriptor */
- Intr = 1<<29, /* interrupt when device is done with it */
- Supcrc = 1<<28, /* suppress crc on transmit */
- Inccrc = 1<<28, /* crc included on receive (always) */
- Ok = 1<<27, /* packet ok */
- Size = 0xFFF, /* packet size in bytes */
-
- /* transmit */
- Txa = 1<<26, /* transmission aborted */
- Tfu = 1<<25, /* transmit fifo underrun */
- Crs = 1<<24, /* carrier sense lost */
- Td = 1<<23, /* transmission deferred */
- Ed = 1<<22, /* excessive deferral */
- Owc = 1<<21, /* out of window collision */
- Ec = 1<<20, /* excessive collisions */
- /* 19-16 collision count */
-
- /* receive */
- Rxa = 1<<26, /* receive aborted (same as Rxo) */
- Rxo = 1<<25, /* receive overrun */
- Dest = 3<<23, /* destination class */
- Drej= 0<<23, /* packet was rejected */
- Duni= 1<<23, /* unicast */
- Dmulti= 2<<23, /* multicast */
- Dbroad= 3<<23, /* broadcast */
- Long = 1<<22, /* too long packet received */
- Runt = 1<<21, /* packet less than 64 bytes */
- Ise = 1<<20, /* invalid symbol */
- Crce = 1<<19, /* invalid crc */
- Fae = 1<<18, /* frame alignment error */
- Lbp = 1<<17, /* loopback packet */
- Col = 1<<16, /* collision during receive */
-};
-
-enum { /* PCI vendor & device IDs */
- Nat83815 = (0x0020<<16)|0x100B,
- SiS = 0x1039,
- SiS900 = (0x0900<<16)|SiS,
- SiS7016 = (0x7016<<16)|SiS,
-
- SiS630bridge = 0x0008,
-
- /* SiS 900 PCI revision codes */
- SiSrev630s = 0x81,
- SiSrev630e = 0x82,
- SiSrev630ea1 = 0x83,
-
- SiSeenodeaddr = 8, /* short addr of SiS eeprom mac addr */
- SiS630eenodeaddr = 9, /* likewise for the 630 */
- Nseenodeaddr = 6, /* " for NS eeprom */
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
- int id; /* (pcidev->did<<16)|pcidev->vid */
-
- ushort srom[0xB+1];
- uchar sromea[Eaddrlen]; /* MAC address */
-
- uchar fd; /* option or auto negotiation */
-
- int mbps;
-
- Lock lock;
-
- Des* rdr; /* receive descriptor ring */
- int nrdr; /* size of rdr */
- int rdrx; /* index into rdr */
-
- Lock tlock;
- Des* tdr; /* transmit descriptor ring */
- int ntdr; /* size of tdr */
- int tdrh; /* host index into tdr */
- int tdri; /* interface index into tdr */
- int ntq; /* descriptors active */
- int ntqmax;
-
- ulong rxa; /* receive statistics */
- ulong rxo;
- ulong rlong;
- ulong runt;
- ulong ise;
- ulong crce;
- ulong fae;
- ulong lbp;
- ulong col;
- ulong rxsovr;
- ulong rxorn;
-
- ulong txa; /* transmit statistics */
- ulong tfu;
- ulong crs;
- ulong td;
- ulong ed;
- ulong owc;
- ulong ec;
- ulong txurn;
-
- ulong dperr; /* system errors */
- ulong rmabt;
- ulong rtabt;
- ulong sserr;
- ulong rxsover;
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-enum {
- /* registers (could memory map) */
- Rcr= 0x00, /* command register */
- Rst= 1<<8,
- Rxr= 1<<5, /* receiver reset */
- Txr= 1<<4, /* transmitter reset */
- Rxd= 1<<3, /* receiver disable */
- Rxe= 1<<2, /* receiver enable */
- Txd= 1<<1, /* transmitter disable */
- Txe= 1<<0, /* transmitter enable */
- Rcfg= 0x04, /* configuration */
- Lnksts= 1<<31, /* link good */
- Speed100= 1<<30, /* 100 Mb/s link */
- Fdup= 1<<29, /* full duplex */
- Pol= 1<<28, /* polarity reversal (10baseT) */
- Aneg_dn= 1<<27, /* autonegotiation done */
- Pint_acen= 1<<17, /* PHY interrupt auto clear enable */
- Pause_adv= 1<<16, /* advertise pause during auto neg */
- Paneg_ena= 1<<13, /* auto negotiation enable */
- Paneg_all= 7<<13, /* auto negotiation enable 10/100 half & full */
- Ext_phy= 1<<12, /* enable MII for external PHY */
- Phy_rst= 1<<10, /* reset internal PHY */
- Phy_dis= 1<<9, /* disable internal PHY (eg, low power) */
- Req_alg= 1<<7, /* PCI bus request: set means less aggressive */
- Sb= 1<<6, /* single slot back-off not random */
- Pow= 1<<5, /* out of window timer selection */
- Exd= 1<<4, /* disable excessive deferral timer */
- Pesel= 1<<3, /* parity error algorithm selection */
- Brom_dis= 1<<2, /* disable boot rom interface */
- Bem= 1<<0, /* big-endian mode */
- Rmear= 0x08, /* eeprom access */
- Mdc= 1<<6, /* MII mangement check */
- Mddir= 1<<5, /* MII management direction */
- Mdio= 1<<4, /* MII mangement data */
- Eesel= 1<<3, /* EEPROM chip select */
- Eeclk= 1<<2, /* EEPROM clock */
- Eedo= 1<<1, /* EEPROM data out (from chip) */
- Eedi= 1<<0, /* EEPROM data in (to chip) */
- Rptscr= 0x0C, /* pci test control */
- Risr= 0x10, /* interrupt status */
- Txrcmp= 1<<25, /* transmit reset complete */
- Rxrcmp= 1<<24, /* receiver reset complete */
- Dperr= 1<<23, /* detected parity error */
- Sserr= 1<<22, /* signalled system error */
- Rmabt= 1<<21, /* received master abort */
- Rtabt= 1<<20, /* received target abort */
- Rxsovr= 1<<16, /* RX status FIFO overrun */
- Hiberr= 1<<15, /* high bits error set (OR of 25-16) */
- Phy= 1<<14, /* PHY interrupt */
- Pme= 1<<13, /* power management event (wake online) */
- Swi= 1<<12, /* software interrupt */
- Mib= 1<<11, /* MIB service */
- Txurn= 1<<10, /* TX underrun */
- Txidle= 1<<9, /* TX idle */
- Txerr= 1<<8, /* TX packet error */
- Txdesc= 1<<7, /* TX descriptor (with Intr bit done) */
- Txok= 1<<6, /* TX ok */
- Rxorn= 1<<5, /* RX overrun */
- Rxidle= 1<<4, /* RX idle */
- Rxearly= 1<<3, /* RX early threshold */
- Rxerr= 1<<2, /* RX packet error */
- Rxdesc= 1<<1, /* RX descriptor (with Intr bit done) */
- Rxok= 1<<0, /* RX ok */
- Rimr= 0x14, /* interrupt mask */
- Rier= 0x18, /* interrupt enable */
- Ie= 1<<0, /* interrupt enable */
- Rtxdp= 0x20, /* transmit descriptor pointer */
- Rtxcfg= 0x24, /* transmit configuration */
- Csi= 1<<31, /* carrier sense ignore (needed for full duplex) */
- Hbi= 1<<30, /* heartbeat ignore (needed for full duplex) */
- Atp= 1<<28, /* automatic padding of runt packets */
- Mxdma= 7<<20, /* maximum dma transfer field */
- Mxdma32= 4<<20, /* 4x32-bit words (32 bytes) */
- Mxdma64= 5<<20, /* 8x32-bit words (64 bytes) */
- Flth= 0x3F<<8,/* Tx fill threshold, units of 32 bytes (must be > Mxdma) */
- Drth= 0x3F<<0,/* Tx drain threshold (units of 32 bytes) */
- Flth128= 4<<8, /* fill at 128 bytes */
- Drth512= 16<<0, /* drain at 512 bytes */
- Rrxdp= 0x30, /* receive descriptor pointer */
- Rrxcfg= 0x34, /* receive configuration */
- Atx= 1<<28, /* accept transmit packets (needed for full duplex) */
- Rdrth= 0x1F<<1,/* Rx drain threshold (units of 32 bytes) */
- Rdrth64= 2<<1, /* drain at 64 bytes */
- Rccsr= 0x3C, /* CLKRUN control/status */
- Pmests= 1<<15, /* PME status */
- Rwcsr= 0x40, /* wake on lan control/status */
- Rpcr= 0x44, /* pause control/status */
- Rrfcr= 0x48, /* receive filter/match control */
- Rfen= 1<<31, /* receive filter enable */
- Aab= 1<<30, /* accept all broadcast */
- Aam= 1<<29, /* accept all multicast */
- Aau= 1<<28, /* accept all unicast */
- Apm= 1<<27, /* accept on perfect match */
- Apat= 0xF<<23,/* accept on pattern match */
- Aarp= 1<<22, /* accept ARP */
- Mhen= 1<<21, /* multicast hash enable */
- Uhen= 1<<20, /* unicast hash enable */
- Ulm= 1<<19, /* U/L bit mask */
- /* bits 0-9 are rfaddr */
- Rrfdr= 0x4C, /* receive filter/match data */
- Rbrar= 0x50, /* boot rom address */
- Rbrdr= 0x54, /* boot rom data */
- Rsrr= 0x58, /* silicon revision */
- Rmibc= 0x5C, /* MIB control */
- /* 60-78 MIB data */
-
- /* PHY registers */
- Rbmcr= 0x80, /* basic mode configuration */
- Reset= 1<<15,
- Sel100= 1<<13, /* select 100Mb/sec if no auto neg */
- Anena= 1<<12, /* auto negotiation enable */
- Anrestart= 1<<9, /* restart auto negotiation */
- Selfdx= 1<<8, /* select full duplex if no auto neg */
- Rbmsr= 0x84, /* basic mode status */
- Ancomp= 1<<5, /* autonegotiation complete */
- Rphyidr1= 0x88,
- Rphyidr2= 0x8C,
- Ranar= 0x90, /* autonegotiation advertisement */
- Ranlpar= 0x94, /* autonegotiation link partner ability */
- Raner= 0x98, /* autonegotiation expansion */
- Rannptr= 0x9C, /* autonegotiation next page TX */
- Rphysts= 0xC0, /* PHY status */
- Rmicr= 0xC4, /* MII control */
- Inten= 1<<1, /* PHY interrupt enable */
- Rmisr= 0xC8, /* MII status */
- Rfcscr= 0xD0, /* false carrier sense counter */
- Rrecr= 0xD4, /* receive error counter */
- Rpcsr= 0xD8, /* 100Mb config/status */
- Rphycr= 0xE4, /* PHY control */
- Rtbscr= 0xE8, /* 10BaseT status/control */
-};
-
-/*
- * eeprom addresses
- * 7 to 9 (16 bit words): mac address, shifted and reversed
- */
-
-#define csr32r(c, r) (inl((c)->port+(r)))
-#define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
-#define csr16r(c, r) (ins((c)->port+(r)))
-#define csr16w(c, r, l) (outs((c)->port+(r), (ulong)(l)))
-
-static void
-dumpcregs(Ctlr *ctlr)
-{
- int i;
-
- for(i=0; i<=0x5C; i+=4)
- print("%2.2ux %8.8lux\n", i, csr32r(ctlr, i));
-}
-
-static void
-promiscuous(void* arg, int on)
-{
- Ctlr *ctlr;
- ulong w;
-
- ctlr = ((Ether*)arg)->ctlr;
- ilock(&ctlr->lock);
- w = csr32r(ctlr, Rrfcr);
- if(on != ((w&Aau)!=0)){
- csr32w(ctlr, Rrfcr, w & ~Rfen);
- csr32w(ctlr, Rrfcr, Rfen | (w ^ Aau));
- }
- iunlock(&ctlr->lock);
-}
-
-static void
-attach(Ether* ether)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(&ctlr->lock);
- if(0)
- dumpcregs(ctlr);
- csr32w(ctlr, Rcr, Rxe);
- iunlock(&ctlr->lock);
-}
-
-static long
-ifstat(Ether* ether, void* a, long n, ulong offset)
-{
- Ctlr *ctlr;
- char *buf, *p;
- int i, l, len;
-
- ctlr = ether->ctlr;
-
- ether->crcs = ctlr->crce;
- ether->frames = ctlr->runt+ctlr->ise+ctlr->rlong+ctlr->fae;
- ether->buffs = ctlr->rxorn+ctlr->tfu;
- ether->overflows = ctlr->rxsovr;
-
- if(n == 0)
- return 0;
-
- p = malloc(READSTR);
- l = snprint(p, READSTR, "Rxa: %lud\n", ctlr->rxa);
- l += snprint(p+l, READSTR-l, "Rxo: %lud\n", ctlr->rxo);
- l += snprint(p+l, READSTR-l, "Rlong: %lud\n", ctlr->rlong);
- l += snprint(p+l, READSTR-l, "Runt: %lud\n", ctlr->runt);
- l += snprint(p+l, READSTR-l, "Ise: %lud\n", ctlr->ise);
- l += snprint(p+l, READSTR-l, "Fae: %lud\n", ctlr->fae);
- l += snprint(p+l, READSTR-l, "Lbp: %lud\n", ctlr->lbp);
- l += snprint(p+l, READSTR-l, "Tfu: %lud\n", ctlr->tfu);
- l += snprint(p+l, READSTR-l, "Txa: %lud\n", ctlr->txa);
- l += snprint(p+l, READSTR-l, "CRC Error: %lud\n", ctlr->crce);
- l += snprint(p+l, READSTR-l, "Collision Seen: %lud\n", ctlr->col);
- l += snprint(p+l, READSTR-l, "Frame Too Long: %lud\n", ctlr->rlong);
- l += snprint(p+l, READSTR-l, "Runt Frame: %lud\n", ctlr->runt);
- l += snprint(p+l, READSTR-l, "Rx Underflow Error: %lud\n", ctlr->rxorn);
- l += snprint(p+l, READSTR-l, "Tx Underrun: %lud\n", ctlr->txurn);
- l += snprint(p+l, READSTR-l, "Excessive Collisions: %lud\n", ctlr->ec);
- l += snprint(p+l, READSTR-l, "Late Collision: %lud\n", ctlr->owc);
- l += snprint(p+l, READSTR-l, "Loss of Carrier: %lud\n", ctlr->crs);
- l += snprint(p+l, READSTR-l, "Parity: %lud\n", ctlr->dperr);
- l += snprint(p+l, READSTR-l, "Aborts: %lud\n", ctlr->rmabt+ctlr->rtabt);
- l += snprint(p+l, READSTR-l, "RX Status overrun: %lud\n", ctlr->rxsover);
- snprint(p+l, READSTR-l, "ntqmax: %d\n", ctlr->ntqmax);
- ctlr->ntqmax = 0;
- buf = a;
- len = readstr(offset, buf, n, p);
- if(offset > l)
- offset -= l;
- else
- offset = 0;
- buf += len;
- n -= len;
-
- l = snprint(p, READSTR, "srom:");
- for(i = 0; i < nelem(ctlr->srom); i++){
- if(i && ((i & 0x0F) == 0))
- l += snprint(p+l, READSTR-l, "\n ");
- l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->srom[i]);
- }
-
- snprint(p+l, READSTR-l, "\n");
- len += readstr(offset, buf, n, p);
- free(p);
-
- return len;
-}
-
-static void
-txstart(Ether* ether)
-{
- Ctlr *ctlr;
- Block *bp;
- Des *des;
- int started;
-
- ctlr = ether->ctlr;
- started = 0;
- while(ctlr->ntq < ctlr->ntdr-1){
- bp = qget(ether->oq);
- if(bp == nil)
- break;
- des = &ctlr->tdr[ctlr->tdrh];
- des->bp = bp;
- des->addr = PADDR(bp->rp);
- ctlr->ntq++;
- coherence();
- des->cmdsts = Own | BLEN(bp);
- ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);
- started = 1;
- }
- if(started){
- coherence();
- csr32w(ctlr, Rcr, Txe); /* prompt */
- }
-
- if(ctlr->ntq > ctlr->ntqmax)
- ctlr->ntqmax = ctlr->ntq;
-}
-
-static void
-transmit(Ether* ether)
-{
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(&ctlr->tlock);
- txstart(ether);
- iunlock(&ctlr->tlock);
-}
-
-static void
-txrxcfg(Ctlr *ctlr, int txdrth)
-{
- ulong rx, tx;
-
- rx = csr32r(ctlr, Rrxcfg);
- tx = csr32r(ctlr, Rtxcfg);
- if(ctlr->fd){
- rx |= Atx;
- tx |= Csi | Hbi;
- }else{
- rx &= ~Atx;
- tx &= ~(Csi | Hbi);
- }
- tx &= ~(Mxdma|Drth|Flth);
- tx |= Mxdma64 | Flth128 | txdrth;
- csr32w(ctlr, Rtxcfg, tx);
- rx &= ~(Mxdma|Rdrth);
- rx |= Mxdma64 | Rdrth64;
- csr32w(ctlr, Rrxcfg, rx);
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
- int len, status, cmdsts, n;
- Ctlr *ctlr;
- Ether *ether;
- Des *des;
- Block *bp;
-
- ether = arg;
- ctlr = ether->ctlr;
-
- while((status = csr32r(ctlr, Risr)) != 0){
-
- status &= ~(Pme|Mib);
-
- if(status & Hiberr){
- if(status & Rxsovr)
- ctlr->rxsover++;
- if(status & Sserr)
- ctlr->sserr++;
- if(status & Dperr)
- ctlr->dperr++;
- if(status & Rmabt)
- ctlr->rmabt++;
- if(status & Rtabt)
- ctlr->rtabt++;
- status &= ~(Hiberr|Txrcmp|Rxrcmp|Rxsovr|Dperr|Sserr|Rmabt|Rtabt);
- }
-
- /* update link state */
- if(status&Phy){
- status &= ~Phy;
- csr32r(ctlr, Rcfg);
- n = csr32r(ctlr, Rcfg);
-// iprint("83815 phy %x %x\n", n, n&Lnksts);
- ether->link = (n&Lnksts) != 0;
- }
-
- /*
- * Received packets.
- */
- if(status & (Rxdesc|Rxok|Rxerr|Rxearly|Rxorn)){
- des = &ctlr->rdr[ctlr->rdrx];
- while((cmdsts = des->cmdsts) & Own){
- if((cmdsts&Ok) == 0){
- if(cmdsts & Rxa)
- ctlr->rxa++;
- if(cmdsts & Rxo)
- ctlr->rxo++;
- if(cmdsts & Long)
- ctlr->rlong++;
- if(cmdsts & Runt)
- ctlr->runt++;
- if(cmdsts & Ise)
- ctlr->ise++;
- if(cmdsts & Crce)
- ctlr->crce++;
- if(cmdsts & Fae)
- ctlr->fae++;
- if(cmdsts & Lbp)
- ctlr->lbp++;
- if(cmdsts & Col)
- ctlr->col++;
- }
- else if(bp = iallocb(Rbsz)){
- len = (cmdsts&Size)-4;
- if(len <= 0){
- debug("ns83815: packet len %d <=0\n", len);
- freeb(des->bp);
- }else{
- des->bp->wp = des->bp->rp+len;
- etheriq(ether, des->bp, 1);
- }
- des->bp = bp;
- des->addr = PADDR(bp->rp);
- coherence();
- }else{
- debug("ns83815: interrupt: iallocb for input buffer failed\n");
- des->bp->next = 0;
- }
-
- des->cmdsts = Rbsz;
- coherence();
-
- ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);
- des = &ctlr->rdr[ctlr->rdrx];
- }
- status &= ~(Rxdesc|Rxok|Rxerr|Rxearly|Rxorn);
- }
-
- /*
- * Check the transmit side:
- * check for Transmit Underflow and Adjust
- * the threshold upwards;
- * free any transmitted buffers and try to
- * top-up the ring.
- */
- if(status & Txurn){
- ctlr->txurn++;
- ilock(&ctlr->lock);
- /* change threshold */
- iunlock(&ctlr->lock);
- status &= ~(Txurn);
- }
-
- ilock(&ctlr->tlock);
- while(ctlr->ntq){
- des = &ctlr->tdr[ctlr->tdri];
- cmdsts = des->cmdsts;
- if(cmdsts & Own)
- break;
-
- if((cmdsts & Ok) == 0){
- if(cmdsts & Txa)
- ctlr->txa++;
- if(cmdsts & Tfu)
- ctlr->tfu++;
- if(cmdsts & Td)
- ctlr->td++;
- if(cmdsts & Ed)
- ctlr->ed++;
- if(cmdsts & Owc)
- ctlr->owc++;
- if(cmdsts & Ec)
- ctlr->ec++;
- ether->oerrs++;
- }
-
- freeb(des->bp);
- des->bp = nil;
- des->cmdsts = 0;
-
- ctlr->ntq--;
- ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr);
- }
- txstart(ether);
- iunlock(&ctlr->tlock);
-
- status &= ~(Txurn|Txidle|Txerr|Txdesc|Txok);
-
- /*
- * Anything left not catered for?
- */
- if(status)
- print("#l%d: status %8.8uX\n", ether->ctlrno, status);
- }
-}
-
-static void
-ctlrinit(Ether* ether)
-{
- Ctlr *ctlr;
- Des *des, *last;
-
- ctlr = ether->ctlr;
-
- /*
- * Allocate suitable aligned descriptors
- * for the transmit and receive rings;
- * initialise the receive ring;
- * initialise the transmit ring;
- * unmask interrupts and start the transmit side.
- */
- des = xspanalloc((ctlr->nrdr+ctlr->ntdr)*sizeof(Des), 32, 0);
- ctlr->tdr = des;
- ctlr->rdr = des+ctlr->ntdr;
-
- last = nil;
- for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
- des->bp = iallocb(Rbsz);
- if(des->bp == nil)
- error(Enomem);
- des->cmdsts = Rbsz;
- des->addr = PADDR(des->bp->rp);
- if(last != nil)
- last->next = PADDR(des);
- last = des;
- }
- ctlr->rdr[ctlr->nrdr-1].next = PADDR(ctlr->rdr);
- ctlr->rdrx = 0;
- csr32w(ctlr, Rrxdp, PADDR(ctlr->rdr));
-
- last = nil;
- for(des = ctlr->tdr; des < &ctlr->tdr[ctlr->ntdr]; des++){
- des->cmdsts = 0;
- des->bp = nil;
- des->addr = ~0;
- if(last != nil)
- last->next = PADDR(des);
- last = des;
- }
- ctlr->tdr[ctlr->ntdr-1].next = PADDR(ctlr->tdr);
- ctlr->tdrh = 0;
- ctlr->tdri = 0;
- csr32w(ctlr, Rtxdp, PADDR(ctlr->tdr));
-
- txrxcfg(ctlr, Drth512);
-
- csr32w(ctlr, Rimr, Dperr|Sserr|Rmabt|Rtabt|Rxsovr|Hiberr|Txurn|Txerr|
- Txdesc|Txok|Rxorn|Rxerr|Rxdesc|Rxok); /* Phy|Pme|Mib */
- csr32w(ctlr, Rmicr, Inten); /* enable phy interrupts */
- csr32r(ctlr, Risr); /* clear status */
- csr32w(ctlr, Rier, Ie);
-}
-
-static void
-eeclk(Ctlr *ctlr, int clk)
-{
- csr32w(ctlr, Rmear, Eesel | clk);
- microdelay(2);
-}
-
-static void
-eeidle(Ctlr *ctlr)
-{
- int i;
-
- eeclk(ctlr, 0);
- eeclk(ctlr, Eeclk);
- for(i=0; i<25; i++){
- eeclk(ctlr, 0);
- eeclk(ctlr, Eeclk);
- }
- eeclk(ctlr, 0);
- csr32w(ctlr, Rmear, 0);
- microdelay(2);
-}
-
-static int
-eegetw(Ctlr *ctlr, int a)
-{
- int d, i, w, v;
-
- eeidle(ctlr);
- eeclk(ctlr, 0);
- eeclk(ctlr, Eeclk);
- d = 0x180 | a;
- for(i=0x400; i; i>>=1){
- v = (d & i) ? Eedi : 0;
- eeclk(ctlr, v);
- eeclk(ctlr, Eeclk|v);
- }
- eeclk(ctlr, 0);
-
- w = 0;
- for(i=0x8000; i; i >>= 1){
- eeclk(ctlr, Eeclk);
- if(csr32r(ctlr, Rmear) & Eedo)
- w |= i;
- microdelay(2);
- eeclk(ctlr, 0);
- }
- eeidle(ctlr);
- return w;
-}
-
-static void
-resetctlr(Ctlr *ctlr)
-{
- int i;
-
- csr32w(ctlr, Rcr, Rst);
- for(i=0;; i++){
- if(i > 100)
- panic("ns83815: soft reset did not complete");
- microdelay(250);
- if((csr32r(ctlr, Rcr) & Rst) == 0)
- break;
- delay(1);
- }
-}
-
-static void
-shutdown(Ether* ether)
-{
- Ctlr *ctlr = ether->ctlr;
-
-print("ether83815 shutting down\n");
- csr32w(ctlr, Rcr, Rxd|Txd); /* disable transceiver */
- resetctlr(ctlr);
-}
-
-static void
-softreset(Ctlr* ctlr, int resetphys)
-{
- int i, w;
-
- /*
- * Soft-reset the controller
- */
- resetctlr(ctlr);
- csr32w(ctlr, Rccsr, Pmests);
- csr32w(ctlr, Rccsr, 0);
- csr32w(ctlr, Rcfg, csr32r(ctlr, Rcfg) | Pint_acen);
-
- if(resetphys){
- /*
- * Soft-reset the PHY
- */
- csr32w(ctlr, Rbmcr, Reset);
- for(i=0;; i++){
- if(i > 100)
- panic("ns83815: PHY soft reset time out");
- if((csr32r(ctlr, Rbmcr) & Reset) == 0)
- break;
- delay(1);
- }
- }
-
- /*
- * Initialisation values, in sequence (see 4.4 Recommended Registers Configuration)
- */
- csr16w(ctlr, 0xCC, 0x0001); /* PGSEL */
- csr16w(ctlr, 0xE4, 0x189C); /* PMCCSR */
- csr16w(ctlr, 0xFC, 0x0000); /* TSTDAT */
- csr16w(ctlr, 0xF4, 0x5040); /* DSPCFG */
- csr16w(ctlr, 0xF8, 0x008C); /* SDCFG */
-
- /*
- * Auto negotiate
- */
- w = csr16r(ctlr, Rbmsr); /* clear latched bits */
- debug("anar: %4.4ux\n", csr16r(ctlr, Ranar));
- csr16w(ctlr, Rbmcr, Anena);
- if(csr16r(ctlr, Ranar) == 0 || (csr32r(ctlr, Rcfg) & Aneg_dn) == 0){
- csr16w(ctlr, Rbmcr, Anena|Anrestart);
- for(i=0;; i++){
- if(i > 3000){
- print("ns83815: auto neg timed out\n");
- break;
- }
- if((w = csr16r(ctlr, Rbmsr)) & Ancomp)
- break;
- delay(1);
- }
- debug("%d ms\n", i);
- w &= 0xFFFF;
- debug("bmsr: %4.4ux\n", w);
- }
- USED(w);
- debug("anar: %4.4ux\n", csr16r(ctlr, Ranar));
- debug("anlpar: %4.4ux\n", csr16r(ctlr, Ranlpar));
- debug("aner: %4.4ux\n", csr16r(ctlr, Raner));
- debug("physts: %4.4ux\n", csr16r(ctlr, Rphysts));
- debug("tbscr: %4.4ux\n", csr16r(ctlr, Rtbscr));
-}
-
-static int
-media(Ether* ether)
-{
- Ctlr* ctlr;
- ulong cfg;
-
- ctlr = ether->ctlr;
- cfg = csr32r(ctlr, Rcfg);
- ctlr->fd = (cfg & Fdup) != 0;
- ether->link = (cfg&Lnksts) != 0;
- return (cfg&(Lnksts|Speed100)) == Lnksts? 10: 100;
-}
-
-static char* mediatable[9] = {
- "10BASE-T", /* TP */
- "10BASE-2", /* BNC */
- "10BASE-5", /* AUI */
- "100BASE-TX",
- "10BASE-TFD",
- "100BASE-TXFD",
- "100BASE-T4",
- "100BASE-FX",
- "100BASE-FXFD",
-};
-
-static int
-is630(ulong id, Pcidev *p)
-{
- if(id == SiS900)
- switch (p->rid) {
- case SiSrev630s:
- case SiSrev630e:
- case SiSrev630ea1:
- return 1;
- }
- return 0;
-}
-
-enum {
- MagicReg = 0x48,
- MagicRegSz = 1,
- Magicrden = 0x40, /* read enable, apparently */
- Paddr= 0x70, /* address port */
- Pdata= 0x71, /* data port */
-};
-
-/* rcmos() originally from LANL's SiS 900 driver's rcmos() */
-static int
-sisrdcmos(Ctlr *ctlr)
-{
- int i;
- unsigned reg;
- ulong port;
- Pcidev *p;
-
- debug("ns83815: SiS 630 rev. %ux reading mac address from cmos\n", ctlr->pcidev->rid);
- p = pcimatch(nil, SiS, SiS630bridge);
- if(p == nil) {
- print("ns83815: no SiS 630 rev. %ux bridge for mac addr\n",
- ctlr->pcidev->rid);
- return 0;
- }
- port = p->mem[0].bar & ~0x01;
- debug("ns83815: SiS 630 rev. %ux reading mac addr from cmos via bridge at port 0x%lux\n", ctlr->pcidev->rid, port);
-
- reg = pcicfgr8(p, MagicReg);
- pcicfgw8(p, MagicReg, reg|Magicrden);
-
- for (i = 0; i < Eaddrlen; i++) {
- outb(port+Paddr, SiS630eenodeaddr + i);
- ctlr->sromea[i] = inb(port+Pdata);
- }
-
- pcicfgw8(p, MagicReg, reg & ~Magicrden);
- return 1;
-}
-
-/*
- * If this is a SiS 630E chipset with an embedded SiS 900 controller,
- * we have to read the MAC address from the APC CMOS RAM. - sez freebsd.
- * However, CMOS *is* NVRAM normally. See devrtc.c:440, memory.c:88.
- */
-static void
-sissrom(Ctlr *ctlr)
-{
- union {
- uchar eaddr[Eaddrlen];
- ushort alignment;
- } ee;
- int i, off = SiSeenodeaddr, cnt = sizeof ee.eaddr / sizeof(short);
- ushort *shp = (ushort *)ee.eaddr;
-
- if(!is630(ctlr->id, ctlr->pcidev) || !sisrdcmos(ctlr)) {
- for (i = 0; i < cnt; i++)
- *shp++ = eegetw(ctlr, off++);
- memmove(ctlr->sromea, ee.eaddr, sizeof ctlr->sromea);
- }
-}
-
-static void
-nssrom(Ctlr* ctlr)
-{
- int i, j;
-
- for(i = 0; i < nelem(ctlr->srom); i++)
- ctlr->srom[i] = eegetw(ctlr, i);
-
- /*
- * the MAC address is reversed, straddling word boundaries
- */
- j = Nseenodeaddr*16 + 15;
- for(i=0; i<48; i++){
- ctlr->sromea[i>>3] |= ((ctlr->srom[j>>4] >> (15-(j&0xF))) & 1) << (i&7);
- j++;
- }
-}
-
-static void
-srom(Ctlr* ctlr)
-{
- memset(ctlr->sromea, 0, sizeof(ctlr->sromea));
- switch (ctlr->id) {
- case SiS900:
- case SiS7016:
- sissrom(ctlr);
- break;
- case Nat83815:
- nssrom(ctlr);
- break;
- default:
- print("ns83815: srom: unknown id 0x%ux\n", ctlr->id);
- break;
- }
-}
-
-static void
-scanpci83815(void)
-{
- Ctlr *ctlr;
- Pcidev *p;
- ulong id;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != Pcibcnet || p->ccru != 0)
- continue;
- id = (p->did<<16)|p->vid;
- switch(id){
- default:
- continue;
-
- case Nat83815:
- break;
- case SiS900:
- break;
- }
-
- /*
- * bar[0] is the I/O port register address and
- * bar[1] is the memory-mapped register address.
- */
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = p->mem[0].bar & ~0x01;
- ctlr->pcidev = p;
- ctlr->id = id;
-
- if(ioalloc(ctlr->port, p->mem[0].size, 0, "ns83815") < 0){
- print("ns83815: port 0x%uX in use\n", ctlr->port);
- free(ctlr);
- continue;
- }
-
- softreset(ctlr, 0);
- srom(ctlr);
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- }
-}
-
-/* multicast already on, don't need to do anything */
-static void
-multicast(void*, uchar*, int)
-{
-}
-
-static int
-reset(Ether* ether)
-{
- Ctlr *ctlr;
- int i, x;
- ulong ctladdr;
- uchar ea[Eaddrlen];
- static int scandone;
-
- if(scandone == 0){
- scanpci83815();
- scandone = 1;
- }
-
- /*
- * Any adapter matches if no ether->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(ether->port == 0 || ether->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- ether->ctlr = ctlr;
- ether->port = ctlr->port;
- ether->irq = ctlr->pcidev->intl;
- ether->tbdf = ctlr->pcidev->tbdf;
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the EEPROM and set in ether->ea prior to
- * loading the station address in the hardware.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, ether->ea, Eaddrlen) == 0)
- memmove(ether->ea, ctlr->sromea, Eaddrlen);
- for(i=0; i<Eaddrlen; i+=2){
- x = ether->ea[i] | (ether->ea[i+1]<<8);
- ctladdr = (ctlr->id == Nat83815? i: i<<15);
- csr32w(ctlr, Rrfcr, ctladdr);
- csr32w(ctlr, Rrfdr, x);
- }
- csr32w(ctlr, Rrfcr, Rfen|Apm|Aab|Aam);
-
- ether->mbps = media(ether);
-
- /*
- * Look for a medium override in case there's no autonegotiation
- * the autonegotiation fails.
- */
-
- for(i = 0; i < ether->nopt; i++){
- if(cistrcmp(ether->opt[i], "FD") == 0){
- ctlr->fd = 1;
- continue;
- }
- for(x = 0; x < nelem(mediatable); x++){
- debug("compare <%s> <%s>\n", mediatable[x],
- ether->opt[i]);
- if(cistrcmp(mediatable[x], ether->opt[i]) == 0){
- if(x != 4 && x >= 3)
- ether->mbps = 100;
- else
- ether->mbps = 10;
- switch(x){
- default:
- ctlr->fd = 0;
- break;
-
- case 0x04: /* 10BASE-TFD */
- case 0x05: /* 100BASE-TXFD */
- case 0x08: /* 100BASE-FXFD */
- ctlr->fd = 1;
- break;
- }
- break;
- }
- }
- }
-
- /*
- * Initialise descriptor rings, ethernet address.
- */
- ctlr->nrdr = Nrde;
- ctlr->ntdr = Ntde;
- pcisetbme(ctlr->pcidev);
- ctlrinit(ether);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = ifstat;
-
- ether->arg = ether;
- ether->promiscuous = promiscuous;
- ether->multicast = multicast;
- ether->shutdown = shutdown;
- return 0;
-}
-
-void
-ether83815link(void)
-{
- addethercard("83815", reset);
-}
diff --git a/os/pc/ether8390.c b/os/pc/ether8390.c
deleted file mode 100644
index 50d7ce39..00000000
--- a/os/pc/ether8390.c
+++ /dev/null
@@ -1,812 +0,0 @@
-/*
- * National Semiconductor DP8390 and clone
- * Network Interface Controller.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-#include "ether8390.h"
-
-enum { /* NIC core registers */
- Cr = 0x00, /* command register, all pages */
-
- /* Page 0, read */
- Clda0 = 0x01, /* current local DMA address 0 */
- Clda1 = 0x02, /* current local DMA address 1 */
- Bnry = 0x03, /* boundary pointer (R/W) */
- Tsr = 0x04, /* transmit status register */
- Ncr = 0x05, /* number of collisions register */
- Fifo = 0x06, /* FIFO */
- Isr = 0x07, /* interrupt status register (R/W) */
- Crda0 = 0x08, /* current remote DMA address 0 */
- Crda1 = 0x09, /* current remote DMA address 1 */
- Rsr = 0x0C, /* receive status register */
- Ref0 = 0x0D, /* frame alignment errors */
- Ref1 = 0x0E, /* CRC errors */
- Ref2 = 0x0F, /* missed packet errors */
-
- /* Page 0, write */
- Pstart = 0x01, /* page start register */
- Pstop = 0x02, /* page stop register */
- Tpsr = 0x04, /* transmit page start address */
- Tbcr0 = 0x05, /* transmit byte count register 0 */
- Tbcr1 = 0x06, /* transmit byte count register 1 */
- Rsar0 = 0x08, /* remote start address register 0 */
- Rsar1 = 0x09, /* remote start address register 1 */
- Rbcr0 = 0x0A, /* remote byte count register 0 */
- Rbcr1 = 0x0B, /* remote byte count register 1 */
- Rcr = 0x0C, /* receive configuration register */
- Tcr = 0x0D, /* transmit configuration register */
- Dcr = 0x0E, /* data configuration register */
- Imr = 0x0F, /* interrupt mask */
-
- /* Page 1, read/write */
- Par0 = 0x01, /* physical address register 0 */
- Curr = 0x07, /* current page register */
- Mar0 = 0x08, /* multicast address register 0 */
-};
-
-enum { /* Cr */
- Stp = 0x01, /* stop */
- Sta = 0x02, /* start */
- Txp = 0x04, /* transmit packet */
- Rd0 = 0x08, /* remote DMA command */
- Rd1 = 0x10,
- Rd2 = 0x20,
- RdREAD = Rd0, /* remote read */
- RdWRITE = Rd1, /* remote write */
- RdSEND = Rd1|Rd0, /* send packet */
- RdABORT = Rd2, /* abort/complete remote DMA */
- Ps0 = 0x40, /* page select */
- Ps1 = 0x80,
- Page0 = 0x00,
- Page1 = Ps0,
- Page2 = Ps1,
-};
-
-enum { /* Isr/Imr */
- Prx = 0x01, /* packet received */
- Ptx = 0x02, /* packet transmitted */
- Rxe = 0x04, /* receive error */
- Txe = 0x08, /* transmit error */
- Ovw = 0x10, /* overwrite warning */
- Cnt = 0x20, /* counter overflow */
- Rdc = 0x40, /* remote DMA complete */
- Rst = 0x80, /* reset status */
-};
-
-enum { /* Dcr */
- Wts = 0x01, /* word transfer select */
- Bos = 0x02, /* byte order select */
- Las = 0x04, /* long address select */
- Ls = 0x08, /* loopback select */
- Arm = 0x10, /* auto-initialise remote */
- Ft0 = 0x20, /* FIFO threshold select */
- Ft1 = 0x40,
- Ft1WORD = 0x00,
- Ft2WORD = Ft0,
- Ft4WORD = Ft1,
- Ft6WORD = Ft1|Ft0,
-};
-
-enum { /* Tcr */
- Crc = 0x01, /* inhibit CRC */
- Lb0 = 0x02, /* encoded loopback control */
- Lb1 = 0x04,
- LpbkNORMAL = 0x00, /* normal operation */
- LpbkNIC = Lb0, /* internal NIC module loopback */
- LpbkENDEC = Lb1, /* internal ENDEC module loopback */
- LpbkEXTERNAL = Lb1|Lb0, /* external loopback */
- Atd = 0x08, /* auto transmit disable */
- Ofst = 0x10, /* collision offset enable */
-};
-
-enum { /* Tsr */
- Ptxok = 0x01, /* packet transmitted */
- Col = 0x04, /* transmit collided */
- Abt = 0x08, /* tranmit aborted */
- Crs = 0x10, /* carrier sense lost */
- Fu = 0x20, /* FIFO underrun */
- Cdh = 0x40, /* CD heartbeat */
- Owc = 0x80, /* out of window collision */
-};
-
-enum { /* Rcr */
- Sep = 0x01, /* save errored packets */
- Ar = 0x02, /* accept runt packets */
- Ab = 0x04, /* accept broadcast */
- Am = 0x08, /* accept multicast */
- Pro = 0x10, /* promiscuous physical */
- Mon = 0x20, /* monitor mode */
-};
-
-enum { /* Rsr */
- Prxok = 0x01, /* packet received intact */
- Crce = 0x02, /* CRC error */
- Fae = 0x04, /* frame alignment error */
- Fo = 0x08, /* FIFO overrun */
- Mpa = 0x10, /* missed packet */
- Phy = 0x20, /* physical/multicast address */
- Dis = 0x40, /* receiver disabled */
- Dfr = 0x80, /* deferring */
-};
-
-typedef struct Hdr Hdr;
-struct Hdr {
- uchar status;
- uchar next;
- uchar len0;
- uchar len1;
-};
-
-void
-dp8390getea(Ether* ether, uchar* ea)
-{
- Dp8390 *ctlr;
- uchar cr;
- int i;
-
- ctlr = ether->ctlr;
-
- /*
- * Get the ethernet address from the chip.
- * Take care to restore the command register
- * afterwards.
- */
- ilock(ctlr);
- cr = regr(ctlr, Cr) & ~Txp;
- regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
- for(i = 0; i < Eaddrlen; i++)
- ea[i] = regr(ctlr, Par0+i);
- regw(ctlr, Cr, cr);
- iunlock(ctlr);
-}
-
-void
-dp8390setea(Ether* ether)
-{
- int i;
- uchar cr;
- Dp8390 *ctlr;
-
- ctlr = ether->ctlr;
-
- /*
- * Set the ethernet address into the chip.
- * Take care to restore the command register
- * afterwards. Don't care about multicast
- * addresses as multicast is never enabled
- * (currently).
- */
- ilock(ctlr);
- cr = regr(ctlr, Cr) & ~Txp;
- regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
- for(i = 0; i < Eaddrlen; i++)
- regw(ctlr, Par0+i, ether->ea[i]);
- regw(ctlr, Cr, cr);
- iunlock(ctlr);
-}
-
-static void*
-_dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len)
-{
- uchar cr;
- int timo;
-
- /*
- * Read some data at offset 'from' in the card's memory
- * using the DP8390 remote DMA facility, and place it at
- * 'to' in main memory, via the I/O data port.
- */
- cr = regr(ctlr, Cr) & ~Txp;
- regw(ctlr, Cr, Page0|RdABORT|Sta);
- regw(ctlr, Isr, Rdc);
-
- /*
- * Set up the remote DMA address and count.
- */
- len = ROUNDUP(len, ctlr->width);
- regw(ctlr, Rbcr0, len & 0xFF);
- regw(ctlr, Rbcr1, (len>>8) & 0xFF);
- regw(ctlr, Rsar0, from & 0xFF);
- regw(ctlr, Rsar1, (from>>8) & 0xFF);
-
- /*
- * Start the remote DMA read and suck the data
- * out of the I/O port.
- */
- regw(ctlr, Cr, Page0|RdREAD|Sta);
- rdread(ctlr, to, len);
-
- /*
- * Wait for the remote DMA to complete. The timeout
- * is necessary because this routine may be called on
- * a non-existent chip during initialisation and, due
- * to the miracles of the bus, it's possible to get this
- * far and still be talking to a slot full of nothing.
- */
- for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--)
- ;
-
- regw(ctlr, Isr, Rdc);
- regw(ctlr, Cr, cr);
-
- return to;
-}
-
-void*
-dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len)
-{
- void *v;
-
- ilock(ctlr);
- v = _dp8390read(ctlr, to, from, len);
- iunlock(ctlr);
-
- return v;
-}
-
-static void*
-dp8390write(Dp8390* ctlr, ulong to, void* from, ulong len)
-{
- ulong crda;
- uchar cr;
- int timo, width;
-
-top:
- /*
- * Write some data to offset 'to' in the card's memory
- * using the DP8390 remote DMA facility, reading it at
- * 'from' in main memory, via the I/O data port.
- */
- cr = regr(ctlr, Cr) & ~Txp;
- regw(ctlr, Cr, Page0|RdABORT|Sta);
- regw(ctlr, Isr, Rdc);
-
- len = ROUNDUP(len, ctlr->width);
-
- /*
- * Set up the remote DMA address and count.
- * This is straight from the DP8390[12D] datasheet,
- * hence the initial set up for read.
- * Assumption here that the A7000 EtherV card will
- * never need a dummyrr.
- */
- if(ctlr->dummyrr && (ctlr->width == 1 || ctlr->width == 2)){
- if(ctlr->width == 2)
- width = 1;
- else
- width = 0;
- crda = to-1-width;
- regw(ctlr, Rbcr0, (len+1+width) & 0xFF);
- regw(ctlr, Rbcr1, ((len+1+width)>>8) & 0xFF);
- regw(ctlr, Rsar0, crda & 0xFF);
- regw(ctlr, Rsar1, (crda>>8) & 0xFF);
- regw(ctlr, Cr, Page0|RdREAD|Sta);
-
- for(timo=0;; timo++){
- if(timo > 10000){
- print("ether8390: dummyrr timeout; assuming nodummyrr\n");
- ctlr->dummyrr = 0;
- goto top;
- }
- crda = regr(ctlr, Crda0);
- crda |= regr(ctlr, Crda1)<<8;
- if(crda == to){
- /*
- * Start the remote DMA write and make sure
- * the registers are correct.
- */
- regw(ctlr, Cr, Page0|RdWRITE|Sta);
-
- crda = regr(ctlr, Crda0);
- crda |= regr(ctlr, Crda1)<<8;
- if(crda != to)
- panic("crda write %lud to %lud\n", crda, to);
-
- break;
- }
- }
- }
- else{
- regw(ctlr, Rsar0, to & 0xFF);
- regw(ctlr, Rsar1, (to>>8) & 0xFF);
- regw(ctlr, Rbcr0, len & 0xFF);
- regw(ctlr, Rbcr1, (len>>8) & 0xFF);
- regw(ctlr, Cr, Page0|RdWRITE|Sta);
- }
-
- /*
- * Pump the data into the I/O port
- * then wait for the remote DMA to finish.
- */
- rdwrite(ctlr, from, len);
- for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--)
- ;
-
- regw(ctlr, Isr, Rdc);
- regw(ctlr, Cr, cr);
-
- return (void*)to;
-}
-
-static void
-ringinit(Dp8390* ctlr)
-{
- regw(ctlr, Pstart, ctlr->pstart);
- regw(ctlr, Pstop, ctlr->pstop);
- regw(ctlr, Bnry, ctlr->pstop-1);
-
- regw(ctlr, Cr, Page1|RdABORT|Stp);
- regw(ctlr, Curr, ctlr->pstart);
- regw(ctlr, Cr, Page0|RdABORT|Stp);
-
- ctlr->nxtpkt = ctlr->pstart;
-}
-
-static uchar
-getcurr(Dp8390* ctlr)
-{
- uchar cr, curr;
-
- cr = regr(ctlr, Cr) & ~Txp;
- regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
- curr = regr(ctlr, Curr);
- regw(ctlr, Cr, cr);
-
- return curr;
-}
-
-static void
-receive(Ether* ether)
-{
- Dp8390 *ctlr;
- uchar curr, *p;
- Hdr hdr;
- ulong count, data, len;
- Block *bp;
-
- ctlr = ether->ctlr;
- for(curr = getcurr(ctlr); ctlr->nxtpkt != curr; curr = getcurr(ctlr)){
- data = ctlr->nxtpkt*Dp8390BufSz;
- if(ctlr->ram)
- memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr));
- else
- _dp8390read(ctlr, &hdr, data, sizeof(Hdr));
-
- /*
- * Don't believe the upper byte count, work it
- * out from the software next-page pointer and
- * the current next-page pointer.
- */
- if(hdr.next > ctlr->nxtpkt)
- len = hdr.next - ctlr->nxtpkt - 1;
- else
- len = (ctlr->pstop-ctlr->nxtpkt) + (hdr.next-ctlr->pstart) - 1;
- if(hdr.len0 > (Dp8390BufSz-sizeof(Hdr)))
- len--;
-
- len = ((len<<8)|hdr.len0)-4;
-
- /*
- * Chip is badly scrogged, reinitialise the ring.
- */
- if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop
- || len < 60 || len > sizeof(Etherpkt)){
- print("dp8390: H%2.2ux+%2.2ux+%2.2ux+%2.2ux,%lud\n",
- hdr.status, hdr.next, hdr.len0, hdr.len1, len);
- regw(ctlr, Cr, Page0|RdABORT|Stp);
- ringinit(ctlr);
- regw(ctlr, Cr, Page0|RdABORT|Sta);
-
- return;
- }
-
- /*
- * If it's a good packet read it in to the software buffer.
- * If the packet wraps round the hardware ring, read it in
- * two pieces.
- */
- if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok && (bp = iallocb(len))){
- p = bp->rp;
- bp->wp = p+len;
- data += sizeof(Hdr);
-
- if((data+len) >= ctlr->pstop*Dp8390BufSz){
- count = ctlr->pstop*Dp8390BufSz - data;
- if(ctlr->ram)
- memmove(p, (void*)(ether->mem+data), count);
- else
- _dp8390read(ctlr, p, data, count);
- p += count;
- data = ctlr->pstart*Dp8390BufSz;
- len -= count;
- }
- if(len){
- if(ctlr->ram)
- memmove(p, (void*)(ether->mem+data), len);
- else
- _dp8390read(ctlr, p, data, len);
- }
-
- /*
- * Copy the packet to whoever wants it.
- */
- etheriq(ether, bp, 1);
- }
-
- /*
- * Finished with this packet, update the
- * hardware and software ring pointers.
- */
- ctlr->nxtpkt = hdr.next;
-
- hdr.next--;
- if(hdr.next < ctlr->pstart)
- hdr.next = ctlr->pstop-1;
- regw(ctlr, Bnry, hdr.next);
- }
-}
-
-static void
-txstart(Ether* ether)
-{
- int len;
- Dp8390 *ctlr;
- Block *bp;
- uchar minpkt[ETHERMINTU], *rp;
-
- ctlr = ether->ctlr;
-
- /*
- * This routine is called both from the top level and from interrupt
- * level and expects to be called with ctlr already locked.
- */
- if(ctlr->txbusy)
- return;
- bp = qget(ether->oq);
- if(bp == nil)
- return;
-
- /*
- * Make sure the packet is of minimum length;
- * copy it to the card's memory by the appropriate means;
- * start the transmission.
- */
- len = BLEN(bp);
- rp = bp->rp;
- if(len < ETHERMINTU){
- rp = minpkt;
- memmove(rp, bp->rp, len);
- memset(rp+len, 0, ETHERMINTU-len);
- len = ETHERMINTU;
- }
-
- if(ctlr->ram)
- memmove((void*)(ether->mem+ctlr->tstart*Dp8390BufSz), rp, len);
- else
- dp8390write(ctlr, ctlr->tstart*Dp8390BufSz, rp, len);
- freeb(bp);
-
- regw(ctlr, Tbcr0, len & 0xFF);
- regw(ctlr, Tbcr1, (len>>8) & 0xFF);
- regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
-
- ether->outpackets++;
- ctlr->txbusy = 1;
-}
-
-static void
-transmit(Ether* ether)
-{
- Dp8390 *ctlr;
-
- ctlr = ether->ctlr;
-
- ilock(ctlr);
- txstart(ether);
- iunlock(ctlr);
-}
-
-static void
-overflow(Ether *ether)
-{
- Dp8390 *ctlr;
- uchar txp;
- int resend;
-
- ctlr = ether->ctlr;
-
- /*
- * The following procedure is taken from the DP8390[12D] datasheet,
- * it seems pretty adamant that this is what has to be done.
- */
- txp = regr(ctlr, Cr) & Txp;
- regw(ctlr, Cr, Page0|RdABORT|Stp);
- delay(2);
- regw(ctlr, Rbcr0, 0);
- regw(ctlr, Rbcr1, 0);
-
- resend = 0;
- if(txp && (regr(ctlr, Isr) & (Txe|Ptx)) == 0)
- resend = 1;
-
- regw(ctlr, Tcr, LpbkNIC);
- regw(ctlr, Cr, Page0|RdABORT|Sta);
- receive(ether);
- regw(ctlr, Isr, Ovw);
- regw(ctlr, Tcr, LpbkNORMAL);
-
- if(resend)
- regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
- Ether *ether;
- Dp8390 *ctlr;
- uchar isr, r;
-
- ether = arg;
- ctlr = ether->ctlr;
-
- /*
- * While there is something of interest,
- * clear all the interrupts and process.
- */
- ilock(ctlr);
- regw(ctlr, Imr, 0x00);
- while(isr = (regr(ctlr, Isr) & (Cnt|Ovw|Txe|Rxe|Ptx|Prx))){
- if(isr & Ovw){
- overflow(ether);
- regw(ctlr, Isr, Ovw);
- ether->overflows++;
- }
-
- /*
- * Packets have been received.
- * Take a spin round the ring.
- */
- if(isr & (Rxe|Prx)){
- receive(ether);
- regw(ctlr, Isr, Rxe|Prx);
- }
-
- /*
- * A packet completed transmission, successfully or
- * not. Start transmission on the next buffered packet,
- * and wake the output routine.
- */
- if(isr & (Txe|Ptx)){
- r = regr(ctlr, Tsr);
- if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){
- print("dp8390: Tsr %#2.2ux", r);
- ether->oerrs++;
- }
-
- regw(ctlr, Isr, Txe|Ptx);
-
- if(isr & Ptx)
- ether->outpackets++;
- ctlr->txbusy = 0;
- txstart(ether);
- }
-
- if(isr & Cnt){
- ether->frames += regr(ctlr, Ref0);
- ether->crcs += regr(ctlr, Ref1);
- ether->buffs += regr(ctlr, Ref2);
- regw(ctlr, Isr, Cnt);
- }
- }
- regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
- iunlock(ctlr);
-}
-
-static uchar allmar[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-static void
-setfilter(Ether *ether, Dp8390 *ctlr)
-{
- uchar r, cr;
- int i;
- uchar *mar;
-
- r = Ab;
- mar = 0;
- if(ether->prom){
- r |= Pro|Am;
- mar = allmar;
- } else if(ether->nmaddr){
- r |= Am;
- mar = ctlr->mar;
- }
- if(mar){
- cr = regr(ctlr, Cr) & ~Txp;
- regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
- for(i = 0; i < 8; i++)
- regw(ctlr, Mar0+i, *(mar++));
- regw(ctlr, Cr, cr);
- }
- regw(ctlr, Rcr, r);
-}
-
-static void
-promiscuous(void *arg, int )
-{
- Ether *ether;
- Dp8390 *ctlr;
-
- ether = arg;
- ctlr = ether->ctlr;
-
- ilock(ctlr);
- setfilter(ether, ctlr);
- iunlock(ctlr);
-}
-
-static void
-setbit(Dp8390 *ctlr, int bit, int on)
-{
- int i, h;
-
- i = bit/8;
- h = bit%8;
- if(on){
- if(++(ctlr->mref[bit]) == 1)
- ctlr->mar[i] |= 1<<h;
- } else {
- if(--(ctlr->mref[bit]) <= 0){
- ctlr->mref[bit] = 0;
- ctlr->mar[i] &= ~(1<<h);
- }
- }
-}
-
-static uchar reverse[64];
-
-static void
-multicast(void* arg, uchar *addr, int on)
-{
- Ether *ether;
- Dp8390 *ctlr;
- int i;
- ulong h;
-
- ether = arg;
- ctlr = ether->ctlr;
- if(reverse[1] == 0){
- for(i = 0; i < 64; i++)
- reverse[i] = ((i&1)<<5) | ((i&2)<<3) | ((i&4)<<1)
- | ((i&8)>>1) | ((i&16)>>3) | ((i&32)>>5);
- }
-
- /*
- * change filter bits
- */
- h = ethercrc(addr, 6);
- ilock(ctlr);
- setbit(ctlr, reverse[h&0x3f], on);
- setfilter(ether, ctlr);
- iunlock(ctlr);
-}
-
-static void
-attach(Ether* ether)
-{
- Dp8390 *ctlr;
- uchar r;
-
- ctlr = ether->ctlr;
-
- /*
- * Enable the chip for transmit/receive.
- * The init routine leaves the chip in monitor
- * mode. Clear the missed-packet counter, it
- * increments while in monitor mode.
- * Sometimes there's an interrupt pending at this
- * point but there's nothing in the Isr, so
- * any pending interrupts are cleared and the
- * mask of acceptable interrupts is enabled here.
- */
- r = Ab;
- if(ether->prom)
- r |= Pro;
- if(ether->nmaddr)
- r |= Am;
- ilock(ctlr);
- regw(ctlr, Isr, 0xFF);
- regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
- regw(ctlr, Rcr, r);
- r = regr(ctlr, Ref2);
- regw(ctlr, Tcr, LpbkNORMAL);
- iunlock(ctlr);
- USED(r);
-}
-
-static void
-disable(Dp8390* ctlr)
-{
- int timo;
-
- /*
- * Stop the chip. Set the Stp bit and wait for the chip
- * to finish whatever was on its tiny mind before it sets
- * the Rst bit.
- * The timeout is needed because there may not be a real
- * chip there if this is called when probing for a device
- * at boot.
- */
- regw(ctlr, Cr, Page0|RdABORT|Stp);
- regw(ctlr, Rbcr0, 0);
- regw(ctlr, Rbcr1, 0);
- for(timo = 10000; (regr(ctlr, Isr) & Rst) == 0 && timo; timo--)
- ;
-}
-
-int
-dp8390reset(Ether* ether)
-{
- Dp8390 *ctlr;
-
- ctlr = ether->ctlr;
-
- /*
- * This is the initialisation procedure described
- * as 'mandatory' in the datasheet, with references
- * to the 3C503 technical reference manual.
- */
- disable(ctlr);
- if(ctlr->width != 1)
- regw(ctlr, Dcr, Ft4WORD|Ls|Wts);
- else
- regw(ctlr, Dcr, Ft4WORD|Ls);
-
- regw(ctlr, Rbcr0, 0);
- regw(ctlr, Rbcr1, 0);
-
- regw(ctlr, Tcr, LpbkNIC);
- regw(ctlr, Rcr, Mon);
-
- /*
- * Init the ring hardware and software ring pointers.
- * Can't initialise ethernet address as it may not be
- * known yet.
- */
- ringinit(ctlr);
- regw(ctlr, Tpsr, ctlr->tstart);
-
- /*
- * Clear any pending interrupts and mask then all off.
- */
- regw(ctlr, Isr, 0xFF);
- regw(ctlr, Imr, 0);
-
- /*
- * Leave the chip initialised,
- * but in monitor mode.
- */
- regw(ctlr, Cr, Page0|RdABORT|Sta);
-
- /*
- * Set up the software configuration.
- */
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = 0;
-
- ether->promiscuous = promiscuous;
- ether->multicast = multicast;
- ether->arg = ether;
-
- return 0;
-}
diff --git a/os/pc/ether8390.h b/os/pc/ether8390.h
deleted file mode 100644
index b5bf6e55..00000000
--- a/os/pc/ether8390.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Ctlr for the boards using the National Semiconductor DP8390
- * and SMC 83C90 Network Interface Controller.
- * Common code is in ether8390.c.
- */
-typedef struct {
- Lock;
-
- ulong port; /* I/O address of 8390 */
- ulong data; /* I/O data port if no shared memory */
-
- uchar width; /* data transfer width in bytes */
- uchar ram; /* true if card has shared memory */
- uchar dummyrr; /* do dummy remote read */
-
- uchar nxtpkt; /* receive: software bndry */
- uchar pstart;
- uchar pstop;
-
- int txbusy; /* transmit */
- uchar tstart; /* 8390 ring addresses */
-
- uchar mar[8]; /* shadow multicast address registers */
- int mref[64]; /* reference counts for multicast groups */
-} Dp8390;
-
-#define Dp8390BufSz 256
-
-extern int dp8390reset(Ether*);
-extern void *dp8390read(Dp8390*, void*, ulong, ulong);
-extern void dp8390getea(Ether*, uchar*);
-extern void dp8390setea(Ether*);
-
-/*
- * x86-specific code.
- */
-#define regr(c, r) inb((c)->port+(r))
-#define regw(c, r, v) outb((c)->port+(r), (v))
-
-static void
-rdread(Dp8390* ctlr, void* to, int len)
-{
- switch(ctlr->width){
- default:
- panic("dp8390 rdread: width %d\n", ctlr->width);
- break;
-
- case 2:
- inss(ctlr->data, to, len/2);
- break;
-
- case 1:
- insb(ctlr->data, to, len);
- break;
- }
-}
-
-static void
-rdwrite(Dp8390* ctlr, void* from, int len)
-{
- switch(ctlr->width){
- default:
- panic("dp8390 rdwrite: width %d\n", ctlr->width);
- break;
-
- case 2:
- outss(ctlr->data, from, len/2);
- break;
-
- case 1:
- outsb(ctlr->data, from, len);
- break;
- }
-}
diff --git a/os/pc/etherdp83820.c b/os/pc/etherdp83820.c
deleted file mode 100644
index aeda3713..00000000
--- a/os/pc/etherdp83820.c
+++ /dev/null
@@ -1,1246 +0,0 @@
-/*
- * National Semiconductor DP83820
- * 10/100/1000 Mb/s Ethernet Network Interface Controller
- * (Gig-NIC).
- * Driver assumes little-endian and 32-bit host throughout.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-enum { /* Registers */
- Cr = 0x00, /* Command */
- Cfg = 0x04, /* Configuration and Media Status */
- Mear = 0x08, /* MII/EEPROM Access */
- Ptscr = 0x0C, /* PCI Test Control */
- Isr = 0x10, /* Interrupt Status */
- Imr = 0x14, /* Interrupt Mask */
- Ier = 0x18, /* Interrupt Enable */
- Ihr = 0x1C, /* Interrupt Holdoff */
- Txdp = 0x20, /* Transmit Descriptor Pointer */
- Txdphi = 0x24, /* Transmit Descriptor Pointer Hi */
- Txcfg = 0x28, /* Transmit Configuration */
- Gpior = 0x2C, /* General Purpose I/O Control */
- Rxdp = 0x30, /* Receive Descriptor Pointer */
- Rxdphi = 0x34, /* Receive Descriptor Pointer Hi */
- Rxcfg = 0x38, /* Receive Configuration */
- Pqcr = 0x3C, /* Priority Queueing Control */
- Wcsr = 0x40, /* Wake on LAN Control/Status */
- Pcr = 0x44, /* Pause Control/Status */
- Rfcr = 0x48, /* Receive Filter/Match Control */
- Rfdr = 0x4C, /* Receive Filter/Match Data */
- Brar = 0x50, /* Boot ROM Address */
- Brdr = 0x54, /* Boot ROM Data */
- Srr = 0x58, /* Silicon Revision */
- Mibc = 0x5C, /* MIB Control */
- Mibd = 0x60, /* MIB Data */
- Txdp1 = 0xA0, /* Txdp Priority 1 */
- Txdp2 = 0xA4, /* Txdp Priority 2 */
- Txdp3 = 0xA8, /* Txdp Priority 3 */
- Rxdp1 = 0xB0, /* Rxdp Priority 1 */
- Rxdp2 = 0xB4, /* Rxdp Priority 2 */
- Rxdp3 = 0xB8, /* Rxdp Priority 3 */
- Vrcr = 0xBC, /* VLAN/IP Receive Control */
- Vtcr = 0xC0, /* VLAN/IP Transmit Control */
- Vdr = 0xC4, /* VLAN Data */
- Ccsr = 0xCC, /* Clockrun Control/Status */
- Tbicr = 0xE0, /* TBI Control */
- Tbisr = 0xE4, /* TBI Status */
- Tanar = 0xE8, /* TBI ANAR */
- Tanlpar = 0xEC, /* TBI ANLPAR */
- Taner = 0xF0, /* TBI ANER */
- Tesr = 0xF4, /* TBI ESR */
-};
-
-enum { /* Cr */
- Txe = 0x00000001, /* Transmit Enable */
- Txd = 0x00000002, /* Transmit Disable */
- Rxe = 0x00000004, /* Receiver Enable */
- Rxd = 0x00000008, /* Receiver Disable */
- Txr = 0x00000010, /* Transmitter Reset */
- Rxr = 0x00000020, /* Receiver Reset */
- Swien = 0x00000080, /* Software Interrupt Enable */
- Rst = 0x00000100, /* Reset */
- TxpriSHFT = 9, /* Tx Priority Queue Select */
- TxpriMASK = 0x00001E00,
- RxpriSHFT = 13, /* Rx Priority Queue Select */
- RxpriMASK = 0x0001E000,
-};
-
-enum { /* Configuration and Media Status */
- Bem = 0x00000001, /* Big Endian Mode */
- Ext125 = 0x00000002, /* External 125MHz reference Select */
- Bromdis = 0x00000004, /* Disable Boot ROM interface */
- Pesel = 0x00000008, /* Parity Error Detection Action */
- Exd = 0x00000010, /* Excessive Deferral Abort */
- Pow = 0x00000020, /* Program Out of Window Timer */
- Sb = 0x00000040, /* Single Back-off */
- Reqalg = 0x00000080, /* PCI Bus Request Algorithm */
- Extstsen = 0x00000100, /* Extended Status Enable */
- Phydis = 0x00000200, /* Disable PHY */
- Phyrst = 0x00000400, /* Reset PHY */
- M64addren = 0x00000800, /* Master 64-bit Addressing Enable */
- Data64en = 0x00001000, /* 64-bit Data Enable */
- Pci64det = 0x00002000, /* PCI 64-bit Bus Detected */
- T64addren = 0x00004000, /* Target 64-bit Addressing Enable */
- Mwidis = 0x00008000, /* MWI Disable */
- Mrmdis = 0x00010000, /* MRM Disable */
- Tmrtest = 0x00020000, /* Timer Test Mode */
- Spdstsien = 0x00040000, /* PHY Spdsts Interrupt Enable */
- Lnkstsien = 0x00080000, /* PHY Lnksts Interrupt Enable */
- Dupstsien = 0x00100000, /* PHY Dupsts Interrupt Enable */
- Mode1000 = 0x00400000, /* 1000Mb/s Mode Control */
- Tbien = 0x01000000, /* Ten-Bit Interface Enable */
- Dupsts = 0x10000000, /* Full Duplex Status */
- Spdsts100 = 0x20000000, /* SPEED100 Input Pin Status */
- Spdsts1000 = 0x40000000, /* SPEED1000 Input Pin Status */
- Lnksts = 0x80000000, /* Link Status */
-};
-
-enum { /* MII/EEPROM Access */
- Eedi = 0x00000001, /* EEPROM Data In */
- Eedo = 0x00000002, /* EEPROM Data Out */
- Eeclk = 0x00000004, /* EEPROM Serial Clock */
- Eesel = 0x00000008, /* EEPROM Chip Select */
- Mdio = 0x00000010, /* MII Management Data */
- Mddir = 0x00000020, /* MII Management Direction */
- Mdc = 0x00000040, /* MII Management Clock */
-};
-
-enum { /* Interrupts */
- Rxok = 0x00000001, /* Rx OK */
- Rxdesc = 0x00000002, /* Rx Descriptor */
- Rxerr = 0x00000004, /* Rx Packet Error */
- Rxearly = 0x00000008, /* Rx Early Threshold */
- Rxidle = 0x00000010, /* Rx Idle */
- Rxorn = 0x00000020, /* Rx Overrun */
- Txok = 0x00000040, /* Tx Packet OK */
- Txdesc = 0x00000080, /* Tx Descriptor */
- Txerr = 0x00000100, /* Tx Packet Error */
- Txidle = 0x00000200, /* Tx Idle */
- Txurn = 0x00000400, /* Tx Underrun */
- Mib = 0x00000800, /* MIB Service */
- Swi = 0x00001000, /* Software Interrupt */
- Pme = 0x00002000, /* Power Management Event */
- Phy = 0x00004000, /* PHY Interrupt */
- Hibint = 0x00008000, /* High Bits Interrupt Set */
- Rxsovr = 0x00010000, /* Rx Status FIFO Overrun */
- Rtabt = 0x00020000, /* Received Target Abort */
- Rmabt = 0x00040000, /* Received Master Abort */
- Sserr = 0x00080000, /* Signalled System Error */
- Dperr = 0x00100000, /* Detected Parity Error */
- Rxrcmp = 0x00200000, /* Receive Reset Complete */
- Txrcmp = 0x00400000, /* Transmit Reset Complete */
- Rxdesc0 = 0x00800000, /* Rx Descriptor for Priority Queue 0 */
- Rxdesc1 = 0x01000000, /* Rx Descriptor for Priority Queue 1 */
- Rxdesc2 = 0x02000000, /* Rx Descriptor for Priority Queue 2 */
- Rxdesc3 = 0x04000000, /* Rx Descriptor for Priority Queue 3 */
- Txdesc0 = 0x08000000, /* Tx Descriptor for Priority Queue 0 */
- Txdesc1 = 0x10000000, /* Tx Descriptor for Priority Queue 1 */
- Txdesc2 = 0x20000000, /* Tx Descriptor for Priority Queue 2 */
- Txdesc3 = 0x40000000, /* Tx Descriptor for Priority Queue 3 */
-};
-
-enum { /* Interrupt Enable */
- Ien = 0x00000001, /* Interrupt Enable */
-};
-
-enum { /* Interrupt Holdoff */
- IhSHFT = 0, /* Interrupt Holdoff */
- IhMASK = 0x000000FF,
- Ihctl = 0x00000100, /* Interrupt Holdoff Control */
-};
-
-enum { /* Transmit Configuration */
- TxdrthSHFT = 0, /* Tx Drain Threshold */
- TxdrthMASK = 0x000000FF,
- FlthSHFT = 16, /* Tx Fill Threshold */
- FlthMASK = 0x0000FF00,
- Brstdis = 0x00080000, /* 1000Mb/s Burst Disable */
- MxdmaSHFT = 20, /* Max Size per Tx DMA Burst */
- MxdmaMASK = 0x00700000,
- Ecretryen = 0x00800000, /* Excessive Collision Retry Enable */
- Atp = 0x10000000, /* Automatic Transmit Padding */
- Mlb = 0x20000000, /* MAC Loopback */
- Hbi = 0x40000000, /* Heartbeat Ignore */
- Csi = 0x80000000, /* Carrier Sense Ignore */
-};
-
-enum { /* Receive Configuration */
- RxdrthSHFT = 1, /* Rx Drain Threshold */
- RxdrthMASK = 0x0000003E,
- Airl = 0x04000000, /* Accept In-Range Length Errored */
- Alp = 0x08000000, /* Accept Long Packets */
- Rxfd = 0x10000000, /* Receive Full Duplex */
- Stripcrc = 0x20000000, /* Strip CRC */
- Arp = 0x40000000, /* Accept Runt Packets */
- Aep = 0x80000000, /* Accept Errored Packets */
-};
-
-enum { /* Priority Queueing Control */
- Txpqen = 0x00000001, /* Transmit Priority Queuing Enable */
- Txfairen = 0x00000002, /* Transmit Fairness Enable */
- RxpqenSHFT = 2, /* Receive Priority Queue Enable */
- RxpqenMASK = 0x0000000C,
-};
-
-enum { /* Pause Control/Status */
- PscntSHFT = 0, /* Pause Counter Value */
- PscntMASK = 0x0000FFFF,
- Pstx = 0x00020000, /* Transmit Pause Frame */
- PsffloSHFT = 18, /* Rx Data FIFO Lo Threshold */
- PsffloMASK = 0x000C0000,
- PsffhiSHFT = 20, /* Rx Data FIFO Hi Threshold */
- PsffhiMASK = 0x00300000,
- PsstloSHFT = 22, /* Rx Stat FIFO Hi Threshold */
- PsstloMASK = 0x00C00000,
- PssthiSHFT = 24, /* Rx Stat FIFO Hi Threshold */
- PssthiMASK = 0x03000000,
- Psrcvd = 0x08000000, /* Pause Frame Received */
- Psact = 0x10000000, /* Pause Active */
- Psda = 0x20000000, /* Pause on Destination Address */
- Psmcast = 0x40000000, /* Pause on Multicast */
- Psen = 0x80000000, /* Pause Enable */
-};
-
-enum { /* Receive Filter/Match Control */
- RfaddrSHFT = 0, /* Extended Register Address */
- RfaddrMASK = 0x000003FF,
- Ulm = 0x00080000, /* U/L bit mask */
- Uhen = 0x00100000, /* Unicast Hash Enable */
- Mhen = 0x00200000, /* Multicast Hash Enable */
- Aarp = 0x00400000, /* Accept ARP Packets */
- ApatSHFT = 23, /* Accept on Pattern Match */
- ApatMASK = 0x07800000,
- Apm = 0x08000000, /* Accept on Perfect Match */
- Aau = 0x10000000, /* Accept All Unicast */
- Aam = 0x20000000, /* Accept All Multicast */
- Aab = 0x40000000, /* Accept All Broadcast */
- Rfen = 0x80000000, /* Rx Filter Enable */
-};
-
-enum { /* Receive Filter/Match Data */
- RfdataSHFT = 0, /* Receive Filter Data */
- RfdataMASK = 0x0000FFFF,
- BmaskSHFT = 16, /* Byte Mask */
- BmaskMASK = 0x00030000,
-};
-
-enum { /* MIB Control */
- Wrn = 0x00000001, /* Warning Test Indicator */
- Frz = 0x00000002, /* Freeze All Counters */
- Aclr = 0x00000004, /* Clear All Counters */
- Mibs = 0x00000008, /* MIB Counter Strobe */
-};
-
-enum { /* MIB Data */
- Nmibd = 11, /* Number of MIB Data Registers */
-};
-
-enum { /* VLAN/IP Receive Control */
- Vtden = 0x00000001, /* VLAN Tag Detection Enable */
- Vtren = 0x00000002, /* VLAN Tag Removal Enable */
- Dvtf = 0x00000004, /* Discard VLAN Tagged Frames */
- Dutf = 0x00000008, /* Discard Untagged Frames */
- Ipen = 0x00000010, /* IP Checksum Enable */
- Ripe = 0x00000020, /* Reject IP Checksum Errors */
- Rtcpe = 0x00000040, /* Reject TCP Checksum Errors */
- Rudpe = 0x00000080, /* Reject UDP Checksum Errors */
-};
-
-enum { /* VLAN/IP Transmit Control */
- Vgti = 0x00000001, /* VLAN Global Tag Insertion */
- Vppti = 0x00000002, /* VLAN Per-Packet Tag Insertion */
- Gchk = 0x00000004, /* Global Checksum Generation */
- Ppchk = 0x00000008, /* Per-Packet Checksum Generation */
-};
-
-enum { /* VLAN Data */
- VtypeSHFT = 0, /* VLAN Type Field */
- VtypeMASK = 0x0000FFFF,
- VtciSHFT = 16, /* VLAN Tag Control Information */
- VtciMASK = 0xFFFF0000,
-};
-
-enum { /* Clockrun Control/Status */
- Clkrunen = 0x00000001, /* CLKRUN Enable */
- Pmeen = 0x00000100, /* PME Enable */
- Pmests = 0x00008000, /* PME Status */
-};
-
-typedef struct {
- u32int link; /* Link to the next descriptor */
- u32int bufptr; /* pointer to data Buffer */
- int cmdsts; /* Command/Status */
- int extsts; /* optional Extended Status */
-
- Block* bp; /* Block containing bufptr */
- u32int unused; /* pad to 64-bit */
-} Desc;
-
-enum { /* Common cmdsts bits */
- SizeMASK = 0x0000FFFF, /* Descriptor Byte Count */
- SizeSHFT = 0,
- Ok = 0x08000000, /* Packet OK */
- Crc = 0x10000000, /* Suppress/Include CRC */
- Intr = 0x20000000, /* Interrupt on ownership transfer */
- More = 0x40000000, /* not last descriptor in a packet */
- Own = 0x80000000, /* Descriptor Ownership */
-};
-
-enum { /* Transmit cmdsts bits */
- CcntMASK = 0x000F0000, /* Collision Count */
- CcntSHFT = 16,
- Ec = 0x00100000, /* Excessive Collisions */
- Owc = 0x00200000, /* Out of Window Collision */
- Ed = 0x00400000, /* Excessive Deferral */
- Td = 0x00800000, /* Transmit Deferred */
- Crs = 0x01000000, /* Carrier Sense Lost */
- Tfu = 0x02000000, /* Transmit FIFO Underrun */
- Txa = 0x04000000, /* Transmit Abort */
-};
-
-enum { /* Receive cmdsts bits */
- Irl = 0x00010000, /* In-Range Length Error */
- Lbp = 0x00020000, /* Loopback Packet */
- Fae = 0x00040000, /* Frame Alignment Error */
- Crce = 0x00080000, /* CRC Error */
- Ise = 0x00100000, /* Invalid Symbol Error */
- Runt = 0x00200000, /* Runt Packet Received */
- Long = 0x00400000, /* Too Long Packet Received */
- DestMASK = 0x01800000, /* Destination Class */
- DestSHFT = 23,
- Rxo = 0x02000000, /* Receive Overrun */
- Rxa = 0x04000000, /* Receive Aborted */
-};
-
-enum { /* extsts bits */
- EvtciMASK = 0x0000FFFF, /* VLAN Tag Control Information */
- EvtciSHFT = 0,
- Vpkt = 0x00010000, /* VLAN Packet */
- Ippkt = 0x00020000, /* IP Packet */
- Iperr = 0x00040000, /* IP Checksum Error */
- Tcppkt = 0x00080000, /* TCP Packet */
- Tcperr = 0x00100000, /* TCP Checksum Error */
- Udppkt = 0x00200000, /* UDP Packet */
- Udperr = 0x00400000, /* UDP Checksum Error */
-};
-
-enum {
- Nrd = 256,
- Nrb = 4*Nrd,
- Rbsz = ROUNDUP(sizeof(Etherpkt)+8, 8),
- Ntd = 128,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
- int id;
-
- int eepromsz; /* address size in bits */
- ushort* eeprom;
-
- int* nic;
- int cfg;
- int imr;
-
- QLock alock; /* attach */
- Lock ilock; /* init */
- void* alloc; /* base of per-Ctlr allocated data */
-
- Mii* mii;
-
- Lock rdlock; /* receive */
- Desc* rd;
- int nrd;
- int nrb;
- int rdx;
- int rxcfg;
-
- Lock tlock; /* transmit */
- Desc* td;
- int ntd;
- int tdh;
- int tdt;
- int ntq;
- int txcfg;
-
- int rxidle;
-
- uint mibd[Nmibd];
-
- int ec;
- int owc;
- int ed;
- int crs;
- int tfu;
- int txa;
-} Ctlr;
-
-#define csr32r(c, r) (*((c)->nic+((r)/4)))
-#define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
-
-static Ctlr* dp83820ctlrhead;
-static Ctlr* dp83820ctlrtail;
-
-static Lock dp83820rblock; /* free receive Blocks */
-static Block* dp83820rbpool;
-
-static char* dp83820mibs[Nmibd] = {
- "RXErroredPkts",
- "RXFCSErrors",
- "RXMsdPktErrors",
- "RXFAErrors",
- "RXSymbolErrors",
- "RXFrameToLong",
- "RXIRLErrors",
- "RXBadOpcodes",
- "RXPauseFrames",
- "TXPauseFrames",
- "TXSQEErrors",
-};
-
-static int
-mdior(Ctlr* ctlr, int n)
-{
- int data, i, mear, r;
-
- mear = csr32r(ctlr, Mear);
- r = ~(Mdc|Mddir) & mear;
- data = 0;
- for(i = n-1; i >= 0; i--){
- if(csr32r(ctlr, Mear) & Mdio)
- data |= (1<<i);
- csr32w(ctlr, Mear, Mdc|r);
- csr32w(ctlr, Mear, r);
- }
- csr32w(ctlr, Mear, mear);
-
- return data;
-}
-
-static void
-mdiow(Ctlr* ctlr, int bits, int n)
-{
- int i, mear, r;
-
- mear = csr32r(ctlr, Mear);
- r = Mddir|(~Mdc & mear);
- for(i = n-1; i >= 0; i--){
- if(bits & (1<<i))
- r |= Mdio;
- else
- r &= ~Mdio;
- csr32w(ctlr, Mear, r);
- csr32w(ctlr, Mear, Mdc|r);
- }
- csr32w(ctlr, Mear, mear);
-}
-
-static int
-dp83820miimir(Mii* mii, int pa, int ra)
-{
- int data;
- Ctlr *ctlr;
-
- ctlr = mii->ctlr;
-
- /*
- * MII Management Interface Read.
- *
- * Preamble;
- * ST+OP+PA+RA;
- * LT + 16 data bits.
- */
- mdiow(ctlr, 0xFFFFFFFF, 32);
- mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
- data = mdior(ctlr, 18);
-
- if(data & 0x10000)
- return -1;
-
- return data & 0xFFFF;
-}
-
-static int
-dp83820miimiw(Mii* mii, int pa, int ra, int data)
-{
- Ctlr *ctlr;
-
- ctlr = mii->ctlr;
-
- /*
- * MII Management Interface Write.
- *
- * Preamble;
- * ST+OP+PA+RA+LT + 16 data bits;
- * Z.
- */
- mdiow(ctlr, 0xFFFFFFFF, 32);
- data &= 0xFFFF;
- data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
- mdiow(ctlr, data, 32);
-
- return 0;
-}
-
-static Block *
-dp83820rballoc(Desc* desc)
-{
- Block *bp;
-
- if(desc->bp == nil){
- ilock(&dp83820rblock);
- if((bp = dp83820rbpool) == nil){
- iunlock(&dp83820rblock);
- desc->bp = nil;
- desc->cmdsts = Own;
- return nil;
- }
- dp83820rbpool = bp->next;
- bp->next = nil;
- iunlock(&dp83820rblock);
-
- desc->bufptr = PCIWADDR(bp->rp);
- desc->bp = bp;
- }
- else{
- bp = desc->bp;
- bp->rp = bp->lim - Rbsz;
- bp->wp = bp->rp;
- }
-
- coherence();
- desc->cmdsts = Intr|Rbsz;
-
- return bp;
-}
-
-static void
-dp83820rbfree(Block *bp)
-{
- bp->rp = bp->lim - Rbsz;
- bp->wp = bp->rp;
-
- ilock(&dp83820rblock);
- bp->next = dp83820rbpool;
- dp83820rbpool = bp;
- iunlock(&dp83820rblock);
-}
-
-static void
-dp83820halt(Ctlr* ctlr)
-{
- int i, timeo;
-
- ilock(&ctlr->ilock);
- csr32w(ctlr, Imr, 0);
- csr32w(ctlr, Ier, 0);
- csr32w(ctlr, Cr, Rxd|Txd);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr32r(ctlr, Cr) & (Rxe|Txe)))
- break;
- microdelay(1);
- }
- csr32w(ctlr, Mibc, Frz);
- iunlock(&ctlr->ilock);
-
- if(ctlr->rd != nil){
- for(i = 0; i < ctlr->nrd; i++){
- if(ctlr->rd[i].bp == nil)
- continue;
- freeb(ctlr->rd[i].bp);
- ctlr->rd[i].bp = nil;
- }
- }
- if(ctlr->td != nil){
- for(i = 0; i < ctlr->ntd; i++){
- if(ctlr->td[i].bp == nil)
- continue;
- freeb(ctlr->td[i].bp);
- ctlr->td[i].bp = nil;
- }
- }
-}
-
-static void
-dp83820cfg(Ctlr* ctlr)
-{
- int cfg;
-
- /*
- * Don't know how to deal with a TBI yet.
- */
- if(ctlr->mii == nil)
- return;
-
- /*
- * The polarity of these bits is at the mercy
- * of the board designer.
- * The correct answer for all speed and duplex questions
- * should be to query the phy.
- */
- cfg = csr32r(ctlr, Cfg);
- if(!(cfg & Dupsts)){
- ctlr->rxcfg |= Rxfd;
- ctlr->txcfg |= Csi|Hbi;
- iprint("83820: full duplex, ");
- }
- else{
- ctlr->rxcfg &= ~Rxfd;
- ctlr->txcfg &= ~(Csi|Hbi);
- iprint("83820: half duplex, ");
- }
- csr32w(ctlr, Rxcfg, ctlr->rxcfg);
- csr32w(ctlr, Txcfg, ctlr->txcfg);
-
- switch(cfg & (Spdsts1000|Spdsts100)){
- case Spdsts1000: /* 100Mbps */
- default: /* 10Mbps */
- ctlr->cfg &= ~Mode1000;
- if((cfg & (Spdsts1000|Spdsts100)) == Spdsts1000)
- iprint("100Mb/s\n");
- else
- iprint("10Mb/s\n");
- break;
- case Spdsts100: /* 1Gbps */
- ctlr->cfg |= Mode1000;
- iprint("1Gb/s\n");
- break;
- }
- csr32w(ctlr, Cfg, ctlr->cfg);
-}
-
-static void
-dp83820init(Ether* edev)
-{
- int i;
- Ctlr *ctlr;
- Desc *desc;
- uchar *alloc;
-
- ctlr = edev->ctlr;
-
- dp83820halt(ctlr);
-
- /*
- * Receiver
- */
- alloc = (uchar*)ROUNDUP((ulong)ctlr->alloc, 8);
- ctlr->rd = (Desc*)alloc;
- alloc += ctlr->nrd*sizeof(Desc);
- memset(ctlr->rd, 0, ctlr->nrd*sizeof(Desc));
- ctlr->rdx = 0;
- for(i = 0; i < ctlr->nrd; i++){
- desc = &ctlr->rd[i];
- desc->link = PCIWADDR(&ctlr->rd[NEXT(i, ctlr->nrd)]);
- if(dp83820rballoc(desc) == nil)
- continue;
- }
- csr32w(ctlr, Rxdphi, 0);
- csr32w(ctlr, Rxdp, PCIWADDR(ctlr->rd));
-
- for(i = 0; i < Eaddrlen; i += 2){
- csr32w(ctlr, Rfcr, i);
- csr32w(ctlr, Rfdr, (edev->ea[i+1]<<8)|edev->ea[i]);
- }
- csr32w(ctlr, Rfcr, Rfen|Aab|Aam|Apm);
-
- ctlr->rxcfg = Stripcrc|(((2*(ETHERMINTU+4))/8)<<RxdrthSHFT);
- ctlr->imr |= Rxorn|Rxidle|Rxearly|Rxdesc|Rxok;
-
- /*
- * Transmitter.
- */
- ctlr->td = (Desc*)alloc;
- memset(ctlr->td, 0, ctlr->ntd*sizeof(Desc));
- ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
- for(i = 0; i < ctlr->ntd; i++){
- desc = &ctlr->td[i];
- desc->link = PCIWADDR(&ctlr->td[NEXT(i, ctlr->ntd)]);
- }
- csr32w(ctlr, Txdphi, 0);
- csr32w(ctlr, Txdp, PCIWADDR(ctlr->td));
-
- ctlr->txcfg = Atp|(((2*(ETHERMINTU+4))/32)<<FlthSHFT)|((4096/32)<<TxdrthSHFT);
- ctlr->imr |= Txurn|Txidle|Txdesc|Txok;
-
- ilock(&ctlr->ilock);
-
- dp83820cfg(ctlr);
-
- csr32w(ctlr, Mibc, Aclr);
- ctlr->imr |= Mib;
-
- csr32w(ctlr, Imr, ctlr->imr);
-
- /* try coalescing adjacent interrupts; use hold-off interval of 100µs */
- csr32w(ctlr, Ihr, Ihctl|(1<<IhSHFT));
-
- csr32w(ctlr, Ier, Ien);
- csr32w(ctlr, Cr, Rxe|Txe);
-
- iunlock(&ctlr->ilock);
-}
-
-static void
-dp83820attach(Ether* edev)
-{
- Block *bp;
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
- qlock(&ctlr->alock);
- if(ctlr->alloc != nil){
- qunlock(&ctlr->alock);
- return;
- }
-
- if(waserror()){
- if(ctlr->mii != nil){
- free(ctlr->mii);
- ctlr->mii = nil;
- }
- if(ctlr->alloc != nil){
- free(ctlr->alloc);
- ctlr->alloc = nil;
- }
- qunlock(&ctlr->alock);
- nexterror();
- }
-
- if(!(ctlr->cfg & Tbien)){
- if((ctlr->mii = malloc(sizeof(Mii))) == nil)
- error(Enomem);
- ctlr->mii->ctlr = ctlr;
- ctlr->mii->mir = dp83820miimir;
- ctlr->mii->miw = dp83820miimiw;
- if(mii(ctlr->mii, ~0) == 0)
- error("no PHY");
- ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien;
- ctlr->imr |= Phy;
- }
-
- ctlr->nrd = Nrd;
- ctlr->nrb = Nrb;
- ctlr->ntd = Ntd;
- ctlr->alloc = mallocz((ctlr->nrd+ctlr->ntd)*sizeof(Desc) + 7, 0);
- if(ctlr->alloc == nil)
- error(Enomem);
-
- for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
- if((bp = allocb(Rbsz)) == nil)
- break;
- bp->free = dp83820rbfree;
- dp83820rbfree(bp);
- }
-
- dp83820init(edev);
-
- qunlock(&ctlr->alock);
- poperror();
-}
-
-static void
-dp83820transmit(Ether* edev)
-{
- Block *bp;
- Ctlr *ctlr;
- Desc *desc;
- int cmdsts, r, x;
-
- ctlr = edev->ctlr;
-
- ilock(&ctlr->tlock);
-
- bp = nil;
- for(x = ctlr->tdh; ctlr->ntq; x = NEXT(x, ctlr->ntd)){
- desc = &ctlr->td[x];
- if((cmdsts = desc->cmdsts) & Own)
- break;
- if(!(cmdsts & Ok)){
- if(cmdsts & Ec)
- ctlr->ec++;
- if(cmdsts & Owc)
- ctlr->owc++;
- if(cmdsts & Ed)
- ctlr->ed++;
- if(cmdsts & Crs)
- ctlr->crs++;
- if(cmdsts & Tfu)
- ctlr->tfu++;
- if(cmdsts & Txa)
- ctlr->txa++;
- edev->oerrs++;
- }
- desc->bp->next = bp;
- bp = desc->bp;
- desc->bp = nil;
-
- ctlr->ntq--;
- }
- ctlr->tdh = x;
- if(bp != nil)
- freeblist(bp);
-
- x = ctlr->tdt;
- while(ctlr->ntq < (ctlr->ntd-1)){
- if((bp = qget(edev->oq)) == nil)
- break;
-
- desc = &ctlr->td[x];
- desc->bufptr = PCIWADDR(bp->rp);
- desc->bp = bp;
- ctlr->ntq++;
- coherence();
- desc->cmdsts = Own|Intr|BLEN(bp);
-
- x = NEXT(x, ctlr->ntd);
- }
- if(x != ctlr->tdt){
- ctlr->tdt = x;
- r = csr32r(ctlr, Cr);
- csr32w(ctlr, Cr, Txe|r);
- }
-
- iunlock(&ctlr->tlock);
-}
-
-static void
-dp83820interrupt(Ureg*, void* arg)
-{
- Block *bp;
- Ctlr *ctlr;
- Desc *desc;
- Ether *edev;
- int cmdsts, i, isr, r, x;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- for(isr = csr32r(ctlr, Isr); isr & ctlr->imr; isr = csr32r(ctlr, Isr)){
- if(isr & (Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok)){
- x = ctlr->rdx;
- desc = &ctlr->rd[x];
- while((cmdsts = desc->cmdsts) & Own){
- if((cmdsts & Ok) && desc->bp != nil){
- bp = desc->bp;
- desc->bp = nil;
- bp->wp += cmdsts & SizeMASK;
- etheriq(edev, bp, 1);
- }
- //else if(!(cmdsts & Ok)){
- // iprint("dp83820: rx %8.8uX:", cmdsts);
- // bp = desc->bp;
- // for(i = 0; i < 20; i++)
- // iprint(" %2.2uX", bp->rp[i]);
- // iprint("\n");
- //}
- dp83820rballoc(desc);
-
- x = NEXT(x, ctlr->nrd);
- desc = &ctlr->rd[x];
- }
- ctlr->rdx = x;
-
- if(isr & Rxidle){
- r = csr32r(ctlr, Cr);
- csr32w(ctlr, Cr, Rxe|r);
- ctlr->rxidle++;
- }
-
- isr &= ~(Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok);
- }
-
- if(isr & Txurn){
- x = (ctlr->txcfg & TxdrthMASK)>>TxdrthSHFT;
- r = (ctlr->txcfg & FlthMASK)>>FlthSHFT;
- if(x < ((TxdrthMASK)>>TxdrthSHFT)
- && x < (2048/32 - r)){
- ctlr->txcfg &= ~TxdrthMASK;
- x++;
- ctlr->txcfg |= x<<TxdrthSHFT;
- csr32w(ctlr, Txcfg, ctlr->txcfg);
- }
- }
-
- if(isr & (Txurn|Txidle|Txdesc|Txok)){
- dp83820transmit(edev);
- isr &= ~(Txurn|Txidle|Txdesc|Txok);
- }
-
- if(isr & Mib){
- for(i = 0; i < Nmibd; i++){
- r = csr32r(ctlr, Mibd+(i*sizeof(int)));
- ctlr->mibd[i] += r & 0xFFFF;
- }
- isr &= ~Mib;
- }
-
- if((isr & Phy) && ctlr->mii != nil){
- ctlr->mii->mir(ctlr->mii, 1, Bmsr);
- print("phy: cfg %8.8uX bmsr %4.4uX\n",
- csr32r(ctlr, Cfg),
- ctlr->mii->mir(ctlr->mii, 1, Bmsr));
- dp83820cfg(ctlr);
- isr &= ~Phy;
- }
- if(isr)
- iprint("dp83820: isr %8.8uX\n", isr);
- }
-}
-
-static long
-dp83820ifstat(Ether* edev, void* a, long n, ulong offset)
-{
- char *p;
- Ctlr *ctlr;
- int i, l, r;
-
- ctlr = edev->ctlr;
-
- edev->crcs = ctlr->mibd[Mibd+(1*sizeof(int))];
- edev->frames = ctlr->mibd[Mibd+(3*sizeof(int))];
- edev->buffs = ctlr->mibd[Mibd+(5*sizeof(int))];
- edev->overflows = ctlr->mibd[Mibd+(2*sizeof(int))];
-
- if(n == 0)
- return 0;
-
- p = malloc(READSTR);
- l = 0;
- for(i = 0; i < Nmibd; i++){
- r = csr32r(ctlr, Mibd+(i*sizeof(int)));
- ctlr->mibd[i] += r & 0xFFFF;
- if(ctlr->mibd[i] != 0 && dp83820mibs[i] != nil)
- l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
- dp83820mibs[i], ctlr->mibd[i], r);
- }
- l += snprint(p+l, READSTR-l, "rxidle %d\n", ctlr->rxidle);
- l += snprint(p+l, READSTR-l, "ec %d\n", ctlr->ec);
- l += snprint(p+l, READSTR-l, "owc %d\n", ctlr->owc);
- l += snprint(p+l, READSTR-l, "ed %d\n", ctlr->ed);
- l += snprint(p+l, READSTR-l, "crs %d\n", ctlr->crs);
- l += snprint(p+l, READSTR-l, "tfu %d\n", ctlr->tfu);
- l += snprint(p+l, READSTR-l, "txa %d\n", ctlr->txa);
-
- l += snprint(p+l, READSTR, "rom:");
- for(i = 0; i < 0x10; i++){
- if(i && ((i & 0x07) == 0))
- l += snprint(p+l, READSTR-l, "\n ");
- l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
- }
- l += snprint(p+l, READSTR-l, "\n");
-
- if(ctlr->mii != nil && ctlr->mii->curphy != nil){
- l += snprint(p+l, READSTR, "phy:");
- for(i = 0; i < NMiiPhyr; i++){
- if(i && ((i & 0x07) == 0))
- l += snprint(p+l, READSTR-l, "\n ");
- r = miimir(ctlr->mii, i);
- l += snprint(p+l, READSTR-l, " %4.4uX", r);
- }
- snprint(p+l, READSTR-l, "\n");
- }
-
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static void
-dp83820promiscuous(void* arg, int on)
-{
- USED(arg, on);
-}
-
-/* multicast already on, don't need to do anything */
-static void
-dp83820multicast(void*, uchar*, int)
-{
-}
-
-static int
-dp83820detach(Ctlr* ctlr)
-{
- /*
- * Soft reset the controller.
- */
- csr32w(ctlr, Cr, Rst);
- delay(1);
- while(csr32r(ctlr, Cr) & Rst)
- delay(1);
- return 0;
-}
-
-static void
-dp83820shutdown(Ether* ether)
-{
-print("dp83820shutdown\n");
- dp83820detach(ether->ctlr);
-}
-
-static int
-atc93c46r(Ctlr* ctlr, int address)
-{
- int data, i, mear, r, size;
-
- /*
- * Analog Technology, Inc. ATC93C46
- * or equivalent serial EEPROM.
- */
- mear = csr32r(ctlr, Mear);
- mear &= ~(Eesel|Eeclk|Eedo|Eedi);
- r = Eesel|mear;
-
-reread:
- csr32w(ctlr, Mear, r);
- data = 0x06;
- for(i = 3-1; i >= 0; i--){
- if(data & (1<<i))
- r |= Eedi;
- else
- r &= ~Eedi;
- csr32w(ctlr, Mear, r);
- csr32w(ctlr, Mear, Eeclk|r);
- microdelay(1);
- csr32w(ctlr, Mear, r);
- microdelay(1);
- }
-
- /*
- * First time through must work out the EEPROM size.
- */
- if((size = ctlr->eepromsz) == 0)
- size = 8;
-
- for(size = size-1; size >= 0; size--){
- if(address & (1<<size))
- r |= Eedi;
- else
- r &= ~Eedi;
- csr32w(ctlr, Mear, r);
- microdelay(1);
- csr32w(ctlr, Mear, Eeclk|r);
- microdelay(1);
- csr32w(ctlr, Mear, r);
- microdelay(1);
- if(!(csr32r(ctlr, Mear) & Eedo))
- break;
- }
- r &= ~Eedi;
-
- data = 0;
- for(i = 16-1; i >= 0; i--){
- csr32w(ctlr, Mear, Eeclk|r);
- microdelay(1);
- if(csr32r(ctlr, Mear) & Eedo)
- data |= (1<<i);
- csr32w(ctlr, Mear, r);
- microdelay(1);
- }
-
- csr32w(ctlr, Mear, mear);
-
- if(ctlr->eepromsz == 0){
- ctlr->eepromsz = 8-size;
- ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
- goto reread;
- }
-
- return data;
-}
-
-static int
-dp83820reset(Ctlr* ctlr)
-{
- int i, r;
- unsigned char sum;
-
- /*
- * Soft reset the controller;
- * read the EEPROM to get the initial settings
- * of the Cfg and Gpior bits which should be cleared by
- * the reset.
- */
- dp83820detach(ctlr);
-
- atc93c46r(ctlr, 0);
- if(ctlr->eeprom == nil) {
- print("dp83820reset: no eeprom\n");
- return -1;
- }
- sum = 0;
- for(i = 0; i < 0x0E; i++){
- r = atc93c46r(ctlr, i);
- ctlr->eeprom[i] = r;
- sum += r;
- sum += r>>8;
- }
-
- if(sum != 0){
- print("dp83820reset: bad EEPROM checksum\n");
- return -1;
- }
-
-#ifdef notdef
- csr32w(ctlr, Gpior, ctlr->eeprom[4]);
-
- cfg = Extstsen|Exd;
- r = csr32r(ctlr, Cfg);
- if(ctlr->eeprom[5] & 0x0001)
- cfg |= Ext125;
- if(ctlr->eeprom[5] & 0x0002)
- cfg |= M64addren;
- if((ctlr->eeprom[5] & 0x0004) && (r & Pci64det))
- cfg |= Data64en;
- if(ctlr->eeprom[5] & 0x0008)
- cfg |= T64addren;
- if(!(pcicfgr16(ctlr->pcidev, PciPCR) & 0x10))
- cfg |= Mwidis;
- if(ctlr->eeprom[5] & 0x0020)
- cfg |= Mrmdis;
- if(ctlr->eeprom[5] & 0x0080)
- cfg |= Mode1000;
- if(ctlr->eeprom[5] & 0x0200)
- cfg |= Tbien|Mode1000;
- /*
- * What about RO bits we might have destroyed with Rst?
- * What about Exd, Tmrtest, Extstsen, Pintctl?
- * Why does it think it has detected a 64-bit bus when
- * it hasn't?
- */
-#else
- //r = csr32r(ctlr, Cfg);
- //r &= ~(Mode1000|T64addren|Data64en|M64addren);
- //csr32w(ctlr, Cfg, r);
- //csr32w(ctlr, Cfg, 0x2000);
-#endif /* notdef */
- ctlr->cfg = csr32r(ctlr, Cfg);
-print("cfg %8.8uX pcicfg %8.8uX\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR));
- ctlr->cfg &= ~(T64addren|Data64en|M64addren);
- csr32w(ctlr, Cfg, ctlr->cfg);
- csr32w(ctlr, Mibc, Aclr|Frz);
-
- return 0;
-}
-
-static void
-dp83820pci(void)
-{
- void *mem;
- Pcidev *p;
- Ctlr *ctlr;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != Pcibcnet || p->ccru != Pciscether)
- continue;
-
- switch((p->did<<16)|p->vid){
- default:
- continue;
- case (0x0022<<16)|0x100B: /* DP83820 (Gig-NIC) */
- break;
- }
-
- mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
- if(mem == 0){
- print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
- continue;
- }
-
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = p->mem[1].bar & ~0x0F;
- ctlr->pcidev = p;
- ctlr->id = (p->did<<16)|p->vid;
-
- ctlr->nic = mem;
- if(dp83820reset(ctlr)){
- free(ctlr);
- continue;
- }
- pcisetbme(p);
-
- if(dp83820ctlrhead != nil)
- dp83820ctlrtail->next = ctlr;
- else
- dp83820ctlrhead = ctlr;
- dp83820ctlrtail = ctlr;
- }
-}
-
-static int
-dp83820pnp(Ether* edev)
-{
- int i;
- Ctlr *ctlr;
- uchar ea[Eaddrlen];
-
- if(dp83820ctlrhead == nil)
- dp83820pci();
-
- /*
- * Any adapter matches if no edev->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = dp83820ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(edev->port == 0 || edev->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- edev->ctlr = ctlr;
- edev->port = ctlr->port;
- edev->irq = ctlr->pcidev->intl;
- edev->tbdf = ctlr->pcidev->tbdf;
- edev->mbps = 1000;
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the EEPROM and set in ether->ea prior to
- * loading the station address in the hardware.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, edev->ea, Eaddrlen) == 0)
- for(i = 0; i < Eaddrlen/2; i++){
- edev->ea[2*i] = ctlr->eeprom[0x0C-i];
- edev->ea[2*i+1] = ctlr->eeprom[0x0C-i]>>8;
- }
-
- edev->attach = dp83820attach;
- edev->transmit = dp83820transmit;
- edev->interrupt = dp83820interrupt;
- edev->ifstat = dp83820ifstat;
-
- edev->arg = edev;
- edev->promiscuous = dp83820promiscuous;
- edev->multicast = dp83820multicast;
- edev->shutdown = dp83820shutdown;
-
- return 0;
-}
-
-void
-etherdp83820link(void)
-{
- addethercard("DP83820", dp83820pnp);
-}
diff --git a/os/pc/etherec2t.c b/os/pc/etherec2t.c
deleted file mode 100644
index c7625060..00000000
--- a/os/pc/etherec2t.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Supposed NE2000 PCMCIA clones, see the comments in ether2000.c
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-#include "ether8390.h"
-
-enum {
- Data = 0x10, /* offset from I/O base of data port */
- Reset = 0x1F, /* offset from I/O base of reset port */
-};
-
-typedef struct Ec2t {
- char* name;
- int iochecksum;
-} Ec2t;
-
-static Ec2t ec2tpcmcia[] = {
- { "EC2T", 0, }, /* Linksys Combo PCMCIA EthernetCard */
- { "PCMPC100", 1, }, /* EtherFast 10/100 PC Card */
- { "PCM100", 1, }, /* EtherFast PCM100 Card */
- { "EN2216", 0, }, /* Accton EtherPair-PCMCIA */
- { "FA410TX", 1, }, /* Netgear FA410TX */
- { "Network Everywhere", 0, }, /* Linksys NP10T 10BaseT Card */
- { "10/100 Port Attached", 1, }, /* SMC 8040TX */
- { "8041TX-10/100-PC-Card-V2", 0 }, /* SMC 8041TX */
- { "FA411", 0 }, /* Netgear FA411 PCMCIA */
- { nil, 0, },
-};
-
-static int
-reset(Ether* ether)
-{
- ushort buf[16];
- ulong port;
- Dp8390 *ctlr;
- int i, slot;
- uchar ea[Eaddrlen], sum, x;
- Ec2t *ec2t, tmpec2t;
-
- /*
- * Set up the software configuration.
- * Use defaults for port, irq, mem and size
- * if not specified.
- * The manual says 16KB memory, the box
- * says 32KB. The manual seems to be correct.
- */
- if(ether->port == 0)
- ether->port = 0x300;
- if(ether->irq == 0)
- ether->irq = 9;
- if(ether->mem == 0)
- ether->mem = 0x4000;
- if(ether->size == 0)
- ether->size = 16*1024;
- port = ether->port;
-
- if(ioalloc(ether->port, 0x20, 0, "ec2t") < 0)
- return -1;
- slot = -1;
- for(ec2t = ec2tpcmcia; ec2t->name != nil; ec2t++){
- if((slot = pcmspecial(ec2t->name, ether)) >= 0)
- break;
- }
- if(ec2t->name == nil){
- ec2t = &tmpec2t;
- ec2t->name = nil;
- ec2t->iochecksum = 0;
- for(i = 0; i < ether->nopt; i++){
- if(cistrncmp(ether->opt[i], "id=", 3) == 0){
- ec2t->name = &ether->opt[i][3];
- slot = pcmspecial(ec2t->name, ether);
- }
- else if(cistrncmp(ether->opt[i], "iochecksum", 10) == 0)
- ec2t->iochecksum = 1;
- }
- }
- if(slot < 0){
- iofree(port);
- return -1;
- }
-
- ether->ctlr = malloc(sizeof(Dp8390));
- ctlr = ether->ctlr;
- ctlr->width = 2;
- ctlr->ram = 0;
-
- ctlr->port = port;
- ctlr->data = port+Data;
-
- ctlr->tstart = HOWMANY(ether->mem, Dp8390BufSz);
- ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
- ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz);
-
- ctlr->dummyrr = 0;
- for(i = 0; i < ether->nopt; i++){
- if(cistrcmp(ether->opt[i], "nodummyrr") == 0)
- ctlr->dummyrr = 0;
- else if(cistrncmp(ether->opt[i], "dummyrr=", 8) == 0)
- ctlr->dummyrr = strtol(&ether->opt[i][8], nil, 0);
- }
-
- /*
- * Reset the board. This is done by doing a read
- * followed by a write to the Reset address.
- */
- buf[0] = inb(port+Reset);
- delay(2);
- outb(port+Reset, buf[0]);
- delay(2);
-
- /*
- * Init the (possible) chip, then use the (possible)
- * chip to read the (possible) PROM for ethernet address
- * and a marker byte.
- * Could just look at the DP8390 command register after
- * initialisation has been tried, but that wouldn't be
- * enough, there are other ethernet boards which could
- * match.
- */
- dp8390reset(ether);
- sum = 0;
- if(ec2t->iochecksum){
- /*
- * These cards have the ethernet address in I/O space.
- * There's a checksum over 8 bytes which sums to 0xFF.
- */
- for(i = 0; i < 8; i++){
- x = inb(port+0x14+i);
- sum += x;
- buf[i] = (x<<8)|x;
- }
- }
- else{
- memset(buf, 0, sizeof(buf));
- dp8390read(ctlr, buf, 0, sizeof(buf));
- if((buf[0x0E] & 0xFF) == 0x57 && (buf[0x0F] & 0xFF) == 0x57)
- sum = 0xFF;
- }
- if(sum != 0xFF){
- pcmspecialclose(slot);
- iofree(ether->port);
- free(ether->ctlr);
- return -1;
- }
-
- /*
- * Stupid machine. Shorts were asked for,
- * shorts were delivered, although the PROM is a byte array.
- * Set the ethernet address.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, ether->ea, Eaddrlen) == 0){
- for(i = 0; i < sizeof(ether->ea); i++)
- ether->ea[i] = buf[i];
- }
- dp8390setea(ether);
-
- return 0;
-}
-
-void
-etherec2tlink(void)
-{
- addethercard("EC2T", reset);
-}
diff --git a/os/pc/etherelnk3.c b/os/pc/etherelnk3.c
deleted file mode 100644
index 9c612b13..00000000
--- a/os/pc/etherelnk3.c
+++ /dev/null
@@ -1,2134 +0,0 @@
-/*
- * Etherlink III, Fast EtherLink and Fast EtherLink XL adapters.
- * To do:
- * check robustness in the face of errors (e.g. busmaster & rxUnderrun);
- * RxEarly and busmaster;
- * autoSelect;
- * PCI latency timer and master enable;
- * errata list;
- * rewrite all initialisation.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-#define XCVRDEBUG if(0)print
-
-enum {
- IDport = 0x0110, /* anywhere between 0x0100 and 0x01F0 */
-};
-
-enum { /* all windows */
- CommandR = 0x000E,
- IntStatusR = 0x000E,
-};
-
-enum { /* Commands */
- GlobalReset = 0x0000,
- SelectRegisterWindow = 0x0001,
- EnableDcConverter = 0x0002,
- RxDisable = 0x0003,
- RxEnable = 0x0004,
- RxReset = 0x0005,
- Stall = 0x0006, /* 3C90x */
- TxDone = 0x0007,
- RxDiscard = 0x0008,
- TxEnable = 0x0009,
- TxDisable = 0x000A,
- TxReset = 0x000B,
- RequestInterrupt = 0x000C,
- AcknowledgeInterrupt = 0x000D,
- SetInterruptEnable = 0x000E,
- SetIndicationEnable = 0x000F, /* SetReadZeroMask */
- SetRxFilter = 0x0010,
- SetRxEarlyThresh = 0x0011,
- SetTxAvailableThresh = 0x0012,
- SetTxStartThresh = 0x0013,
- StartDma = 0x0014, /* initiate busmaster operation */
- StatisticsEnable = 0x0015,
- StatisticsDisable = 0x0016,
- DisableDcConverter = 0x0017,
- SetTxReclaimThresh = 0x0018, /* PIO-only adapters */
- PowerUp = 0x001B, /* not all adapters */
- PowerDownFull = 0x001C, /* not all adapters */
- PowerAuto = 0x001D, /* not all adapters */
-};
-
-enum { /* (Global|Rx|Tx)Reset command bits */
- tpAuiReset = 0x0001, /* 10BaseT and AUI transceivers */
- endecReset = 0x0002, /* internal Ethernet encoder/decoder */
- networkReset = 0x0004, /* network interface logic */
- fifoReset = 0x0008, /* FIFO control logic */
- aismReset = 0x0010, /* autoinitialise state-machine logic */
- hostReset = 0x0020, /* bus interface logic */
- dmaReset = 0x0040, /* bus master logic */
- vcoReset = 0x0080, /* on-board 10Mbps VCO */
- updnReset = 0x0100, /* upload/download (Rx/TX) logic */
-
- resetMask = 0x01FF,
-};
-
-enum { /* Stall command bits */
- upStall = 0x0000,
- upUnStall = 0x0001,
- dnStall = 0x0002,
- dnUnStall = 0x0003,
-};
-
-enum { /* SetRxFilter command bits */
- receiveIndividual = 0x0001, /* match station address */
- receiveMulticast = 0x0002,
- receiveBroadcast = 0x0004,
- receiveAllFrames = 0x0008, /* promiscuous */
-};
-
-enum { /* StartDma command bits */
- Upload = 0x0000, /* transfer data from adapter to memory */
- Download = 0x0001, /* transfer data from memory to adapter */
-};
-
-enum { /* IntStatus bits */
- interruptLatch = 0x0001,
- hostError = 0x0002, /* Adapter Failure */
- txComplete = 0x0004,
- txAvailable = 0x0008,
- rxComplete = 0x0010,
- rxEarly = 0x0020,
- intRequested = 0x0040,
- updateStats = 0x0080,
- transferInt = 0x0100, /* Bus Master Transfer Complete */
- dnComplete = 0x0200,
- upComplete = 0x0400,
- busMasterInProgress = 0x0800,
- commandInProgress = 0x1000,
-
- interruptMask = 0x07FE,
-};
-
-#define COMMAND(port, cmd, a) outs((port)+CommandR, ((cmd)<<11)|(a))
-#define STATUS(port) ins((port)+IntStatusR)
-
-enum { /* Window 0 - setup */
- Wsetup = 0x0000,
- /* registers */
- ManufacturerID = 0x0000, /* 3C5[08]*, 3C59[27] */
- ProductID = 0x0002, /* 3C5[08]*, 3C59[27] */
- ConfigControl = 0x0004, /* 3C5[08]*, 3C59[27] */
- AddressConfig = 0x0006, /* 3C5[08]*, 3C59[27] */
- ResourceConfig = 0x0008, /* 3C5[08]*, 3C59[27] */
- EepromCommand = 0x000A,
- EepromData = 0x000C,
- /* AddressConfig Bits */
- autoSelect9 = 0x0080,
- xcvrMask9 = 0xC000,
- /* ConfigControl bits */
- Ena = 0x0001,
- base10TAvailable9 = 0x0200,
- coaxAvailable9 = 0x1000,
- auiAvailable9 = 0x2000,
- /* EepromCommand bits */
- EepromReadRegister = 0x0080,
- EepromReadOffRegister = 0x00B0,
- EepromRead8bRegister = 0x0230,
- EepromBusy = 0x8000,
-};
-
-#define EEPROMCMD(port, cmd, a) outs((port)+EepromCommand, (cmd)|(a))
-#define EEPROMBUSY(port) (ins((port)+EepromCommand) & EepromBusy)
-#define EEPROMDATA(port) ins((port)+EepromData)
-
-enum { /* Window 1 - operating set */
- Wop = 0x0001,
- /* registers */
- Fifo = 0x0000,
- RxError = 0x0004, /* 3C59[0257] only */
- RxStatus = 0x0008,
- TIMER = 0x000A,
- TxStatus = 0x000B,
- TxFree = 0x000C,
- /* RxError bits */
- rxOverrun = 0x0001,
- runtFrame = 0x0002,
- alignmentError = 0x0004, /* Framing */
- crcError = 0x0008,
- oversizedFrame = 0x0010,
- dribbleBits = 0x0080,
- /* RxStatus bits */
- rxBytes = 0x1FFF, /* 3C59[0257] mask */
- rxBytes9 = 0x07FF, /* 3C5[078]9 mask */
- rxError9 = 0x3800, /* 3C5[078]9 error mask */
- rxOverrun9 = 0x0000,
- oversizedFrame9 = 0x0800,
- dribbleBits9 = 0x1000,
- runtFrame9 = 0x1800,
- alignmentError9 = 0x2000, /* Framing */
- crcError9 = 0x2800,
- rxError = 0x4000,
- rxIncomplete = 0x8000,
- /* TxStatus Bits */
- txStatusOverflow = 0x0004,
- maxCollisions = 0x0008,
- txUnderrun = 0x0010,
- txJabber = 0x0020,
- interruptRequested = 0x0040,
- txStatusComplete = 0x0080,
-};
-
-enum { /* Window 2 - station address */
- Wstation = 0x0002,
-
- ResetOp905B = 0x000C,
-};
-
-enum { /* Window 3 - FIFO management */
- Wfifo = 0x0003,
- /* registers */
- InternalConfig = 0x0000, /* 3C509B, 3C589, 3C59[0257] */
- OtherInt = 0x0004, /* 3C59[0257] */
- RomControl = 0x0006, /* 3C509B, 3C59[27] */
- MacControl = 0x0006, /* 3C59[0257] */
- ResetOptions = 0x0008, /* 3C59[0257] */
- MediaOptions = 0x0008, /* 3C905B */
- RxFree = 0x000A,
- /* InternalConfig bits */
- disableBadSsdDetect = 0x00000100,
- ramLocation = 0x00000200, /* 0 external, 1 internal */
- ramPartition5to3 = 0x00000000,
- ramPartition3to1 = 0x00010000,
- ramPartition1to1 = 0x00020000,
- ramPartition3to5 = 0x00030000,
- ramPartitionMask = 0x00030000,
- xcvr10BaseT = 0x00000000,
- xcvrAui = 0x00100000, /* 10BASE5 */
- xcvr10Base2 = 0x00300000,
- xcvr100BaseTX = 0x00400000,
- xcvr100BaseFX = 0x00500000,
- xcvrMii = 0x00600000,
- xcvrMask = 0x00700000,
- autoSelect = 0x01000000,
- /* MacControl bits */
- deferExtendEnable = 0x0001,
- deferTIMERSelect = 0x001E, /* mask */
- fullDuplexEnable = 0x0020,
- allowLargePackets = 0x0040,
- extendAfterCollision = 0x0080, /* 3C90xB */
- flowControlEnable = 0x0100, /* 3C90xB */
- vltEnable = 0x0200, /* 3C90xB */
- /* ResetOptions bits */
- baseT4Available = 0x0001,
- baseTXAvailable = 0x0002,
- baseFXAvailable = 0x0004,
- base10TAvailable = 0x0008,
- coaxAvailable = 0x0010,
- auiAvailable = 0x0020,
- miiConnector = 0x0040,
-};
-
-enum { /* Window 4 - diagnostic */
- Wdiagnostic = 0x0004,
- /* registers */
- VcoDiagnostic = 0x0002,
- FifoDiagnostic = 0x0004,
- NetworkDiagnostic = 0x0006,
- PhysicalMgmt = 0x0008,
- MediaStatus = 0x000A,
- BadSSD = 0x000C,
- UpperBytesOk = 0x000D,
- /* FifoDiagnostic bits */
- txOverrun = 0x0400,
- rxUnderrun = 0x2000,
- receiving = 0x8000,
- /* PhysicalMgmt bits */
- mgmtClk = 0x0001,
- mgmtData = 0x0002,
- mgmtDir = 0x0004,
- cat5LinkTestDefeat = 0x8000,
- /* MediaStatus bits */
- dataRate100 = 0x0002,
- crcStripDisable = 0x0004,
- enableSqeStats = 0x0008,
- collisionDetect = 0x0010,
- carrierSense = 0x0020,
- jabberGuardEnable = 0x0040,
- linkBeatEnable = 0x0080,
- jabberDetect = 0x0200,
- polarityReversed = 0x0400,
- linkBeatDetect = 0x0800,
- txInProg = 0x1000,
- dcConverterEnabled = 0x4000,
- auiDisable = 0x8000, /* 10BaseT transceiver selected */
-};
-
-enum { /* Window 5 - internal state */
- Wstate = 0x0005,
- /* registers */
- TxStartThresh = 0x0000,
- TxAvailableThresh = 0x0002,
- RxEarlyThresh = 0x0006,
- RxFilter = 0x0008,
- InterruptEnable = 0x000A,
- IndicationEnable = 0x000C,
-};
-
-enum { /* Window 6 - statistics */
- Wstatistics = 0x0006,
- /* registers */
- CarrierLost = 0x0000,
- SqeErrors = 0x0001,
- MultipleColls = 0x0002,
- SingleCollFrames = 0x0003,
- LateCollisions = 0x0004,
- RxOverruns = 0x0005,
- FramesXmittedOk = 0x0006,
- FramesRcvdOk = 0x0007,
- FramesDeferred = 0x0008,
- UpperFramesOk = 0x0009,
- BytesRcvdOk = 0x000A,
- BytesXmittedOk = 0x000C,
-};
-
-enum { /* Window 7 - bus master operations */
- Wmaster = 0x0007,
- /* registers */
- MasterAddress = 0x0000,
- MasterLen = 0x0006,
- MasterStatus = 0x000C,
- /* MasterStatus bits */
- masterAbort = 0x0001,
- targetAbort = 0x0002,
- targetRetry = 0x0004,
- targetDisc = 0x0008,
- masterDownload = 0x1000,
- masterUpload = 0x4000,
- masterInProgress = 0x8000,
-
- masterMask = 0xD00F,
-};
-
-enum { /* 3C90x extended register set */
- TIMER905 = 0x001A, /* 8-bits */
- TxStatus905 = 0x001B, /* 8-bits */
- PktStatus = 0x0020, /* 32-bits */
- DnListPtr = 0x0024, /* 32-bits, 8-byte aligned */
- FragAddr = 0x0028, /* 32-bits */
- FragLen = 0x002C, /* 16-bits */
- ListOffset = 0x002E, /* 8-bits */
- TxFreeThresh = 0x002F, /* 8-bits */
- UpPktStatus = 0x0030, /* 32-bits */
- FreeTIMER = 0x0034, /* 16-bits */
- UpListPtr = 0x0038, /* 32-bits, 8-byte aligned */
-
- /* PktStatus bits */
- fragLast = 0x00000001,
- dnCmplReq = 0x00000002,
- dnStalled = 0x00000004,
- upCompleteX = 0x00000008,
- dnCompleteX = 0x00000010,
- upRxEarlyEnable = 0x00000020,
- armCountdown = 0x00000040,
- dnInProg = 0x00000080,
- counterSpeed = 0x00000010, /* 0 3.2uS, 1 320nS */
- countdownMode = 0x00000020,
- /* UpPktStatus bits (dpd->control) */
- upPktLenMask = 0x00001FFF,
- upStalled = 0x00002000,
- upError = 0x00004000,
- upPktComplete = 0x00008000,
- upOverrun = 0x00010000, /* RxError<<16 */
- upRuntFrame = 0x00020000,
- upAlignmentError = 0x00040000,
- upCRCError = 0x00080000,
- upOversizedFrame = 0x00100000,
- upDribbleBits = 0x00800000,
- upOverflow = 0x01000000,
-
- dnIndicate = 0x80000000, /* FrameStartHeader (dpd->control) */
-
- updnLastFrag = 0x80000000, /* (dpd->len) */
-
- Nup = 32,
- Ndn = 64,
-};
-
-/*
- * Up/Dn Packet Descriptors.
- * The hardware info (np, control, addr, len) must be 8-byte aligned
- * and this structure size must be a multiple of 8.
- */
-typedef struct Pd Pd;
-typedef struct Pd {
- ulong np; /* next pointer */
- ulong control; /* FSH or UpPktStatus */
- ulong addr;
- ulong len;
-
- Pd* next;
- Block* bp;
-} Pd;
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- int irq;
- Ctlr* next;
- int active;
- int did;
-
- Lock wlock; /* window access */
-
- int attached;
- int busmaster;
- Block* rbp; /* receive buffer */
-
- Block* txbp; /* FIFO -based transmission */
- int txthreshold;
- int txbusy;
-
- int nup; /* full-busmaster -based reception */
- void* upbase;
- Pd* upr;
- Pd* uphead;
-
- int ndn; /* full-busmaster -based transmission */
- void* dnbase;
- Pd* dnr;
- Pd* dnhead;
- Pd* dntail;
- int dnq;
-
- long interrupts; /* statistics */
- long bogusinterrupts;
- long timer[2];
- long stats[BytesRcvdOk+3];
-
- int upqmax;
- int upqmaxhw;
- ulong upinterrupts;
- ulong upqueued;
- ulong upstalls;
- int dnqmax;
- int dnqmaxhw;
- ulong dninterrupts;
- ulong dnqueued;
-
- int xcvr; /* transceiver type */
- int eepromcmd; /* EEPROM read command */
- int rxstatus9; /* old-style RxStatus register */
- int rxearly; /* RxEarlyThreshold */
- int ts; /* threshold shift */
- int upenabled;
- int dnenabled;
- ulong cbfnpa; /* CardBus functions */
- ulong* cbfn;
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-static void
-init905(Ctlr* ctlr)
-{
- Block *bp;
- Pd *pd, *prev;
-
- /*
- * Create rings for the receive and transmit sides.
- * Take care with alignment:
- * make sure ring base is 8-byte aligned;
- * make sure each entry is 8-byte aligned.
- */
- ctlr->upbase = malloc((ctlr->nup+1)*sizeof(Pd));
- ctlr->upr = (Pd*)ROUNDUP((ulong)ctlr->upbase, 8);
-
- prev = ctlr->upr;
- for(pd = &ctlr->upr[ctlr->nup-1]; pd >= ctlr->upr; pd--){
- pd->np = PADDR(&prev->np);
- pd->control = 0;
- bp = iallocb(sizeof(Etherpkt));
- if(bp == nil)
- panic("can't allocate ethernet receive ring");
- pd->addr = PADDR(bp->rp);
- pd->len = updnLastFrag|sizeof(Etherpkt);
-
- pd->next = prev;
- prev = pd;
- pd->bp = bp;
- }
- ctlr->uphead = ctlr->upr;
-
- ctlr->dnbase = malloc((ctlr->ndn+1)*sizeof(Pd));
- ctlr->dnr = (Pd*)ROUNDUP((ulong)ctlr->dnbase, 8);
-
- prev = ctlr->dnr;
- for(pd = &ctlr->dnr[ctlr->ndn-1]; pd >= ctlr->dnr; pd--){
- pd->next = prev;
- prev = pd;
- }
- ctlr->dnhead = ctlr->dnr;
- ctlr->dntail = ctlr->dnr;
- ctlr->dnq = 0;
-}
-
-static Block*
-rbpalloc(Block* (*f)(int))
-{
- Block *bp;
- ulong addr;
-
- /*
- * The receive buffers must be on a 32-byte
- * boundary for EISA busmastering.
- */
- if(bp = f(ROUNDUP(sizeof(Etherpkt), 4) + 31)){
- addr = (ulong)bp->base;
- addr = ROUNDUP(addr, 32);
- bp->rp = (uchar*)addr;
- }
-
- return bp;
-}
-
-static uchar*
-startdma(Ether* ether, ulong address)
-{
- int port, status, w;
- uchar *wp;
-
- port = ether->port;
-
- w = (STATUS(port)>>13) & 0x07;
- COMMAND(port, SelectRegisterWindow, Wmaster);
-
- wp = KADDR(inl(port+MasterAddress));
- status = ins(port+MasterStatus);
- if(status & (masterInProgress|targetAbort|masterAbort))
- print("#l%d: BM status 0x%uX\n", ether->ctlrno, status);
- outs(port+MasterStatus, masterMask);
- outl(port+MasterAddress, address);
- outs(port+MasterLen, sizeof(Etherpkt));
- COMMAND(port, StartDma, Upload);
-
- COMMAND(port, SelectRegisterWindow, w);
- return wp;
-}
-
-static void
-promiscuous(void* arg, int on)
-{
- int filter, port;
- Ether *ether;
-
- ether = (Ether*)arg;
- port = ether->port;
-
- filter = receiveBroadcast|receiveIndividual;
- if(ether->nmaddr)
- filter |= receiveMulticast;
- if(on)
- filter |= receiveAllFrames;
- COMMAND(port, SetRxFilter, filter);
-}
-
-static void
-multicast(void* arg, uchar *addr, int on)
-{
- int filter, port;
- Ether *ether;
-
- USED(addr, on);
-
- ether = (Ether*)arg;
- port = ether->port;
-
- filter = receiveBroadcast|receiveIndividual;
- if(ether->nmaddr)
- filter |= receiveMulticast;
- if(ether->prom)
- filter |= receiveAllFrames;
- COMMAND(port, SetRxFilter, filter);
-}
-
-/* On the 575B and C, interrupts need to be acknowledged in CardBus memory space */
-static void
-intrackcb(ulong *cbfn)
-{
- cbfn[1] = 0x8000;
-}
-
-static void
-attach(Ether* ether)
-{
- int port, x;
- Ctlr *ctlr;
-
- ctlr = ether->ctlr;
- ilock(&ctlr->wlock);
- if(ctlr->attached){
- iunlock(&ctlr->wlock);
- return;
- }
-
- port = ether->port;
-
- /*
- * Set the receiver packet filter for this and broadcast addresses,
- * set the interrupt masks for all interrupts, enable the receiver
- * and transmitter.
- */
- promiscuous(ether, ether->prom);
-
- x = interruptMask;
- if(ctlr->busmaster == 1)
- x &= ~(rxEarly|rxComplete);
- else{
- if(ctlr->dnenabled)
- x &= ~transferInt;
- if(ctlr->upenabled)
- x &= ~(rxEarly|rxComplete);
- }
- COMMAND(port, SetIndicationEnable, x);
- COMMAND(port, SetInterruptEnable, x);
- COMMAND(port, RxEnable, 0);
- COMMAND(port, TxEnable, 0);
-
- /*
- * If this is a CardBus card, acknowledge any interrupts.
- */
- if(ctlr->cbfn != nil)
- intrackcb(ctlr->cbfn);
-
- /*
- * Prime the busmaster channel for receiving directly into a
- * receive packet buffer if necessary.
- */
- if(ctlr->busmaster == 1)
- startdma(ether, PADDR(ctlr->rbp->rp));
- else{
- if(ctlr->upenabled)
- outl(port+UpListPtr, PADDR(&ctlr->uphead->np));
- }
-
- ctlr->attached = 1;
- iunlock(&ctlr->wlock);
-}
-
-static void
-statistics(Ether* ether)
-{
- int port, i, u, w;
- Ctlr *ctlr;
-
- port = ether->port;
- ctlr = ether->ctlr;
-
- /*
- * 3C59[27] require a read between a PIO write and
- * reading a statistics register.
- */
- w = (STATUS(port)>>13) & 0x07;
- COMMAND(port, SelectRegisterWindow, Wstatistics);
- STATUS(port);
-
- for(i = 0; i < UpperFramesOk; i++)
- ctlr->stats[i] += inb(port+i) & 0xFF;
- u = inb(port+UpperFramesOk) & 0xFF;
- ctlr->stats[FramesXmittedOk] += (u & 0x30)<<4;
- ctlr->stats[FramesRcvdOk] += (u & 0x03)<<8;
- ctlr->stats[BytesRcvdOk] += ins(port+BytesRcvdOk) & 0xFFFF;
- ctlr->stats[BytesRcvdOk+1] += ins(port+BytesXmittedOk) & 0xFFFF;
-
- switch(ctlr->xcvr){
-
- case xcvrMii:
- case xcvr100BaseTX:
- case xcvr100BaseFX:
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- STATUS(port);
- ctlr->stats[BytesRcvdOk+2] += inb(port+BadSSD);
- break;
- }
-
- COMMAND(port, SelectRegisterWindow, w);
-}
-
-static void
-txstart(Ether* ether)
-{
- int port, len;
- Ctlr *ctlr;
- Block *bp;
-
- port = ether->port;
- ctlr = ether->ctlr;
-
- /*
- * Attempt to top-up the transmit FIFO. If there's room simply
- * stuff in the packet length (unpadded to a dword boundary), the
- * packet data (padded) and remove the packet from the queue.
- * If there's no room post an interrupt for when there is.
- * This routine is called both from the top level and from interrupt
- * level and expects to be called with ctlr->wlock already locked
- * and the correct register window (Wop) in place.
- */
- for(;;){
- if(ctlr->txbp){
- bp = ctlr->txbp;
- ctlr->txbp = 0;
- }
- else{
- bp = qget(ether->oq);
- if(bp == nil)
- break;
- }
-
- len = ROUNDUP(BLEN(bp), 4);
- if(len+4 <= ins(port+TxFree)){
- outl(port+Fifo, BLEN(bp));
- outsl(port+Fifo, bp->rp, len/4);
-
- freeb(bp);
-
- ether->outpackets++;
- }
- else{
- ctlr->txbp = bp;
- if(ctlr->txbusy == 0){
- ctlr->txbusy = 1;
- COMMAND(port, SetTxAvailableThresh, len>>ctlr->ts);
- }
- break;
- }
- }
-}
-
-static void
-txstart905(Ether* ether)
-{
- Ctlr *ctlr;
- int port, stalled, timeo;
- Block *bp;
- Pd *pd;
-
- ctlr = ether->ctlr;
- port = ether->port;
-
- /*
- * Free any completed packets.
- */
- pd = ctlr->dntail;
- while(ctlr->dnq){
- if(PADDR(&pd->np) == inl(port+DnListPtr))
- break;
- if(pd->bp){
- freeb(pd->bp);
- pd->bp = nil;
- }
- ctlr->dnq--;
- pd = pd->next;
- }
- ctlr->dntail = pd;
-
- stalled = 0;
- while(ctlr->dnq < (ctlr->ndn-1)){
- bp = qget(ether->oq);
- if(bp == nil)
- break;
-
- pd = ctlr->dnhead->next;
- pd->np = 0;
- pd->control = dnIndicate|BLEN(bp);
- pd->addr = PADDR(bp->rp);
- pd->len = updnLastFrag|BLEN(bp);
- pd->bp = bp;
-
- if(stalled == 0 && ctlr->dnq && inl(port+DnListPtr)){
- COMMAND(port, Stall, dnStall);
- for(timeo = 100; (STATUS(port) & commandInProgress) && timeo; timeo--)
- ;
- if(timeo == 0)
- print("#l%d: dnstall %d\n", ether->ctlrno, timeo);
- stalled = 1;
- }
-
- coherence();
- ctlr->dnhead->np = PADDR(&pd->np);
- ctlr->dnhead->control &= ~dnIndicate;
- ctlr->dnhead = pd;
- if(ctlr->dnq == 0)
- ctlr->dntail = pd;
- ctlr->dnq++;
-
- ctlr->dnqueued++;
- }
-
- if(ctlr->dnq > ctlr->dnqmax)
- ctlr->dnqmax = ctlr->dnq;
-
- /*
- * If the adapter is not currently processing anything
- * and there is something on the queue, start it processing.
- */
- if(inl(port+DnListPtr) == 0 && ctlr->dnq)
- outl(port+DnListPtr, PADDR(&ctlr->dnhead->np));
- if(stalled)
- COMMAND(port, Stall, dnUnStall);
-}
-
-static void
-transmit(Ether* ether)
-{
- Ctlr *ctlr;
- int port, w;
-
- port = ether->port;
- ctlr = ether->ctlr;
-
- ilock(&ctlr->wlock);
- if(ctlr->dnenabled)
- txstart905(ether);
- else{
- w = (STATUS(port)>>13) & 0x07;
- COMMAND(port, SelectRegisterWindow, Wop);
- txstart(ether);
- COMMAND(port, SelectRegisterWindow, w);
- }
- iunlock(&ctlr->wlock);
-}
-
-static void
-receive905(Ether* ether)
-{
- Ctlr *ctlr;
- int len, port, q;
- Pd *pd;
- Block *bp;
-
- ctlr = ether->ctlr;
- port = ether->port;
-
- if(inl(port+UpPktStatus) & upStalled)
- ctlr->upstalls++;
- q = 0;
- for(pd = ctlr->uphead; pd->control & upPktComplete; pd = pd->next){
- if(pd->control & upError){
- if(pd->control & upOverrun)
- ether->overflows++;
- if(pd->control & (upOversizedFrame|upRuntFrame))
- ether->buffs++;
- if(pd->control & upAlignmentError)
- ether->frames++;
- if(pd->control & upCRCError)
- ether->crcs++;
- }
- else if(bp = iallocb(sizeof(Etherpkt)+4)){
- len = pd->control & rxBytes;
- pd->bp->wp = pd->bp->rp+len;
- etheriq(ether, pd->bp, 1);
- pd->bp = bp;
- pd->addr = PADDR(bp->rp);
- coherence();
- }
-
- pd->control = 0;
- COMMAND(port, Stall, upUnStall);
-
- q++;
- }
- ctlr->uphead = pd;
-
- ctlr->upqueued += q;
- if(q > ctlr->upqmax)
- ctlr->upqmax = q;
-}
-
-static void
-receive(Ether* ether)
-{
- int len, port, rxerror, rxstatus;
- Ctlr *ctlr;
- Block *bp;
-
- port = ether->port;
- ctlr = ether->ctlr;
-
- while(((rxstatus = ins(port+RxStatus)) & rxIncomplete) == 0){
- if(ctlr->busmaster == 1 && (STATUS(port) & busMasterInProgress))
- break;
-
- /*
- * If there was an error, log it and continue.
- * Unfortunately the 3C5[078]9 has the error info in the status register
- * and the 3C59[0257] implement a separate RxError register.
- */
- if(rxstatus & rxError){
- if(ctlr->rxstatus9){
- switch(rxstatus & rxError9){
-
- case rxOverrun9:
- ether->overflows++;
- break;
-
- case oversizedFrame9:
- case runtFrame9:
- ether->buffs++;
- break;
-
- case alignmentError9:
- ether->frames++;
- break;
-
- case crcError9:
- ether->crcs++;
- break;
-
- }
- }
- else{
- rxerror = inb(port+RxError);
- if(rxerror & rxOverrun)
- ether->overflows++;
- if(rxerror & (oversizedFrame|runtFrame))
- ether->buffs++;
- if(rxerror & alignmentError)
- ether->frames++;
- if(rxerror & crcError)
- ether->crcs++;
- }
- }
-
- /*
- * If there was an error or a new receive buffer can't be
- * allocated, discard the packet and go on to the next.
- */
- if((rxstatus & rxError) || (bp = rbpalloc(iallocb)) == 0){
- COMMAND(port, RxDiscard, 0);
- while(STATUS(port) & commandInProgress)
- ;
-
- if(ctlr->busmaster == 1)
- startdma(ether, PADDR(ctlr->rbp->rp));
-
- continue;
- }
-
- /*
- * A valid receive packet awaits:
- * if using PIO, read it into the buffer;
- * discard the packet from the FIFO;
- * if using busmastering, start a new transfer for
- * the next packet and as a side-effect get the
- * end-pointer of the one just received;
- * pass the packet on to whoever wants it.
- */
- if(ctlr->busmaster == 0 || ctlr->busmaster == 2){
- len = (rxstatus & rxBytes9);
- ctlr->rbp->wp = ctlr->rbp->rp + len;
- insl(port+Fifo, ctlr->rbp->rp, HOWMANY(len, 4));
- }
-
- COMMAND(port, RxDiscard, 0);
- while(STATUS(port) & commandInProgress)
- ;
-
- if(ctlr->busmaster == 1)
- ctlr->rbp->wp = startdma(ether, PADDR(bp->rp));
-
- etheriq(ether, ctlr->rbp, 1);
- ctlr->rbp = bp;
- }
-}
-
-static int
-ejectable(int did)
-{
- switch (did) {
- case 0x5157:
- return 1;
-
- default:
- return 0;
- }
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
- Ether *ether;
- int port, status, s, txstatus, w, x;
- Ctlr *ctlr;
-
- ether = arg;
- port = ether->port;
- ctlr = ether->ctlr;
-
- ilock(&ctlr->wlock);
- status = STATUS(port);
- if(!(status & (interruptMask|interruptLatch))){
- ctlr->bogusinterrupts++;
- iunlock(&ctlr->wlock);
- return;
- }
- w = (status>>13) & 0x07;
- COMMAND(port, SelectRegisterWindow, Wop);
-
- ctlr->interrupts++;
- if(ctlr->busmaster == 2)
- ctlr->timer[0] += inb(port+TIMER905) & 0xFF;
- else
- ctlr->timer[0] += inb(port+TIMER) & 0xFF;
-
- do{
- if(status & hostError){
- /*
- * Adapter failure, try to find out why, reset if
- * necessary. What happens if Tx is active and a reset
- * occurs, need to retransmit? This probably isn't right.
- */
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- x = ins(port+FifoDiagnostic);
- COMMAND(port, SelectRegisterWindow, Wop);
-
- if (status == 0xFFFF && x == 0xFFFF && ejectable(ctlr->did)) {
- print("#l%d: Card ejected?\n", ether->ctlrno);
- iunlock(&ctlr->wlock);
- return;
- }
-
- print("#l%d: status 0x%uX, diag 0x%uX\n",
- ether->ctlrno, status, x);
-
- if(x & txOverrun){
- if(ctlr->busmaster == 0)
- COMMAND(port, TxReset, 0);
- else
- COMMAND(port, TxReset, (updnReset|dmaReset));
- COMMAND(port, TxEnable, 0);
- }
-
- if(x & rxUnderrun){
- /*
- * This shouldn't happen...
- * Reset the receiver and restore the filter and RxEarly
- * threshold before re-enabling.
- * Need to restart any busmastering?
- */
- COMMAND(port, SelectRegisterWindow, Wstate);
- s = (port+RxFilter) & 0x000F;
- COMMAND(port, SelectRegisterWindow, Wop);
- COMMAND(port, RxReset, 0);
- while(STATUS(port) & commandInProgress)
- ;
- COMMAND(port, SetRxFilter, s);
- COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts);
- COMMAND(port, RxEnable, 0);
- }
-
- status &= ~hostError;
- }
-
- if(status & (transferInt|rxComplete)){
- receive(ether);
- status &= ~(transferInt|rxComplete);
- }
-
- if(status & (upComplete)){
- COMMAND(port, AcknowledgeInterrupt, upComplete);
- receive905(ether);
- status &= ~upComplete;
- ctlr->upinterrupts++;
- }
-
- if(status & txComplete){
- /*
- * Pop the TxStatus stack, accumulating errors.
- * Adjust the TX start threshold if there was an underrun.
- * If there was a Jabber or Underrun error, reset
- * the transmitter, taking care not to reset the dma logic
- * as a busmaster receive may be in progress.
- * For all conditions enable the transmitter.
- */
- if(ctlr->busmaster == 2)
- txstatus = port+TxStatus905;
- else
- txstatus = port+TxStatus;
- s = 0;
- do{
- if(x = inb(txstatus))
- outb(txstatus, 0);
- s |= x;
- }while(STATUS(port) & txComplete);
-
- if(s & txUnderrun){
- if(ctlr->dnenabled){
- while(inl(port+PktStatus) & dnInProg)
- ;
- }
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- while(ins(port+MediaStatus) & txInProg)
- ;
- COMMAND(port, SelectRegisterWindow, Wop);
- if(ctlr->txthreshold < ETHERMAXTU)
- ctlr->txthreshold += ETHERMINTU;
- }
-
- /*
- * According to the manual, maxCollisions does not require
- * a TxReset, merely a TxEnable. However, evidence points to
- * it being necessary on the 3C905. The jury is still out.
- * On busy or badly configured networks maxCollisions can
- * happen frequently enough for messages to be annoying so
- * keep quiet about them by popular request.
- */
- if(s & (txJabber|txUnderrun|maxCollisions)){
- if(ctlr->busmaster == 0)
- COMMAND(port, TxReset, 0);
- else
- COMMAND(port, TxReset, (updnReset|dmaReset));
- while(STATUS(port) & commandInProgress)
- ;
- COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);
- if(ctlr->busmaster == 2)
- outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
- if(ctlr->dnenabled)
- status |= dnComplete;
- }
-
- if(s & ~(txStatusComplete|maxCollisions))
- print("#l%d: txstatus 0x%uX, threshold %d\n",
- ether->ctlrno, s, ctlr->txthreshold);
- COMMAND(port, TxEnable, 0);
- ether->oerrs++;
- status &= ~txComplete;
- status |= txAvailable;
- }
-
- if(status & txAvailable){
- COMMAND(port, AcknowledgeInterrupt, txAvailable);
- ctlr->txbusy = 0;
- txstart(ether);
- status &= ~txAvailable;
- }
-
- if(status & dnComplete){
- COMMAND(port, AcknowledgeInterrupt, dnComplete);
- txstart905(ether);
- status &= ~dnComplete;
- ctlr->dninterrupts++;
- }
-
- if(status & updateStats){
- statistics(ether);
- status &= ~updateStats;
- }
-
- /*
- * Currently, this shouldn't happen.
- */
- if(status & rxEarly){
- COMMAND(port, AcknowledgeInterrupt, rxEarly);
- status &= ~rxEarly;
- }
-
- /*
- * Panic if there are any interrupts not dealt with.
- */
- if(status & interruptMask)
- panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);
-
- COMMAND(port, AcknowledgeInterrupt, interruptLatch);
- if(ctlr->cbfn != nil)
- intrackcb(ctlr->cbfn);
-
- }while((status = STATUS(port)) & (interruptMask|interruptLatch));
-
- if(ctlr->busmaster == 2)
- ctlr->timer[1] += inb(port+TIMER905) & 0xFF;
- else
- ctlr->timer[1] += inb(port+TIMER) & 0xFF;
-
- COMMAND(port, SelectRegisterWindow, w);
- iunlock(&ctlr->wlock);
-}
-
-static long
-ifstat(Ether* ether, void* a, long n, ulong offset)
-{
- char *p;
- int len;
- Ctlr *ctlr;
-
- if(n == 0)
- return 0;
-
- ctlr = ether->ctlr;
-
- ilock(&ctlr->wlock);
- statistics(ether);
- iunlock(&ctlr->wlock);
-
- p = malloc(READSTR);
- len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts);
- len += snprint(p+len, READSTR-len, "bogusinterrupts: %lud\n", ctlr->bogusinterrupts);
- len += snprint(p+len, READSTR-len, "timer: %lud %lud\n",
- ctlr->timer[0], ctlr->timer[1]);
- len += snprint(p+len, READSTR-len, "carrierlost: %lud\n",
- ctlr->stats[CarrierLost]);
- len += snprint(p+len, READSTR-len, "sqeerrors: %lud\n",
- ctlr->stats[SqeErrors]);
- len += snprint(p+len, READSTR-len, "multiplecolls: %lud\n",
- ctlr->stats[MultipleColls]);
- len += snprint(p+len, READSTR-len, "singlecollframes: %lud\n",
- ctlr->stats[SingleCollFrames]);
- len += snprint(p+len, READSTR-len, "latecollisions: %lud\n",
- ctlr->stats[LateCollisions]);
- len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n",
- ctlr->stats[RxOverruns]);
- len += snprint(p+len, READSTR-len, "framesxmittedok: %lud\n",
- ctlr->stats[FramesXmittedOk]);
- len += snprint(p+len, READSTR-len, "framesrcvdok: %lud\n",
- ctlr->stats[FramesRcvdOk]);
- len += snprint(p+len, READSTR-len, "framesdeferred: %lud\n",
- ctlr->stats[FramesDeferred]);
- len += snprint(p+len, READSTR-len, "bytesrcvdok: %lud\n",
- ctlr->stats[BytesRcvdOk]);
- len += snprint(p+len, READSTR-len, "bytesxmittedok: %lud\n",
- ctlr->stats[BytesRcvdOk+1]);
-
- if(ctlr->upenabled){
- if(ctlr->upqmax > ctlr->upqmaxhw)
- ctlr->upqmaxhw = ctlr->upqmax;
- len += snprint(p+len, READSTR-len, "up: q %lud i %lud m %d h %d s %lud\n",
- ctlr->upqueued, ctlr->upinterrupts,
- ctlr->upqmax, ctlr->upqmaxhw, ctlr->upstalls);
- ctlr->upqmax = 0;
- }
- if(ctlr->dnenabled){
- if(ctlr->dnqmax > ctlr->dnqmaxhw)
- ctlr->dnqmaxhw = ctlr->dnqmax;
- len += snprint(p+len, READSTR-len, "dn: q %lud i %lud m %d h %d\n",
- ctlr->dnqueued, ctlr->dninterrupts, ctlr->dnqmax, ctlr->dnqmaxhw);
- ctlr->dnqmax = 0;
- }
-
- snprint(p+len, READSTR-len, "badssd: %lud\n", ctlr->stats[BytesRcvdOk+2]);
-
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static void
-txrxreset(int port)
-{
- COMMAND(port, TxReset, 0);
- while(STATUS(port) & commandInProgress)
- ;
- COMMAND(port, RxReset, 0);
- while(STATUS(port) & commandInProgress)
- ;
-}
-
-static Ctlr*
-tcmadapter(int port, int irq, Pcidev* pcidev)
-{
- Ctlr *ctlr;
-
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = port;
- ctlr->irq = irq;
- ctlr->pcidev = pcidev;
- ctlr->eepromcmd = EepromReadRegister;
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
-
- return ctlr;
-}
-
-/*
- * Write two 0 bytes to identify the IDport and then reset the
- * ID sequence. Then send the ID sequence to the card to get
- * the card into command state.
- */
-static void
-idseq(void)
-{
- int i;
- uchar al;
- static int reset, untag;
-
- /*
- * One time only:
- * reset any adapters listening
- */
- if(reset == 0){
- outb(IDport, 0);
- outb(IDport, 0);
- outb(IDport, 0xC0);
- delay(20);
- reset = 1;
- }
-
- outb(IDport, 0);
- outb(IDport, 0);
- for(al = 0xFF, i = 0; i < 255; i++){
- outb(IDport, al);
- if(al & 0x80){
- al <<= 1;
- al ^= 0xCF;
- }
- else
- al <<= 1;
- }
-
- /*
- * One time only:
- * write ID sequence to get the attention of all adapters;
- * untag all adapters.
- * If a global reset is done here on all adapters it will confuse
- * any ISA cards configured for EISA mode.
- */
- if(untag == 0){
- outb(IDport, 0xD0);
- untag = 1;
- }
-}
-
-static ulong
-activate(void)
-{
- int i;
- ushort x, acr;
-
- /*
- * Do the little configuration dance:
- *
- * 2. write the ID sequence to get to command state.
- */
- idseq();
-
- /*
- * 3. Read the Manufacturer ID from the EEPROM.
- * This is done by writing the IDPort with 0x87 (0x80
- * is the 'read EEPROM' command, 0x07 is the offset of
- * the Manufacturer ID field in the EEPROM).
- * The data comes back 1 bit at a time.
- * A delay seems necessary between reading the bits.
- *
- * If the ID doesn't match, there are no more adapters.
- */
- outb(IDport, 0x87);
- delay(20);
- for(x = 0, i = 0; i < 16; i++){
- delay(20);
- x <<= 1;
- x |= inb(IDport) & 0x01;
- }
- if(x != 0x6D50)
- return 0;
-
- /*
- * 3. Read the Address Configuration from the EEPROM.
- * The Address Configuration field is at offset 0x08 in the EEPROM).
- */
- outb(IDport, 0x88);
- for(acr = 0, i = 0; i < 16; i++){
- delay(20);
- acr <<= 1;
- acr |= inb(IDport) & 0x01;
- }
-
- return (acr & 0x1F)*0x10 + 0x200;
-}
-
-static void
-tcm509isa(void)
-{
- int irq, port;
-
- /*
- * Attempt to activate all adapters. If adapter is set for
- * EISA mode (0x3F0), tag it and ignore. Otherwise, activate
- * it fully.
- */
- while(port = activate()){
- if(ioalloc(port, 0x10, 0, "tcm509isa") < 0){
- print("tcm509isa: port 0x%uX in use\n", port);
- continue;
- }
-
- /*
- * 6. Tag the adapter so it won't respond in future.
- */
- outb(IDport, 0xD1);
- if(port == 0x3F0){
- iofree(port);
- continue;
- }
-
- /*
- * 6. Activate the adapter by writing the Activate command
- * (0xFF).
- */
- outb(IDport, 0xFF);
- delay(20);
-
- /*
- * 8. Can now talk to the adapter's I/O base addresses.
- * Use the I/O base address from the acr just read.
- *
- * Enable the adapter and clear out any lingering status
- * and interrupts.
- */
- while(STATUS(port) & commandInProgress)
- ;
- COMMAND(port, SelectRegisterWindow, Wsetup);
- outs(port+ConfigControl, Ena);
-
- txrxreset(port);
- COMMAND(port, AcknowledgeInterrupt, 0xFF);
-
- irq = (ins(port+ResourceConfig)>>12) & 0x0F;
- tcmadapter(port, irq, nil);
- }
-}
-
-static void
-tcm5XXeisa(void)
-{
- ushort x;
- int irq, port, slot;
-
- /*
- * Check if this is an EISA machine.
- * If not, nothing to do.
- */
- if(strncmp((char*)KADDR(0xFFFD9), "EISA", 4))
- return;
-
- /*
- * Continue through the EISA slots looking for a match on both
- * 3COM as the manufacturer and 3C579-* or 3C59[27]-* as the product.
- * If an adapter is found, select window 0, enable it and clear
- * out any lingering status and interrupts.
- */
- for(slot = 1; slot < MaxEISA; slot++){
- port = slot*0x1000;
- if(ioalloc(port, 0x1000, 0, "tcm5XXeisa") < 0){
- print("tcm5XXeisa: port 0x%uX in use\n", port);
- continue;
- }
- if(ins(port+0xC80+ManufacturerID) != 0x6D50){
- iofree(port);
- continue;
- }
- x = ins(port+0xC80+ProductID);
- if((x & 0xF0FF) != 0x9050 && (x & 0xFF00) != 0x5900){
- iofree(port);
- continue;
- }
-
- COMMAND(port, SelectRegisterWindow, Wsetup);
- outs(port+ConfigControl, Ena);
-
- txrxreset(port);
- COMMAND(port, AcknowledgeInterrupt, 0xFF);
-
- irq = (ins(port+ResourceConfig)>>12) & 0x0F;
- tcmadapter(port, irq, nil);
- }
-}
-
-static void
-tcm59Xpci(void)
-{
- Pcidev *p;
- Ctlr *ctlr;
- int irq, port;
-
- p = nil;
- while(p = pcimatch(p, 0x10B7, 0)){
- if(p->ccrb != 0x02 || p->ccru != 0)
- continue;
- /*
- * Not prepared to deal with memory-mapped
- * devices yet.
- */
- if(!(p->mem[0].bar & 0x01))
- continue;
- port = p->mem[0].bar & ~0x01;
- if((port = ioalloc((port == 0)? -1: port, p->mem[0].size,
- 0, "tcm59Xpci")) < 0){
- print("tcm59Xpci: port 0x%uX in use\n", port);
- continue;
- }
- irq = p->intl;
-
- txrxreset(port);
- COMMAND(port, AcknowledgeInterrupt, 0xFF);
-
- ctlr = tcmadapter(port, irq, p);
- switch(p->did){
- default:
- break;
- case 0x5157:
- ctlr->eepromcmd = EepromRead8bRegister;
- ctlr->cbfnpa = p->mem[2].bar&~0x0F;
- ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
- break;
- case 0x6056:
- ctlr->eepromcmd = EepromReadOffRegister;
- ctlr->cbfnpa = p->mem[2].bar&~0x0F;
- ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
- break;
- }
- pcisetbme(p);
- }
-}
-
-static char* tcmpcmcia[] = {
- "3C589", /* 3COM 589[ABCD] */
- "3C562", /* 3COM 562 */
- "589E", /* 3COM Megahertz 589E */
- nil,
-};
-
-static Ctlr*
-tcm5XXpcmcia(Ether* ether)
-{
- int i;
- Ctlr *ctlr;
-
- if(ether->type == nil)
- return nil;
-
- for(i = 0; tcmpcmcia[i] != nil; i++){
- if(cistrcmp(ether->type, tcmpcmcia[i]))
- continue;
- ctlr = tcmadapter(ether->port, ether->irq, nil);
- ctlr->active = 1;
- return ctlr;
- }
-
- return nil;
-}
-
-static void
-setxcvr(Ctlr* ctlr, int xcvr)
-{
- int port, x;
-
- port = ctlr->port;
- if(ctlr->rxstatus9){
- COMMAND(port, SelectRegisterWindow, Wsetup);
- x = ins(port+AddressConfig) & ~xcvrMask9;
- x |= (xcvr>>20)<<14;
- outs(port+AddressConfig, x);
- }
- else{
- COMMAND(port, SelectRegisterWindow, Wfifo);
- x = inl(port+InternalConfig) & ~xcvrMask;
- x |= xcvr;
- outl(port+InternalConfig, x);
- }
-
- txrxreset(port);
-}
-
-static void
-setfullduplex(int port)
-{
- int x;
-
- COMMAND(port, SelectRegisterWindow, Wfifo);
- x = ins(port+MacControl);
- outs(port+MacControl, fullDuplexEnable|x);
-
- txrxreset(port);
-}
-
-static int
-miimdi(int port, int n)
-{
- int data, i;
-
- /*
- * Read n bits from the MII Management Register.
- */
- data = 0;
- for(i = n-1; i >= 0; i--){
- if(ins(port) & mgmtData)
- data |= (1<<i);
- microdelay(1);
- outs(port, mgmtClk);
- microdelay(1);
- outs(port, 0);
- microdelay(1);
- }
-
- return data;
-}
-
-static void
-miimdo(int port, int bits, int n)
-{
- int i, mdo;
-
- /*
- * Write n bits to the MII Management Register.
- */
- for(i = n-1; i >= 0; i--){
- if(bits & (1<<i))
- mdo = mgmtDir|mgmtData;
- else
- mdo = mgmtDir;
- outs(port, mdo);
- microdelay(1);
- outs(port, mdo|mgmtClk);
- microdelay(1);
- outs(port, mdo);
- microdelay(1);
- }
-}
-
-static int
-miir(int port, int phyad, int regad)
-{
- int data, w;
-
- w = (STATUS(port)>>13) & 0x07;
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- port += PhysicalMgmt;
-
- /*
- * Preamble;
- * ST+OP+PHYAD+REGAD;
- * TA + 16 data bits.
- */
- miimdo(port, 0xFFFFFFFF, 32);
- miimdo(port, 0x1800|(phyad<<5)|regad, 14);
- data = miimdi(port, 18);
-
- port -= PhysicalMgmt;
- COMMAND(port, SelectRegisterWindow, w);
-
- if(data & 0x10000)
- return -1;
-
- return data & 0xFFFF;
-}
-
-static int
-scanphy(int port)
-{
- int i, x;
-
- for(i = 0; i < 32; i++){
- if((x = miir(port, i, 2)) == -1 || x == 0)
- continue;
- x <<= 6;
- x |= miir(port, i, 3)>>10;
- XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(port, i, 1));
- USED(x);
-
- return i;
- }
- return 24;
-}
-
-static struct {
- char *name;
- int avail;
- int xcvr;
-} media[] = {
- "10BaseT", base10TAvailable, xcvr10BaseT,
- "10Base2", coaxAvailable, xcvr10Base2,
- "100BaseTX", baseTXAvailable, xcvr100BaseTX,
- "100BaseFX", baseFXAvailable, xcvr100BaseFX,
- "aui", auiAvailable, xcvrAui,
- "mii", miiConnector, xcvrMii
-};
-
-static int
-autoselect(Ctlr* ctlr)
-{
- int media, port, x;
-
- /*
- * Pathetic attempt at automatic media selection.
- * Really just to get the Fast Etherlink 10BASE-T/100BASE-TX
- * cards operational.
- * It's a bonus if it works for anything else.
- */
- port = ctlr->port;
- if(ctlr->rxstatus9){
- COMMAND(port, SelectRegisterWindow, Wsetup);
- x = ins(port+ConfigControl);
- media = 0;
- if(x & base10TAvailable9)
- media |= base10TAvailable;
- if(x & coaxAvailable9)
- media |= coaxAvailable;
- if(x & auiAvailable9)
- media |= auiAvailable;
- }
- else{
- COMMAND(port, SelectRegisterWindow, Wfifo);
- media = ins(port+ResetOptions);
- }
- XCVRDEBUG("autoselect: media %uX\n", media);
-
- if(media & miiConnector)
- return xcvrMii;
-
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- XCVRDEBUG("autoselect: media status %uX\n", ins(port+MediaStatus));
-
- if(media & baseTXAvailable){
- /*
- * Must have InternalConfig register.
- */
- setxcvr(ctlr, xcvr100BaseTX);
-
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
- outs(port+MediaStatus, linkBeatEnable|x);
- delay(10);
-
- if(ins(port+MediaStatus) & linkBeatDetect)
- return xcvr100BaseTX;
- outs(port+MediaStatus, x);
- }
-
- if(media & base10TAvailable){
- setxcvr(ctlr, xcvr10BaseT);
-
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- x = ins(port+MediaStatus) & ~dcConverterEnabled;
- outs(port+MediaStatus, linkBeatEnable|jabberGuardEnable|x);
- delay(100);
-
- XCVRDEBUG("autoselect: 10BaseT media status %uX\n", ins(port+MediaStatus));
- if(ins(port+MediaStatus) & linkBeatDetect)
- return xcvr10BaseT;
- outs(port+MediaStatus, x);
- }
-
- /*
- * Botch.
- */
- return autoSelect;
-}
-
-static int
-eepromdata(Ctlr* ctlr, int offset)
-{
- int port;
-
- port = ctlr->port;
-
- COMMAND(port, SelectRegisterWindow, Wsetup);
- while(EEPROMBUSY(port))
- ;
- EEPROMCMD(port, ctlr->eepromcmd, offset);
- while(EEPROMBUSY(port))
- ;
- return EEPROMDATA(port);
-}
-
-static void
-resetctlr(Ctlr *ctlr)
-{
- int x, port = ctlr->port;
-
- txrxreset(port);
- x = ins(port+ResetOp905B);
- XCVRDEBUG("905[BC] reset ops 0x%uX\n", x);
- x &= ~0x4010;
- if(ctlr->did == 0x5157){
- x |= 0x0010; /* Invert LED */
- outs(port+ResetOp905B, x);
- }
- if(ctlr->did == 0x6056){
- x |= 0x4000;
- outs(port+ResetOp905B, x);
-
- COMMAND(port, SelectRegisterWindow, Wsetup);
- outs(port, 0x0800);
- }
-}
-
-static void
-shutdown(Ether *ether)
-{
-print("etherelnk3 shutting down\n");
- resetctlr(ether->ctlr);
-}
-
-int
-etherelnk3reset(Ether* ether)
-{
- char *p;
- Ctlr *ctlr;
- uchar ea[Eaddrlen];
- static int scandone;
- int anar, anlpar, i, j, phyaddr, phystat, port, timeo, x;
-
- /*
- * Scan for adapter on PCI, EISA and finally
- * using the little ISA configuration dance.
- */
- if(scandone == 0){
- tcm59Xpci();
- tcm5XXeisa();
- tcm509isa();
- scandone = 1;
- }
-
- /*
- * Any adapter matches if no ether->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(ether->port == 0 || ether->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil && (ctlr = tcm5XXpcmcia(ether)) == 0)
- return -1;
-
- ether->ctlr = ctlr;
- port = ctlr->port;
- ether->port = port;
- ether->irq = ctlr->irq;
- if(ctlr->pcidev != nil)
- ether->tbdf = ctlr->pcidev->tbdf;
- else
- ether->tbdf = BUSUNKNOWN;
-
- /*
- * Read the DeviceID from the EEPROM, it's at offset 0x03,
- * and do something depending on capabilities.
- */
- switch(ctlr->did = eepromdata(ctlr, 0x03)){
- case 0x5157: /* 3C575 Cyclone */
- case 0x6056:
- /*FALLTHROUGH*/
- case 0x4500: /* 3C450 HomePNA Tornado */
- case 0x7646: /* 3CSOHO100-TX */
- case 0x9055: /* 3C905B-TX */
- case 0x9200: /* 3C905C-TX */
- case 0x9201: /* 3C920 */
- case 0x9805: /* 3C9805: 3C980-TX Python-T 10/100baseTX */
- /*FALLTHROUGH*/
- case 0x9000: /* 3C900-TPO */
- case 0x9001: /* 3C900-COMBO */
- case 0x9005: /* 3C900B-COMBO */
- case 0x9050: /* 3C905-TX */
- case 0x9051: /* 3C905-T4 */
- if(BUSTYPE(ether->tbdf) != BusPCI)
- goto buggery;
- ctlr->busmaster = 2;
- goto vortex;
- case 0x5900: /* 3C590-[TP|COMBO|TPO] */
- case 0x5920: /* 3C592-[TP|COMBO|TPO] */
- case 0x5950: /* 3C595-TX */
- case 0x5951: /* 3C595-T4 */
- case 0x5952: /* 3C595-MII */
- case 0x5970: /* 3C597-TX */
- case 0x5971: /* 3C597-T4 */
- case 0x5972: /* 3C597-MII */
- ctlr->busmaster = 1;
- vortex:
- COMMAND(port, SelectRegisterWindow, Wfifo);
- ctlr->xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask);
- ctlr->rxearly = 8188;
- ctlr->rxstatus9 = 0;
- break;
- buggery:
- default:
- ctlr->busmaster = 0;
- COMMAND(port, SelectRegisterWindow, Wsetup);
- x = ins(port+AddressConfig);
- ctlr->xcvr = ((x & xcvrMask9)>>14)<<20;
- if(x & autoSelect9)
- ctlr->xcvr |= autoSelect;
- ctlr->rxearly = 2044;
- ctlr->rxstatus9 = 1;
- break;
- }
- if(ctlr->rxearly >= 2048)
- ctlr->ts = 2;
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the EEPROM and set in ether->ea prior to
- * loading the station address in Wstation.
- * The EEPROM returns 16-bits at a time.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, ether->ea, Eaddrlen) == 0){
- for(i = 0; i < Eaddrlen/2; i++){
- x = eepromdata(ctlr, i);
- ether->ea[2*i] = x>>8;
- ether->ea[2*i+1] = x;
- }
- }
-
- COMMAND(port, SelectRegisterWindow, Wstation);
- for(i = 0; i < Eaddrlen; i++)
- outb(port+i, ether->ea[i]);
-
- /*
- * Enable the transceiver if necessary and determine whether
- * busmastering can be used. Due to bugs in the first revision
- * of the 3C59[05], don't use busmastering at 10Mbps.
- */
- XCVRDEBUG("reset: xcvr %uX\n", ctlr->xcvr);
-
- /*
- * Allow user to specify desired media in plan9.ini
- */
- for(i = 0; i < ether->nopt; i++){
- if(cistrncmp(ether->opt[i], "media=", 6) != 0)
- continue;
- p = ether->opt[i]+6;
- for(j = 0; j < nelem(media); j++)
- if(cistrcmp(p, media[j].name) == 0)
- ctlr->xcvr = media[j].xcvr;
- }
-
- /*
- * forgive me, but i am weak
- */
- switch(ctlr->did){
- default:
- if(ctlr->xcvr & autoSelect)
- ctlr->xcvr = autoselect(ctlr);
- break;
- case 0x5157:
- case 0x6056:
- case 0x4500:
- case 0x7646:
- case 0x9055:
- case 0x9200:
- case 0x9201:
- case 0x9805:
- ctlr->xcvr = xcvrMii;
- resetctlr(ctlr);
- break;
- }
- XCVRDEBUG("xcvr selected: %uX, did 0x%uX\n", ctlr->xcvr, ctlr->did);
-
- switch(ctlr->xcvr){
- case xcvrMii:
- /*
- * Quick hack.
- */
- if(ctlr->did == 0x5157)
- phyaddr = 0;
- else if(ctlr->did == 0x6056)
- phyaddr = scanphy(port);
- else
- phyaddr = 24;
- for(i = 0; i < 7; i++)
- XCVRDEBUG(" %2.2uX", miir(port, phyaddr, i));
- XCVRDEBUG("\n");
-
- for(timeo = 0; timeo < 30; timeo++){
- phystat = miir(port, phyaddr, 0x01);
- if(phystat & 0x20)
- break;
- XCVRDEBUG(" %2.2uX", phystat);
- delay(100);
- }
- XCVRDEBUG(" %2.2uX", miir(port, phyaddr, 0x01));
- XCVRDEBUG("\n");
-
- anar = miir(port, phyaddr, 0x04);
- anlpar = miir(port, phyaddr, 0x05) & 0x03E0;
- anar &= anlpar;
- miir(port, phyaddr, 0x00);
- XCVRDEBUG("mii an: %uX anlp: %uX r0:%uX r1:%uX\n",
- anar, anlpar, miir(port, phyaddr, 0x00),
- miir(port, phyaddr, 0x01));
- for(i = 0; i < ether->nopt; i++){
- if(cistrcmp(ether->opt[i], "fullduplex") == 0)
- anar |= 0x0100;
- else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
- anar |= 0x0100;
- else if(cistrcmp(ether->opt[i], "force100") == 0)
- anar |= 0x0080;
- }
- XCVRDEBUG("mii anar: %uX\n", anar);
- if(anar & 0x0100){ /* 100BASE-TXFD */
- ether->mbps = 100;
- setfullduplex(port);
- }
- else if(anar & 0x0200){ /* 100BASE-T4 */
- /* nothing to do */
- }
- else if(anar & 0x0080) /* 100BASE-TX */
- ether->mbps = 100;
- else if(anar & 0x0040) /* 10BASE-TFD */
- setfullduplex(port);
- else{ /* 10BASE-T */
- /* nothing to do */
- }
- break;
- case xcvr100BaseTX:
- case xcvr100BaseFX:
- COMMAND(port, SelectRegisterWindow, Wfifo);
- x = inl(port+InternalConfig) & ~ramPartitionMask;
- outl(port+InternalConfig, x|ramPartition1to1);
-
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
- x |= linkBeatEnable;
- outs(port+MediaStatus, x);
-
- if(x & dataRate100)
- ether->mbps = 100;
- break;
- case xcvr10BaseT:
- /*
- * Enable Link Beat and Jabber to start the
- * transceiver.
- */
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- x = ins(port+MediaStatus) & ~dcConverterEnabled;
- x |= linkBeatEnable|jabberGuardEnable;
- outs(port+MediaStatus, x);
-
- if((ctlr->did & 0xFF00) == 0x5900)
- ctlr->busmaster = 0;
- break;
- case xcvr10Base2:
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- x = ins(port+MediaStatus) & ~(linkBeatEnable|jabberGuardEnable);
- outs(port+MediaStatus, x);
-
- /*
- * Start the DC-DC converter.
- * Wait > 800 microseconds.
- */
- COMMAND(port, EnableDcConverter, 0);
- delay(1);
- break;
- }
-
- /*
- * Wop is the normal operating register set.
- * The 3C59[0257] adapters allow access to more than one register window
- * at a time, but there are situations where switching still needs to be
- * done, so just do it.
- * Clear out any lingering Tx status.
- */
- COMMAND(port, SelectRegisterWindow, Wop);
- if(ctlr->busmaster == 2)
- x = port+TxStatus905;
- else
- x = port+TxStatus;
- while(inb(x))
- outb(x, 0);
-
- /*
- * Clear out the
- * adapter statistics, clear the statistics logged into ctlr
- * and enable statistics collection.
- */
- ilock(&ctlr->wlock);
- statistics(ether);
- memset(ctlr->stats, 0, sizeof(ctlr->stats));
-
- COMMAND(port, StatisticsEnable, 0);
-
- /*
- * Allocate any receive buffers.
- */
- switch(ctlr->busmaster){
- case 2:
- ctlr->dnenabled = 1;
-
- /*
- * 10MUpldBug.
- * Disabling is too severe, can use receive busmastering at
- * 100Mbps OK, but how to tell which rate is actually being used -
- * the 3c905 always seems to have dataRate100 set?
- * Believe the bug doesn't apply if upRxEarlyEnable is set
- * and the threshold is set such that uploads won't start
- * until the whole packet has been received.
- */
- ctlr->upenabled = 1;
- x = eepromdata(ctlr, 0x0F);
- if(!(x & 0x01))
- outl(port+PktStatus, upRxEarlyEnable);
-
- if(ctlr->upenabled || ctlr->dnenabled){
- ctlr->nup = Nup;
- ctlr->ndn = Ndn;
- init905(ctlr);
- }
- else {
- ctlr->rbp = rbpalloc(iallocb);
- if(ctlr->rbp == nil)
- panic("can't reset ethernet: out of memory");
- }
- outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
- break;
- default:
- ctlr->rbp = rbpalloc(iallocb);
- if(ctlr->rbp == nil)
- panic("can't reset ethernet: out of memory");
- break;
- }
-
- /*
- * Set a base TxStartThresh which will be incremented
- * if any txUnderrun errors occur and ensure no RxEarly
- * interrupts happen.
- */
- ctlr->txthreshold = ETHERMAXTU/2;
- COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);
- COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts);
-
- iunlock(&ctlr->wlock);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = ifstat;
-
- ether->promiscuous = promiscuous;
- ether->multicast = multicast;
- ether->shutdown = shutdown;
- ether->arg = ether;
-
- return 0;
-}
-
-void
-etherelnk3link(void)
-{
- addethercard("elnk3", etherelnk3reset);
- addethercard("3C509", etherelnk3reset);
- addethercard("3C575", etherelnk3reset);
-}
diff --git a/os/pc/etherga620.c b/os/pc/etherga620.c
deleted file mode 100644
index 3d555be0..00000000
--- a/os/pc/etherga620.c
+++ /dev/null
@@ -1,1275 +0,0 @@
-/*
- * Netgear GA620 Gigabit Ethernet Card.
- * Specific for the Alteon Tigon 2 and Intel Pentium or later.
- * To Do:
- * cache alignment for PCI Write-and-Invalidate
- * mini ring (what size)?
- * tune coalescing values
- * statistics formatting
- * don't update Spi if nothing to send
- * receive ring alignment
- * watchdog for link management?
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#define malign(n) xspanalloc((n), 32, 0)
-
-#include "etherif.h"
-#include "etherga620fw.h"
-
-enum {
- Mhc = 0x0040, /* Miscellaneous Host Control */
- Mlc = 0x0044, /* Miscellaneous Local Control */
- Mc = 0x0050, /* Miscellaneous Configuration */
- Ps = 0x005C, /* PCI State */
- Wba = 0x0068, /* Window Base Address */
- Wd = 0x006C, /* Window Data */
-
- DMAas = 0x011C, /* DMA Assist State */
-
- CPUAstate = 0x0140, /* CPU A State */
- CPUApc = 0x0144, /* CPU A Programme Counter */
-
- CPUBstate = 0x0240, /* CPU B State */
-
- Hi = 0x0504, /* Host In Interrupt Handler */
- Cpi = 0x050C, /* Command Producer Index */
- Spi = 0x0514, /* Send Producer Index */
- Rspi = 0x051C, /* Receive Standard Producer Index */
- Rjpi = 0x0524, /* Receive Jumbo Producer Index */
- Rmpi = 0x052C, /* Receive Mini Producer Index */
-
- Mac = 0x0600, /* MAC Address */
- Gip = 0x0608, /* General Information Pointer */
- Om = 0x0618, /* Operating Mode */
- DMArc = 0x061C, /* DMA Read Configuration */
- DMAwc = 0x0620, /* DMA Write Configuration */
- Tbr = 0x0624, /* Transmit Buffer Ratio */
- Eci = 0x0628, /* Event Consumer Index */
- Cci = 0x062C, /* Command Consumer Index */
-
- Rct = 0x0630, /* Receive Coalesced Ticks */
- Sct = 0x0634, /* Send Coalesced Ticks */
- St = 0x0638, /* Stat Ticks */
- SmcBD = 0x063C, /* Send Max. Coalesced BDs */
- RmcBD = 0x0640, /* Receive Max. Coalesced BDs */
- Nt = 0x0644, /* NIC Tracing */
- Gln = 0x0648, /* Gigabit Link Negotiation */
- Fln = 0x064C, /* 10/100 Link Negotiation */
- Ifx = 0x065C, /* Interface Index */
- IfMTU = 0x0660, /* Interface MTU */
- Mi = 0x0664, /* Mask Interrupts */
- Gls = 0x0668, /* Gigabit Link State */
- Fls = 0x066C, /* 10/100 Link State */
-
- Cr = 0x0700, /* Command Ring */
-
- Lmw = 0x0800, /* Local Memory Window */
-};
-
-enum { /* Mhc */
- Is = 0x00000001, /* Interrupt State */
- Ci = 0x00000002, /* Clear Interrupt */
- Hr = 0x00000008, /* Hard Reset */
- Eebs = 0x00000010, /* Enable Endian Byte Swap */
- Eews = 0x00000020, /* Enable Endian Word (64-bit) swap */
- Mpio = 0x00000040, /* Mask PCI Interrupt Output */
-};
-
-enum { /* Mlc */
- SRAM512 = 0x00000200, /* SRAM Bank Size of 512KB */
- SRAMmask = 0x00000300,
- EEclk = 0x00100000, /* Serial EEPROM Clock Output */
- EEdoe = 0x00200000, /* Serial EEPROM Data Out Enable */
- EEdo = 0x00400000, /* Serial EEPROM Data Out Value */
- EEdi = 0x00800000, /* Serial EEPROM Data Input */
-};
-
-enum { /* Mc */
- SyncSRAM = 0x00100000, /* Set Synchronous SRAM Timing */
-};
-
-enum { /* Ps */
- PCIwm32 = 0x000000C0, /* Write Max DMA 32 */
- PCImrm = 0x00020000, /* Use Memory Read Multiple Command */
- PCI66 = 0x00080000,
- PCI32 = 0x00100000,
- PCIrcmd = 0x06000000, /* PCI Read Command */
- PCIwcmd = 0x70000000, /* PCI Write Command */
-};
-
-enum { /* CPUAstate */
- CPUrf = 0x00000010, /* ROM Fail */
- CPUhalt = 0x00010000, /* Halt the internal CPU */
- CPUhie = 0x00040000, /* HALT instruction executed */
-};
-
-enum { /* Om */
- BswapBD = 0x00000002, /* Byte Swap Buffer Descriptors */
- WswapBD = 0x00000004, /* Word Swap Buffer Descriptors */
- Warn = 0x00000008,
- BswapDMA = 0x00000010, /* Byte Swap DMA Data */
- Only1DMA = 0x00000040, /* Only One DMA Active at a time */
- NoJFrag = 0x00000200, /* Don't Fragment Jumbo Frames */
- Fatal = 0x40000000,
-};
-
-enum { /* Lmw */
- Lmwsz = 2*1024, /* Local Memory Window Size */
-
- /*
- * legal values are 0x3800 iff Nsr is 128, 0x3000 iff Nsr is 256,
- * or 0x2000 iff Nsr is 512.
- */
- Sr = 0x2000, /* Send Ring (accessed via Lmw) */
-};
-
-enum { /* Link */
- Lpref = 0x00008000, /* Preferred Link */
- L10MB = 0x00010000,
- L100MB = 0x00020000,
- L1000MB = 0x00040000,
- Lfd = 0x00080000, /* Full Duplex */
- Lhd = 0x00100000, /* Half Duplex */
- Lefc = 0x00200000, /* Emit Flow Control Packets */
- Lofc = 0x00800000, /* Obey Flow Control Packets */
- Lean = 0x20000000, /* Enable Autonegotiation/Sensing */
- Le = 0x40000000, /* Link Enable */
-};
-
-typedef struct Host64 {
- uint hi;
- uint lo;
-} Host64;
-
-typedef struct Ere { /* Event Ring Element */
- int event; /* event<<24 | code<<12 | index */
- int unused;
-} Ere;
-
-typedef int Cmd; /* cmd<<24 | flags<<12 | index */
-
-typedef struct Rbd { /* Receive Buffer Descriptor */
- Host64 addr;
- int indexlen; /* ring-index<<16 | buffer-length */
- int flags; /* only lower 16-bits */
- int checksum; /* ip<<16 | tcp/udp */
- int error; /* only upper 16-bits */
- int reserved;
- void* opaque; /* passed to receive return ring */
-} Rbd;
-
-typedef struct Sbd { /* Send Buffer Descriptor */
- Host64 addr;
- int lenflags; /* len<<16 | flags */
- int reserved;
-} Sbd;
-
-enum { /* Buffer Descriptor Flags */
- Fend = 0x00000004, /* Frame Ends in this Buffer */
- Frjr = 0x00000010, /* Receive Jumbo Ring Buffer */
- Funicast = 0x00000020, /* Unicast packet (2-bit field) */
- Fmulticast = 0x00000040, /* Multicast packet */
- Fbroadcast = 0x00000060, /* Broadcast packet */
- Ferror = 0x00000400, /* Frame Has Error */
- Frmr = 0x00001000, /* Receive Mini Ring Buffer */
-};
-
-enum { /* Buffer Error Flags */
- Ecrc = 0x00010000, /* bad CRC */
- Ecollision = 0x00020000, /* collision */
- Elink = 0x00040000, /* link lost */
- Ephy = 0x00080000, /* unspecified PHY frame decode error */
- Eodd = 0x00100000, /* odd number of nibbles */
- Emac = 0x00200000, /* unspecified MAC abort */
- Elen64 = 0x00400000, /* short packet */
- Eresources = 0x00800000, /* MAC out of internal resources */
- Egiant = 0x01000000, /* packet too big */
-};
-
-typedef struct Rcb { /* Ring Control Block */
- Host64 addr; /* points to the Rbd ring */
- int control; /* max_len<<16 | flags */
- int unused;
-} Rcb;
-
-enum {
- TcpUdpCksum = 0x0001, /* Perform TCP or UDP checksum */
- IpCksum = 0x0002, /* Perform IP checksum */
- NoPseudoHdrCksum= 0x0008, /* Don't include the pseudo header */
- VlanAssist = 0x0010, /* Enable VLAN tagging */
- CoalUpdateOnly = 0x0020, /* Coalesce transmit interrupts */
- HostRing = 0x0040, /* Sr in host memory */
- SnapCksum = 0x0080, /* Parse + offload 802.3 SNAP frames */
- UseExtRxBd = 0x0100, /* Extended Rbd for Jumbo frames */
- RingDisabled = 0x0200, /* Jumbo or Mini RCB only */
-};
-
-typedef struct Gib { /* General Information Block */
- int statistics[256]; /* Statistics */
- Rcb ercb; /* Event Ring */
- Rcb crcb; /* Command Ring */
- Rcb srcb; /* Send Ring */
- Rcb rsrcb; /* Receive Standard Ring */
- Rcb rjrcb; /* Receive Jumbo Ring */
- Rcb rmrcb; /* Receive Mini Ring */
- Rcb rrrcb; /* Receive Return Ring */
- Host64 epp; /* Event Producer */
- Host64 rrrpp; /* Receive Return Ring Producer */
- Host64 scp; /* Send Consumer */
- Host64 rsp; /* Refresh Stats */
-} Gib;
-
-/*
- * these sizes are all fixed in the card,
- * except for Nsr, which has only 3 valid sizes.
- */
-enum { /* Host/NIC Interface ring sizes */
- Ner = 256, /* event ring */
- Ncr = 64, /* command ring */
- Nsr = 512, /* send ring: 128, 256 or 512 */
- Nrsr = 512, /* receive standard ring */
- Nrjr = 256, /* receive jumbo ring */
- Nrmr = 1024, /* receive mini ring, optional */
- Nrrr = 2048, /* receive return ring */
-};
-
-enum {
- NrsrHI = 72, /* Fill-level of Rsr (m.b. < Nrsr) */
- NrsrLO = 54, /* Level at which to top-up ring */
- NrjrHI = 0, /* Fill-level of Rjr (m.b. < Nrjr) */
- NrjrLO = 0, /* Level at which to top-up ring */
- NrmrHI = 0, /* Fill-level of Rmr (m.b. < Nrmr) */
- NrmrLO = 0, /* Level at which to top-up ring */
-};
-
-typedef struct Ctlr Ctlr;
-struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
- int id;
-
- uchar ea[Eaddrlen];
-
- int* nic;
- Gib* gib;
-
- Ere* er;
-
- Lock srlock;
- Sbd* sr;
- Block** srb;
- int nsr; /* currently in send ring */
-
- Rbd* rsr;
- int nrsr; /* currently in Receive Standard Ring */
- Rbd* rjr;
- int nrjr; /* currently in Receive Jumbo Ring */
- Rbd* rmr;
- int nrmr; /* currently in Receive Mini Ring */
- Rbd* rrr;
- int rrrci; /* Receive Return Ring Consumer Index */
-
- int epi[2]; /* Event Producer Index */
- int rrrpi[2]; /* Receive Return Ring Producer Index */
- int sci[3]; /* Send Consumer Index ([2] is host) */
-
- int interrupts; /* statistics */
- int mi;
- uvlong ticks;
-
- int coalupdateonly; /* tuning */
- int hardwarecksum;
- int rct; /* Receive Coalesce Ticks */
- int sct; /* Send Coalesce Ticks */
- int st; /* Stat Ticks */
- int smcbd; /* Send Max. Coalesced BDs */
- int rmcbd; /* Receive Max. Coalesced BDs */
-};
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-#define csr32r(c, r) (*((c)->nic+((r)/4)))
-#define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
-
-static void
-sethost64(Host64* host64, void* addr)
-{
- uvlong uvl;
-
- uvl = PCIWADDR(addr);
- host64->hi = uvl>>32;
- host64->lo = uvl & 0xFFFFFFFFL;
-}
-
-static void
-ga620command(Ctlr* ctlr, int cmd, int flags, int index)
-{
- int cpi;
-
- cpi = csr32r(ctlr, Cpi);
- csr32w(ctlr, Cr+(cpi*4), cmd<<24 | flags<<12 | index);
- cpi = NEXT(cpi, Ncr);
- csr32w(ctlr, Cpi, cpi);
-}
-
-static void
-ga620attach(Ether* edev)
-{
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
- USED(ctlr);
-}
-
-static long
-ga620ifstat(Ether* edev, void* a, long n, ulong offset)
-{
- char *p;
- Ctlr *ctlr;
- int i, l, r;
-
- ctlr = edev->ctlr;
-
- if(n == 0)
- return 0;
- p = malloc(READSTR);
- l = 0;
- for(i = 0; i < 256; i++){
- if((r = ctlr->gib->statistics[i]) == 0)
- continue;
- l += snprint(p+l, READSTR-l, "%d: %ud\n", i, r);
- }
-
- l += snprint(p+l, READSTR-l, "interrupts: %ud\n", ctlr->interrupts);
- l += snprint(p+l, READSTR-l, "mi: %ud\n", ctlr->mi);
- l += snprint(p+l, READSTR-l, "ticks: %llud\n", ctlr->ticks);
- l += snprint(p+l, READSTR-l, "coalupdateonly: %d\n", ctlr->coalupdateonly);
- l += snprint(p+l, READSTR-l, "hardwarecksum: %d\n", ctlr->hardwarecksum);
- l += snprint(p+l, READSTR-l, "rct: %d\n", ctlr->rct);
- l += snprint(p+l, READSTR-l, "sct: %d\n", ctlr->sct);
- l += snprint(p+l, READSTR-l, "smcbd: %d\n", ctlr->smcbd);
- snprint(p+l, READSTR-l, "rmcbd: %d\n", ctlr->rmcbd);
-
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static long
-ga620ctl(Ether* edev, void* buf, long n)
-{
- char *p;
- Cmdbuf *cb;
- Ctlr *ctlr;
- int control, i, r;
-
- ctlr = edev->ctlr;
- if(ctlr == nil)
- error(Enonexist);
- r = 0;
- cb = parsecmd(buf, n);
- if(cb->nf < 2)
- r = -1;
- else if(cistrcmp(cb->f[0], "coalupdateonly") == 0){
- if(cistrcmp(cb->f[1], "off") == 0){
- control = ctlr->gib->srcb.control;
- control &= ~CoalUpdateOnly;
- ctlr->gib->srcb.control = control;
- ctlr->coalupdateonly = 0;
- }
- else if(cistrcmp(cb->f[1], "on") == 0){
- control = ctlr->gib->srcb.control;
- control |= CoalUpdateOnly;
- ctlr->gib->srcb.control = control;
- ctlr->coalupdateonly = 1;
- }
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "hardwarecksum") == 0){
- if(cistrcmp(cb->f[1], "off") == 0){
- control = ctlr->gib->srcb.control;
- control &= ~(TcpUdpCksum|NoPseudoHdrCksum);
- ctlr->gib->srcb.control = control;
-
- control = ctlr->gib->rsrcb.control;
- control &= ~(TcpUdpCksum|NoPseudoHdrCksum);
- ctlr->gib->rsrcb.control = control;
-
- ctlr->hardwarecksum = 0;
- }
- else if(cistrcmp(cb->f[1], "on") == 0){
- control = ctlr->gib->srcb.control;
- control |= (TcpUdpCksum|NoPseudoHdrCksum);
- ctlr->gib->srcb.control = control;
-
- control = ctlr->gib->rsrcb.control;
- control |= (TcpUdpCksum|NoPseudoHdrCksum);
- ctlr->gib->rsrcb.control = control;
-
- ctlr->hardwarecksum = 1;
- }
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "rct") == 0){
- i = strtol(cb->f[1], &p, 0);
- if(i < 0 || p == cb->f[1])
- r = -1;
- else{
- ctlr->rct = i;
- csr32w(ctlr, Rct, ctlr->rct);
- }
- }
- else if(cistrcmp(cb->f[0], "sct") == 0){
- i = strtol(cb->f[1], &p, 0);
- if(i < 0 || p == cb->f[1])
- r = -1;
- else{
- ctlr->sct = i;
- csr32w(ctlr, Sct, ctlr->sct);
- }
- }
- else if(cistrcmp(cb->f[0], "st") == 0){
- i = strtol(cb->f[1], &p, 0);
- if(i < 0 || p == cb->f[1])
- r = -1;
- else{
- ctlr->st = i;
- csr32w(ctlr, St, ctlr->st);
- }
- }
- else if(cistrcmp(cb->f[0], "smcbd") == 0){
- i = strtol(cb->f[1], &p, 0);
- if(i < 0 || p == cb->f[1])
- r = -1;
- else{
- ctlr->smcbd = i;
- csr32w(ctlr, SmcBD, ctlr->smcbd);
- }
- }
- else if(cistrcmp(cb->f[0], "rmcbd") == 0){
- i = strtol(cb->f[1], &p, 0);
- if(i < 0 || p == cb->f[1])
- r = -1;
- else{
- ctlr->rmcbd = i;
- csr32w(ctlr, RmcBD, ctlr->rmcbd);
- }
- }
- else
- r = -1;
-
- free(cb);
- if(r == 0)
- return n;
- return r;
-}
-
-static int
-_ga620transmit(Ether* edev)
-{
- Sbd *sbd;
- Block *bp;
- Ctlr *ctlr;
- int sci, spi, work;
-
- /*
- * For now there are no smarts here, just empty the
- * ring and try to fill it back up. Tuning comes later.
- */
- ctlr = edev->ctlr;
- ilock(&ctlr->srlock);
-
- /*
- * Free any completed packets.
- * Ctlr->sci[0] is where the NIC has got to consuming the ring.
- * Ctlr->sci[2] is where the host has got to tidying up after the
- * NIC has done with the packets.
- */
- work = 0;
- for(sci = ctlr->sci[2]; sci != ctlr->sci[0]; sci = NEXT(sci, Nsr)){
- if(ctlr->srb[sci] == nil)
- continue;
- freeb(ctlr->srb[sci]);
- ctlr->srb[sci] = nil;
- work++;
- }
- ctlr->sci[2] = sci;
-
- sci = PREV(sci, Nsr);
- for(spi = csr32r(ctlr, Spi); spi != sci; spi = NEXT(spi, Nsr)){
- if((bp = qget(edev->oq)) == nil)
- break;
-
- sbd = &ctlr->sr[spi];
- sethost64(&sbd->addr, bp->rp);
- sbd->lenflags = BLEN(bp)<<16 | Fend;
-
- ctlr->srb[spi] = bp;
- work++;
- }
- csr32w(ctlr, Spi, spi);
-
- iunlock(&ctlr->srlock);
-
- return work;
-}
-
-static void
-ga620transmit(Ether* edev)
-{
- _ga620transmit(edev);
-}
-
-static void
-ga620replenish(Ctlr* ctlr)
-{
- Rbd *rbd;
- int rspi;
- Block *bp;
-
- rspi = csr32r(ctlr, Rspi);
- while(ctlr->nrsr < NrsrHI){
- if((bp = iallocb(ETHERMAXTU+4)) == nil)
- break;
- rbd = &ctlr->rsr[rspi];
- sethost64(&rbd->addr, bp->rp);
- rbd->indexlen = rspi<<16 | (ETHERMAXTU+4);
- rbd->flags = 0;
- rbd->opaque = bp;
-
- rspi = NEXT(rspi, Nrsr);
- ctlr->nrsr++;
- }
- csr32w(ctlr, Rspi, rspi);
-}
-
-static void
-ga620event(Ether *edev, int eci, int epi)
-{
- unsigned event, code;
- Ctlr *ctlr;
-
- ctlr = edev->ctlr;
- while(eci != epi){
- event = ctlr->er[eci].event;
- code = (event >> 12) & ((1<<12)-1);
- switch(event>>24){
- case 0x01: /* firmware operational */
- /* host stack (us) is up. 3rd arg of 2 means down. */
- ga620command(ctlr, 0x01, 0x01, 0x00);
- /*
- * link negotiation: any speed is okay.
- * 3rd arg of 1 selects gigabit only; 2 10/100 only.
- */
- ga620command(ctlr, 0x0B, 0x00, 0x00);
- print("#l%d: ga620: port %8.8uX: firmware is up\n",
- edev->ctlrno, ctlr->port);
- break;
- case 0x04: /* statistics updated */
- break;
- case 0x06: /* link state changed */
- switch (code) {
- case 1:
- edev->mbps = 1000;
- break;
- case 2:
- print("#l%d: link down\n", edev->ctlrno);
- break;
- case 3:
- edev->mbps = 100; /* it's 10 or 100 */
- break;
- }
- if (code != 2)
- print("#l%d: %dMbps link up\n",
- edev->ctlrno, edev->mbps);
- break;
- case 0x07: /* event error */
- default:
- print("#l%d: ga620: er[%d] = %8.8uX\n", edev->ctlrno,
- eci, event);
- break;
- }
- eci = NEXT(eci, Ner);
- }
- csr32w(ctlr, Eci, eci);
-}
-
-static void
-ga620receive(Ether* edev)
-{
- int len;
- Rbd *rbd;
- Block *bp;
- Ctlr* ctlr;
-
- ctlr = edev->ctlr;
- while(ctlr->rrrci != ctlr->rrrpi[0]){
- rbd = &ctlr->rrr[ctlr->rrrci];
- /*
- * Errors are collected in the statistics block so
- * no need to tally them here, let ifstat do the work.
- */
- len = rbd->indexlen & 0xFFFF;
- if(!(rbd->flags & Ferror) && len != 0){
- bp = rbd->opaque;
- bp->wp = bp->rp+len;
- etheriq(edev, bp, 1);
- }
- else
- freeb(rbd->opaque);
- rbd->opaque = nil;
-
- if(rbd->flags & Frjr)
- ctlr->nrjr--;
- else if(rbd->flags & Frmr)
- ctlr->nrmr--;
- else
- ctlr->nrsr--;
-
- ctlr->rrrci = NEXT(ctlr->rrrci, Nrrr);
- }
-}
-
-static void
-ga620interrupt(Ureg*, void* arg)
-{
- int csr, ie, work;
- Ctlr *ctlr;
- Ether *edev;
- uvlong tsc0, tsc1;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- if(!(csr32r(ctlr, Mhc) & Is))
- return;
- cycles(&tsc0);
-
- ctlr->interrupts++;
- csr32w(ctlr, Hi, 1);
-
- ie = 0;
- work = 0;
- while(ie < 2){
- if(ctlr->rrrci != ctlr->rrrpi[0]){
- ga620receive(edev);
- work = 1;
- }
-
- if(_ga620transmit(edev) != 0)
- work = 1;
-
- csr = csr32r(ctlr, Eci);
- if(csr != ctlr->epi[0]){
- ga620event(edev, csr, ctlr->epi[0]);
- work = 1;
- }
-
- if(ctlr->nrsr <= NrsrLO)
- ga620replenish(ctlr);
- if(work == 0){
- if(ie == 0)
- csr32w(ctlr, Hi, 0);
- ie++;
- }
- work = 0;
- }
-
- cycles(&tsc1);
- ctlr->ticks += tsc1-tsc0;
-}
-
-static void
-ga620lmw(Ctlr* ctlr, int addr, int* data, int len)
-{
- int i, l, lmw, v;
-
- /*
- * Write to or clear ('data' == nil) 'len' bytes of the NIC
- * local memory at address 'addr'.
- * The destination address and count should be 32-bit aligned.
- */
- v = 0;
- while(len > 0){
- /*
- * 1) Set the window. The (Lmwsz-1) bits are ignored
- * in Wba when accessing through the local memory window;
- * 2) Find the minimum of how many bytes still to
- * transfer and how many left in this window;
- * 3) Create the offset into the local memory window in the
- * shared memory space then copy (or zero) the data;
- * 4) Bump the counts.
- */
- csr32w(ctlr, Wba, addr);
-
- l = ROUNDUP(addr+1, Lmwsz) - addr;
- if(l > len)
- l = len;
-
- lmw = Lmw + (addr & (Lmwsz-1));
- for(i = 0; i < l; i += 4){
- if(data != nil)
- v = *data++;
- csr32w(ctlr, lmw+i, v);
- }
-
- len -= l;
- addr += l;
- }
-}
-
-static int
-ga620init(Ether* edev)
-{
- Ctlr *ctlr;
- Host64 host64;
- int csr, ea, i, flags;
-
- ctlr = edev->ctlr;
-
- /*
- * Load the MAC address.
- */
- ea = edev->ea[0]<<8 | edev->ea[1];
- csr32w(ctlr, Mac, ea);
- ea = edev->ea[2]<<24 | edev->ea[3]<<16 | edev->ea[4]<<8 | edev->ea[5];
- csr32w(ctlr, Mac+4, ea);
-
- /*
- * General Information Block.
- */
- ctlr->gib = malloc(sizeof(Gib));
- sethost64(&host64, ctlr->gib);
- csr32w(ctlr, Gip, host64.hi);
- csr32w(ctlr, Gip+4, host64.lo);
-
- /*
- * Event Ring.
- * This is located in host memory. Allocate the ring,
- * tell the NIC where it is and initialise the indices.
- */
- ctlr->er = malign(sizeof(Ere)*Ner);
- sethost64(&ctlr->gib->ercb.addr, ctlr->er);
- sethost64(&ctlr->gib->epp, ctlr->epi);
- csr32w(ctlr, Eci, 0);
-
- /*
- * Command Ring.
- * This is located in the General Communications Region
- * and so the value placed in the Rcb is unused, the NIC
- * knows where it is. Stick in the value according to
- * the datasheet anyway.
- * Initialise the ring and indices.
- */
- ctlr->gib->crcb.addr.lo = Cr-0x400;
- for(i = 0; i < Ncr*4; i += 4)
- csr32w(ctlr, Cr+i, 0);
- csr32w(ctlr, Cpi, 0);
- csr32w(ctlr, Cci, 0);
-
- /*
- * Send Ring.
- * This ring is either in NIC memory at a fixed location depending
- * on how big the ring is or it is in host memory. If in NIC
- * memory it is accessed via the Local Memory Window; with a send
- * ring size of 128 the window covers the whole ring and then need
- * only be set once:
- * ctlr->sr = (uchar*)ctlr->nic+Lmw;
- * ga620lmw(ctlr, Sr, nil, sizeof(Sbd)*Nsr);
- * ctlr->gib->srcb.addr.lo = Sr;
- * There is nowhere in the Sbd to hold the Block* associated
- * with this entry so an external array must be kept.
- */
- ctlr->sr = malign(sizeof(Sbd)*Nsr);
- sethost64(&ctlr->gib->srcb.addr, ctlr->sr);
- if(ctlr->hardwarecksum)
- flags = TcpUdpCksum|NoPseudoHdrCksum|HostRing;
- else
- flags = HostRing;
- if(ctlr->coalupdateonly)
- flags |= CoalUpdateOnly;
- ctlr->gib->srcb.control = Nsr<<16 | flags;
- sethost64(&ctlr->gib->scp, ctlr->sci);
- csr32w(ctlr, Spi, 0);
- ctlr->srb = malloc(sizeof(Block*)*Nsr);
-
- /*
- * Receive Standard Ring.
- */
- ctlr->rsr = malign(sizeof(Rbd)*Nrsr);
- sethost64(&ctlr->gib->rsrcb.addr, ctlr->rsr);
- if(ctlr->hardwarecksum)
- flags = TcpUdpCksum|NoPseudoHdrCksum;
- else
- flags = 0;
- ctlr->gib->rsrcb.control = (ETHERMAXTU+4)<<16 | flags;
- csr32w(ctlr, Rspi, 0);
-
- /*
- * Jumbo and Mini Rings. Unused for now.
- */
- ctlr->gib->rjrcb.control = RingDisabled;
- ctlr->gib->rmrcb.control = RingDisabled;
-
- /*
- * Receive Return Ring.
- * This is located in host memory. Allocate the ring,
- * tell the NIC where it is and initialise the indices.
- */
- ctlr->rrr = malign(sizeof(Rbd)*Nrrr);
- sethost64(&ctlr->gib->rrrcb.addr, ctlr->rrr);
- ctlr->gib->rrrcb.control = Nrrr<<16 | 0;
- sethost64(&ctlr->gib->rrrpp, ctlr->rrrpi);
- ctlr->rrrci = 0;
-
- /*
- * Refresh Stats Pointer.
- * For now just point it at the existing statistics block.
- */
- sethost64(&ctlr->gib->rsp, ctlr->gib->statistics);
-
- /*
- * DMA configuration.
- * Use the recommended values.
- */
- csr32w(ctlr, DMArc, 0x80);
- csr32w(ctlr, DMAwc, 0x80);
-
- /*
- * Transmit Buffer Ratio.
- * Set to 1/3 of available buffer space (units are 1/64ths)
- * if using Jumbo packets, ~64KB otherwise (assume 1MB on NIC).
- */
- if(NrjrHI > 0 || Nsr > 128)
- csr32w(ctlr, Tbr, 64/3);
- else
- csr32w(ctlr, Tbr, 4);
-
- /*
- * Tuneable parameters.
- * These defaults are based on the tuning hints in the Alteon
- * Host/NIC Software Interface Definition and example software.
- */
- ctlr->rct = 1/*100*/;
- csr32w(ctlr, Rct, ctlr->rct);
- ctlr->sct = 0;
- csr32w(ctlr, Sct, ctlr->sct);
- ctlr->st = 1000000;
- csr32w(ctlr, St, ctlr->st);
- ctlr->smcbd = Nsr/4;
- csr32w(ctlr, SmcBD, ctlr->smcbd);
- ctlr->rmcbd = 4/*6*/;
- csr32w(ctlr, RmcBD, ctlr->rmcbd);
-
- /*
- * Enable DMA Assist Logic.
- */
- csr = csr32r(ctlr, DMAas) & ~0x03;
- csr32w(ctlr, DMAas, csr|0x01);
-
- /*
- * Link negotiation.
- * The bits are set here but the NIC must be given a command
- * once it is running to set negotiation in motion.
- */
- csr32w(ctlr, Gln, Le|Lean|Lofc|Lfd|L1000MB|Lpref);
- csr32w(ctlr, Fln, Le|Lean|Lhd|Lfd|L100MB|L10MB);
-
- /*
- * A unique index for this controller and the maximum packet
- * length expected.
- * For now only standard packets are expected.
- */
- csr32w(ctlr, Ifx, 1);
- csr32w(ctlr, IfMTU, ETHERMAXTU+4);
-
- /*
- * Enable Interrupts.
- * There are 3 ways to mask interrupts - a bit in the Mhc (which
- * is already cleared), the Mi register and the Hi mailbox.
- * Writing to the Hi mailbox has the side-effect of clearing the
- * PCI interrupt.
- */
- csr32w(ctlr, Mi, 0);
- csr32w(ctlr, Hi, 0);
-
- /*
- * Start the firmware.
- */
- csr32w(ctlr, CPUApc, tigon2FwStartAddr);
- csr = csr32r(ctlr, CPUAstate) & ~CPUhalt;
- csr32w(ctlr, CPUAstate, csr);
-
- return 0;
-}
-
-static int
-at24c32io(Ctlr* ctlr, char* op, int data)
-{
- char *lp, *p;
- int i, loop, mlc, r;
-
- mlc = csr32r(ctlr, Mlc);
-
- r = 0;
- loop = -1;
- lp = nil;
- for(p = op; *p != '\0'; p++){
- switch(*p){
- default:
- return -1;
- case ' ':
- continue;
- case ':': /* start of 8-bit loop */
- if(lp != nil)
- return -1;
- lp = p;
- loop = 7;
- continue;
- case ';': /* end of 8-bit loop */
- if(lp == nil)
- return -1;
- loop--;
- if(loop >= 0)
- p = lp;
- else
- lp = nil;
- continue;
- case 'C': /* assert clock */
- mlc |= EEclk;
- break;
- case 'c': /* deassert clock */
- mlc &= ~EEclk;
- break;
- case 'D': /* next bit in 'data' byte */
- if(loop < 0)
- return -1;
- if(data & (1<<loop))
- mlc |= EEdo;
- else
- mlc &= ~EEdo;
- break;
- case 'E': /* enable data output */
- mlc |= EEdoe;
- break;
- case 'e': /* disable data output */
- mlc &= ~EEdoe;
- break;
- case 'I': /* input bit */
- i = (csr32r(ctlr, Mlc) & EEdi) != 0;
- if(loop >= 0)
- r |= (i<<loop);
- else
- r = i;
- continue;
- case 'O': /* assert data output */
- mlc |= EEdo;
- break;
- case 'o': /* deassert data output */
- mlc &= ~EEdo;
- break;
- }
- csr32w(ctlr, Mlc, mlc);
- microdelay(1);
- }
- if(loop >= 0)
- return -1;
- return r;
-}
-
-static int
-at24c32r(Ctlr* ctlr, int addr)
-{
- int data;
-
- /*
- * Read a byte at address 'addr' from the Atmel AT24C32
- * Serial EEPROM. The 2-wire EEPROM access is controlled
- * by 4 bits in Mlc. See the AT24C32 datasheet for
- * protocol details.
- */
- /*
- * Start condition - a high to low transition of data
- * with the clock high must precede any other command.
- */
- at24c32io(ctlr, "OECoc", 0);
-
- /*
- * Perform a random read at 'addr'. A dummy byte
- * write sequence is performed to clock in the device
- * and data word addresses (0 and 'addr' respectively).
- */
- data = -1;
- if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA0) != 0)
- goto stop;
- if(at24c32io(ctlr, "oE :DCc; oeCIc", addr>>8) != 0)
- goto stop;
- if(at24c32io(ctlr, "oE :DCc; oeCIc", addr) != 0)
- goto stop;
-
- /*
- * Now send another start condition followed by a
- * request to read the device. The EEPROM responds
- * by clocking out the data.
- */
- at24c32io(ctlr, "OECoc", 0);
- if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA1) != 0)
- goto stop;
- data = at24c32io(ctlr, ":CIc;", 0xA1);
-
-stop:
- /*
- * Stop condition - a low to high transition of data
- * with the clock high is a stop condition. After a read
- * sequence, the stop command will place the EEPROM in
- * a standby power mode.
- */
- at24c32io(ctlr, "oECOc", 0);
-
- return data;
-}
-
-static int
-ga620detach(Ctlr* ctlr)
-{
- int timeo;
-
- /*
- * Hard reset (don't know which endian so catch both);
- * enable for little-endian mode;
- * wait for code to be loaded from serial EEPROM or flash;
- * make sure CPU A is halted.
- */
- csr32w(ctlr, Mhc, Hr<<24 | Hr);
- csr32w(ctlr, Mhc, (Eews|Ci)<<24 | Eews|Ci);
-
- microdelay(1);
- for(timeo = 0; timeo < 500000; timeo++){
- if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) == CPUhie)
- break;
- microdelay(1);
- }
- if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) != CPUhie)
- return -1;
- csr32w(ctlr, CPUAstate, CPUhalt);
-
- /*
- * After reset, CPU B seems to be stuck in 'CPUrf'.
- * Worry about it later.
- */
- csr32w(ctlr, CPUBstate, CPUhalt);
-
- return 0;
-}
-
-static void
-ga620shutdown(Ether* ether)
-{
-print("ga620shutdown\n");
- ga620detach(ether->ctlr);
-}
-
-static int
-ga620reset(Ctlr* ctlr)
-{
- int cls, csr, i, r;
-
- if(ga620detach(ctlr) < 0)
- return -1;
-
- /*
- * Tigon 2 PCI NICs have 512KB SRAM per bank.
- * Clear out any lingering serial EEPROM state
- * bits.
- */
- csr = csr32r(ctlr, Mlc) & ~(EEdi|EEdo|EEdoe|EEclk|SRAMmask);
- csr32w(ctlr, Mlc, SRAM512|csr);
- csr = csr32r(ctlr, Mc);
- csr32w(ctlr, Mc, SyncSRAM|csr);
-
- /*
- * Initialise PCI State register.
- * If PCI Write-and-Invalidate is enabled set the max write DMA
- * value to the host cache-line size (32 on Pentium or later).
- */
- csr = csr32r(ctlr, Ps) & (PCI32|PCI66);
- csr |= PCIwcmd|PCIrcmd|PCImrm;
- if(ctlr->pcidev->pcr & 0x0010){
- cls = pcicfgr8(ctlr->pcidev, PciCLS) * 4;
- if(cls != 32)
- pcicfgw8(ctlr->pcidev, PciCLS, 32/4);
- csr |= PCIwm32;
- }
- csr32w(ctlr, Ps, csr);
-
- /*
- * Operating Mode.
- */
- csr32w(ctlr, Om, Fatal|NoJFrag|BswapDMA|WswapBD);
-
- /*
- * Snarf the MAC address from the serial EEPROM.
- */
- for(i = 0; i < Eaddrlen; i++){
- if((r = at24c32r(ctlr, 0x8E+i)) == -1)
- return -1;
- ctlr->ea[i] = r;
- }
-
- /*
- * Load the firmware.
- */
- ga620lmw(ctlr, tigon2FwTextAddr, tigon2FwText, tigon2FwTextLen);
- ga620lmw(ctlr, tigon2FwRodataAddr, tigon2FwRodata, tigon2FwRodataLen);
- ga620lmw(ctlr, tigon2FwDataAddr, tigon2FwData, tigon2FwDataLen);
- ga620lmw(ctlr, tigon2FwSbssAddr, nil, tigon2FwSbssLen);
- ga620lmw(ctlr, tigon2FwBssAddr, nil, tigon2FwBssLen);
-
- return 0;
-}
-
-static void
-ga620pci(void)
-{
- void *mem;
- Pcidev *p;
- Ctlr *ctlr;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != 0x02 || p->ccru != 0)
- continue;
-
- switch(p->did<<16 | p->vid){
- default:
- continue;
- case 0x620A<<16 | 0x1385: /* Netgear GA620 fiber */
- case 0x630A<<16 | 0x1385: /* Netgear GA620T copper */
- case 0x0001<<16 | 0x12AE: /* Alteon Acenic fiber
- * and DEC DEGPA-SA */
- case 0x0002<<16 | 0x12AE: /* Alteon Acenic copper */
- case 0x0009<<16 | 0x10A9: /* SGI Acenic */
- break;
- }
-
- mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
- if(mem == 0){
- print("ga620: can't map %8.8luX\n", p->mem[0].bar);
- continue;
- }
-
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = p->mem[0].bar & ~0x0F;
- ctlr->pcidev = p;
- ctlr->id = p->did<<16 | p->vid;
-
- ctlr->nic = mem;
- if(ga620reset(ctlr)){
- free(ctlr);
- continue;
- }
-
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- }
-}
-
-static void
-ga620promiscuous(void *arg, int on)
-{
- Ether *ether = arg;
-
- /* 3rd arg: 1 enables, 2 disables */
- ga620command(ether->ctlr, 0xa, (on? 1: 2), 0);
-}
-
-static void
-ga620multicast(void *arg, uchar *addr, int on)
-{
- Ether *ether = arg;
-
- USED(addr);
- /* 3rd arg: 1 enables, 2 disables */
- ga620command(ether->ctlr, 0xe, (on? 1: 2), 0);
-}
-
-static int
-ga620pnp(Ether* edev)
-{
- Ctlr *ctlr;
- uchar ea[Eaddrlen];
-
- if(ctlrhead == nil)
- ga620pci();
-
- /*
- * Any adapter matches if no edev->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(edev->port == 0 || edev->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- edev->ctlr = ctlr;
- edev->port = ctlr->port;
- edev->irq = ctlr->pcidev->intl;
- edev->tbdf = ctlr->pcidev->tbdf;
- edev->mbps = 1000; /* placeholder */
-
- /*
- * Check if the adapter's station address is to be overridden.
- * If not, read it from the EEPROM and set in ether->ea prior to
- * loading the station address in the hardware.
- */
- memset(ea, 0, Eaddrlen);
- if(memcmp(ea, edev->ea, Eaddrlen) == 0)
- memmove(edev->ea, ctlr->ea, Eaddrlen);
-
- ga620init(edev);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- edev->attach = ga620attach;
- edev->transmit = ga620transmit;
- edev->interrupt = ga620interrupt;
- edev->ifstat = ga620ifstat;
- edev->ctl = ga620ctl;
-
- edev->arg = edev;
- edev->promiscuous = ga620promiscuous;
- edev->multicast = ga620multicast;
- edev->shutdown = ga620shutdown;
-
- return 0;
-}
-
-void
-etherga620link(void)
-{
- addethercard("GA620", ga620pnp);
-}
diff --git a/os/pc/etherga620fw.h b/os/pc/etherga620fw.h
deleted file mode 100644
index c30859e7..00000000
--- a/os/pc/etherga620fw.h
+++ /dev/null
@@ -1,4858 +0,0 @@
-/* Generated by genfw.c */
-#define tigon2FwReleaseMajor 0xc
-#define tigon2FwReleaseMinor 0x4
-#define tigon2FwReleaseFix 0xb
-#define tigon2FwStartAddr 0x00004000
-#define tigon2FwTextAddr 0x00004000
-#define tigon2FwTextLen 0x11bc0
-#define tigon2FwRodataAddr 0x00015bc0
-#define tigon2FwRodataLen 0x10d0
-#define tigon2FwDataAddr 0x00016cc0
-#define tigon2FwDataLen 0x1c0
-#define tigon2FwSbssAddr 0x00016e80
-#define tigon2FwSbssLen 0xcc
-#define tigon2FwBssAddr 0x00016f50
-#define tigon2FwBssLen 0x20c0
-static int tigon2FwText[/*(MAX_TEXT_LEN/4) + 1*/] = {
-0x0,
-0x10000003, 0x0, 0xd, 0xd,
-0x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000,
-0x26104000, 0xc0010c0, 0x0, 0xd,
-0x3c1d0001, 0x8fbd6d24, 0x3a0f021, 0x3c100000,
-0x26104000, 0xc0017e0, 0x0, 0xd,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x2000008,
-0x0, 0x800172f, 0x3c0a0001, 0x800172f,
-0x3c0a0002, 0x800172f, 0x0, 0x8002cac,
-0x0, 0x8002c4f, 0x0, 0x800172f,
-0x3c0a0004, 0x800328a, 0x0, 0x8001a52,
-0x0, 0x800394d, 0x0, 0x80038f4,
-0x0, 0x800172f, 0x3c0a0006, 0x80039bb,
-0x3c0a0007, 0x800172f, 0x3c0a0008, 0x800172f,
-0x3c0a0009, 0x8003a13, 0x0, 0x8002ea6,
-0x0, 0x800172f, 0x3c0a000b, 0x800172f,
-0x3c0a000c, 0x800172f, 0x3c0a000d, 0x80028fb,
-0x0, 0x8002890, 0x0, 0x800172f,
-0x3c0a000e, 0x800208c, 0x0, 0x8001964,
-0x0, 0x8001a04, 0x0, 0x8003ca6,
-0x0, 0x8003c94, 0x0, 0x800172f,
-0x0, 0x800191a, 0x0, 0x800172f,
-0x0, 0x800172f, 0x3c0a0013, 0x800172f,
-0x3c0a0014, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0x3c1cc000, 0xafbf001c, 0xafb00018, 0x8f820140,
-0x24030003, 0xaf8300ec, 0x34420004, 0xc002b20,
-0xaf820140, 0x3c0100c0, 0xc001763, 0xac203ffc,
-0x401821, 0x3c020010, 0x3c010001, 0xac236e9c,
-0x10620011, 0x43102b, 0x14400002, 0x3c020020,
-0x3c020008, 0x1062000c, 0x24050100, 0x3c060001,
-0x8cc66e9c, 0x3c040001, 0x24845c74, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020020,
-0x3c010001, 0xac226e9c, 0x24020008, 0x3c010001,
-0xac226eb4, 0x2402001f, 0x3c010001, 0xac226ec4,
-0x24020016, 0x3c010001, 0xac226e98, 0x3c05fffe,
-0x34a56f08, 0x3c020001, 0x8c426e9c, 0x3c030002,
-0x24639010, 0x3c040001, 0x8c846cc4, 0x431023,
-0x14800002, 0x458021, 0x2610fa38, 0x2402f000,
-0x2028024, 0xc001785, 0x2002021, 0x2022823,
-0x3c040020, 0x821823, 0x651823, 0x247bb000,
-0x3c03fffe, 0x3463bf08, 0x363b821, 0x3c0600bf,
-0x34c6f000, 0x3c070001, 0x8ce76cc0, 0x3c0300bf,
-0x3463e000, 0x852023, 0x3c010001, 0xac246ea8,
-0x822023, 0x3c010001, 0xac256e90, 0x52842,
-0x3c010001, 0xac226e84, 0x27620ffc, 0x3c010001,
-0xac226d20, 0x27621ffc, 0xdb3023, 0x7b1823,
-0x3c010001, 0xac246e88, 0x3c010001, 0xac256eac,
-0x3c010001, 0xac226d24, 0xaf860150, 0x10e00011,
-0xaf830250, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021,
-0xc001749, 0x0, 0x3c020001, 0x8c426cd0,
-0x3c030001, 0x8c636cd4, 0x2442fe00, 0x24630200,
-0x3c010001, 0xac226cd0, 0x3c010001, 0x10000004,
-0xac236cd4, 0x3c1d0001, 0x8fbd6d20, 0x3a0f021,
-0x3c020001, 0x8c426cc4, 0x1040000d, 0x26fafa38,
-0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
-0x3c1a0001, 0x8f5a6cd4, 0x2442fa38, 0x246305c8,
-0x3c010001, 0xac226cd0, 0x3c010001, 0xac236cd4,
-0x3c020001, 0x8c426cc8, 0x14400003, 0x0,
-0x3c010001, 0xac206cd0, 0xc001151, 0x0,
-0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
-0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
-0x27bdff98, 0xafb00048, 0x3c100001, 0x8e1066b8,
-0xafb20050, 0x3c120000, 0x26524100, 0xafbf0060,
-0xafbe005c, 0xafb50058, 0xafb30054, 0xafb1004c,
-0xafa20034, 0xafa30030, 0xafa00010, 0xafa00014,
-0x8f860040, 0x3c040001, 0x24845c80, 0x24050200,
-0x3c010001, 0xac326e80, 0xc002b3b, 0x2003821,
-0x8f830040, 0x3c02f000, 0x621824, 0x3c026000,
-0x1062000b, 0xa3a0003f, 0x240e0001, 0x3c040001,
-0x24845c88, 0xa3ae003f, 0xafa00010, 0xafa00014,
-0x8f860040, 0x24050300, 0xc002b3b, 0x2003821,
-0x8f820240, 0x3c030001, 0x431025, 0xaf820240,
-0xaf800048, 0x8f820048, 0x14400005, 0x0,
-0xaf800048, 0x8f820048, 0x10400004, 0x0,
-0xaf800048, 0x10000003, 0x2e02021, 0xaf80004c,
-0x2e02021, 0x3c050001, 0xc002ba8, 0x34a540f8,
-0x3402021, 0xc002ba8, 0x240505c8, 0x3c020001,
-0x8c426ea8, 0x3c0d0001, 0x8dad6e88, 0x3c030001,
-0x8c636e84, 0x3c080001, 0x8d086e90, 0x3c090001,
-0x8d296eac, 0x3c0a0001, 0x8d4a6eb4, 0x3c0b0001,
-0x8d6b6ec4, 0x3c0c0001, 0x8d8c6e98, 0x3c040001,
-0x24845c94, 0x24050400, 0xaf42013c, 0x8f42013c,
-0x24060001, 0x24070001, 0xaf400000, 0xaf4d0138,
-0xaf430144, 0xaf480148, 0xaf49014c, 0xaf4a0150,
-0xaf4b0154, 0xaf4c0158, 0x2442ff80, 0xaf420140,
-0x24020001, 0xafa20010, 0xc002b3b, 0xafa00014,
-0x8f420138, 0xafa20010, 0x8f42013c, 0xafa20014,
-0x8f460144, 0x8f470148, 0x3c040001, 0x24845ca0,
-0xc002b3b, 0x24050500, 0xafb70010, 0xafba0014,
-0x8f46014c, 0x8f470150, 0x3c040001, 0x24845cac,
-0xc002b3b, 0x24050600, 0x3c020001, 0x8c426e9c,
-0x3603821, 0x3c060002, 0x24c69010, 0x2448ffff,
-0x1061824, 0xe81024, 0x43102b, 0x10400006,
-0x24050900, 0x3c040001, 0x24845cb8, 0xafa80010,
-0xc002b3b, 0xafa00014, 0x8f82000c, 0xafa20010,
-0x8f82003c, 0xafa20014, 0x8f860000, 0x8f870004,
-0x3c040001, 0x24845cc4, 0xc002b3b, 0x24051000,
-0x8c020220, 0x8c030224, 0x8c060218, 0x8c07021c,
-0x3c040001, 0x24845ccc, 0x24051100, 0xafa20010,
-0xc002b3b, 0xafa30014, 0xaf800054, 0xaf80011c,
-0x8c020218, 0x30420002, 0x10400009, 0x0,
-0x8c020220, 0x3c030002, 0x34630004, 0x431025,
-0xaf42000c, 0x8c02021c, 0x10000008, 0x34420004,
-0x8c020220, 0x3c030002, 0x34630006, 0x431025,
-0xaf42000c, 0x8c02021c, 0x34420006, 0xaf420014,
-0x8c020218, 0x30420010, 0x1040000a, 0x0,
-0x8c02021c, 0x34420004, 0xaf420010, 0x8c020220,
-0x3c03000a, 0x34630004, 0x431025, 0x10000009,
-0xaf420008, 0x8c020220, 0x3c03000a, 0x34630006,
-0x431025, 0xaf420008, 0x8c02021c, 0x34420006,
-0xaf420010, 0x24020001, 0xaf8200a0, 0xaf8200b0,
-0x8f830054, 0x8f820054, 0xaf8000d0, 0xaf8000c0,
-0x10000002, 0x24630064, 0x8f820054, 0x621023,
-0x2c420065, 0x1440fffc, 0x0, 0x8c040208,
-0x8c05020c, 0x26e20028, 0xaee20020, 0x24020490,
-0xaee20010, 0xaee40008, 0xaee5000c, 0x26e40008,
-0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094,
-0x8c820018, 0xaf8200b4, 0x9482000a, 0xaf82009c,
-0x8f420014, 0xaf8200b0, 0x8f8200b0, 0x30420004,
-0x1440fffd, 0x0, 0x8f8200b0, 0x3c03ef00,
-0x431024, 0x10400021, 0x0, 0x8f8200b4,
-0xafa20010, 0x8f820090, 0x8f830094, 0x3c040001,
-0x24845cd4, 0xafa30014, 0x8f8600b0, 0x8f87009c,
-0x3c050001, 0xc002b3b, 0x34a5200d, 0x3c040001,
-0x24845ce0, 0x240203c0, 0xafa20010, 0xafa00014,
-0x8f860144, 0x3c070001, 0x24e75ce8, 0xc002b3b,
-0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c,
-0x8f820220, 0x34420004, 0xaf820220, 0x8f820140,
-0x3c030001, 0x431025, 0xaf820140, 0x96e20472,
-0x96e60452, 0x96e70462, 0xafa20010, 0x96e20482,
-0x3c040001, 0x24845d14, 0x24051200, 0xc002b3b,
-0xafa20014, 0x96f00452, 0x32020001, 0x10400002,
-0xb021, 0x24160001, 0x32020002, 0x54400001,
-0x36d60002, 0x32020008, 0x54400001, 0x36d60004,
-0x32020010, 0x54400001, 0x36d60008, 0x32020020,
-0x54400001, 0x36d60010, 0x32020040, 0x54400001,
-0x36d60020, 0x32020080, 0x54400001, 0x36d60040,
-0x96e60482, 0x30c20200, 0x54400001, 0x36d64000,
-0x96e30472, 0x30620200, 0x10400003, 0x30620100,
-0x10000003, 0x36d62000, 0x54400001, 0x36d61000,
-0x96f00462, 0x32c24000, 0x14400004, 0x3207009b,
-0x30c2009b, 0x14e20007, 0x240e0001, 0x32c22000,
-0x1440000d, 0x32020001, 0x3062009b, 0x10e20009,
-0x240e0001, 0x3c040001, 0x24845d20, 0x24051300,
-0x2003821, 0xa3ae003f, 0xafa30010, 0xc002b3b,
-0xafa00014, 0x32020001, 0x54400001, 0x36d60080,
-0x32020002, 0x54400001, 0x36d60100, 0x32020008,
-0x54400001, 0x36d60200, 0x32020010, 0x54400001,
-0x36d60400, 0x32020080, 0x54400001, 0x36d60800,
-0x8c020218, 0x30420200, 0x10400002, 0x3c020008,
-0x2c2b025, 0x8c020218, 0x30420800, 0x10400002,
-0x3c020080, 0x2c2b025, 0x8c020218, 0x30420400,
-0x10400002, 0x3c020100, 0x2c2b025, 0x8c020218,
-0x30420100, 0x10400002, 0x3c020200, 0x2c2b025,
-0x8c020218, 0x30420080, 0x10400002, 0x3c020400,
-0x2c2b025, 0x8c020218, 0x30422000, 0x10400002,
-0x3c020010, 0x2c2b025, 0x8c020218, 0x30424000,
-0x10400002, 0x3c020020, 0x2c2b025, 0x8c020218,
-0x30421000, 0x10400002, 0x3c020040, 0x2c2b025,
-0x8ee20498, 0x8ee3049c, 0xaf420160, 0xaf430164,
-0x8ee204a0, 0x8ee304a4, 0xaf420168, 0xaf43016c,
-0x8ee204a8, 0x8ee304ac, 0xaf420170, 0xaf430174,
-0x8ee20428, 0x8ee3042c, 0xaf420178, 0xaf43017c,
-0x8ee20448, 0x8ee3044c, 0xaf420180, 0xaf430184,
-0x8ee20458, 0x8ee3045c, 0xaf420188, 0xaf43018c,
-0x8ee20468, 0x8ee3046c, 0xaf420190, 0xaf430194,
-0x8ee20478, 0x8ee3047c, 0xaf420198, 0xaf43019c,
-0x8ee20488, 0x8ee3048c, 0xaf4201a0, 0xaf4301a4,
-0x8ee204b0, 0x8ee304b4, 0x24040080, 0xaf4201a8,
-0xaf4301ac, 0xc002ba8, 0x24050080, 0x8c02025c,
-0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200,
-0x24060008, 0xc002bbf, 0xaf4201f8, 0x3c043b9a,
-0x3484ca00, 0x3821, 0x24020006, 0x24030002,
-0xaf4201f4, 0x240203e8, 0xaf430204, 0xaf430200,
-0xaf4401fc, 0xaf420294, 0x24020001, 0xaf430290,
-0xaf42029c, 0x3c030001, 0x671821, 0x90636cd8,
-0x3471021, 0x24e70001, 0xa043022c, 0x2ce2000f,
-0x1440fff8, 0x3471821, 0x24e70001, 0x3c080001,
-0x350840f8, 0x8f820040, 0x3c040001, 0x24845d2c,
-0x24051400, 0x21702, 0x24420030, 0xa062022c,
-0x3471021, 0xa040022c, 0x8c070218, 0x2c03021,
-0x240205c8, 0xafa20010, 0xc002b3b, 0xafa80014,
-0x3c040001, 0x24845d38, 0x3c050000, 0x24a55c80,
-0x24060010, 0x27b10030, 0x2203821, 0x27b30034,
-0xc0017a3, 0xafb30010, 0x3c030001, 0x8c636cc8,
-0x1060000a, 0x408021, 0x8fa30030, 0x2405ff00,
-0x8fa20034, 0x246400ff, 0x852024, 0x831823,
-0x431023, 0xafa20034, 0xafa40030, 0x3c040001,
-0x24845d44, 0x3c050000, 0x24a54100, 0x24060108,
-0x2203821, 0xc0017a3, 0xafb30010, 0x409021,
-0x32c20003, 0x3c010001, 0xac326e80, 0x10400045,
-0x2203821, 0x8f820050, 0x3c030010, 0x431024,
-0x10400016, 0x0, 0x8c020218, 0x30420040,
-0x1040000f, 0x24020001, 0x8f820050, 0x8c030218,
-0x240e0001, 0x3c040001, 0x24845d50, 0xa3ae003f,
-0xafa20010, 0xafa30014, 0x8f870040, 0x24051500,
-0xc002b3b, 0x2c03021, 0x10000004, 0x0,
-0x3c010001, 0x370821, 0xa02240f4, 0x3c040001,
-0x24845d5c, 0x3c050001, 0x24a55b40, 0x3c060001,
-0x24c65bac, 0xc53023, 0x8f420010, 0x27b30030,
-0x2603821, 0x27b10034, 0x34420a00, 0xaf420010,
-0xc0017a3, 0xafb10010, 0x3c040001, 0x24845d70,
-0x3c050001, 0x24a5b714, 0x3c060001, 0x24c6ba90,
-0xc53023, 0x2603821, 0xaf420108, 0xc0017a3,
-0xafb10010, 0x3c040001, 0x24845d8c, 0x3c050001,
-0x24a5be58, 0x3c060001, 0x24c6c900, 0xc53023,
-0x2603821, 0x3c010001, 0xac226ef4, 0xc0017a3,
-0xafb10010, 0x3c040001, 0x24845da4, 0x10000024,
-0x24051600, 0x3c040001, 0x24845dac, 0x3c050001,
-0x24a5a10c, 0x3c060001, 0x24c6a238, 0xc53023,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845dbc,
-0x3c050001, 0x24a5b2b0, 0x3c060001, 0x24c6b70c,
-0xc53023, 0x2203821, 0xaf420108, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845dd0, 0x3c050001,
-0x24a5ba98, 0x3c060001, 0x24c6be50, 0xc53023,
-0x2203821, 0x3c010001, 0xac226ef4, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845de4, 0x24051650,
-0x2c03021, 0x3821, 0x3c010001, 0xac226ef8,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x32c20020,
-0x10400021, 0x27a70030, 0x3c040001, 0x24845df0,
-0x3c050001, 0x24a5b13c, 0x3c060001, 0x24c6b2a8,
-0xc53023, 0x24022000, 0xaf42001c, 0x27a20034,
-0xc0017a3, 0xafa20010, 0x21900, 0x31982,
-0x3c040800, 0x641825, 0xae430028, 0x24030010,
-0xaf43003c, 0x96e30450, 0xaf430040, 0x8f430040,
-0x3c040001, 0x24845e04, 0xafa00014, 0xafa30010,
-0x8f47001c, 0x24051660, 0x3c010001, 0xac226ef0,
-0x10000025, 0x32c60020, 0x8ee20448, 0x8ee3044c,
-0xaf43001c, 0x8f42001c, 0x2442e000, 0x2c422001,
-0x1440000a, 0x240e0001, 0x3c040001, 0x24845e10,
-0xa3ae003f, 0xafa00010, 0xafa00014, 0x8f46001c,
-0x24051700, 0xc002b3b, 0x3821, 0x3c020000,
-0x24425cbc, 0x21100, 0x21182, 0x3c030800,
-0x431025, 0xae420028, 0x24020008, 0xaf42003c,
-0x96e20450, 0xaf420040, 0x8f420040, 0x3c040001,
-0x24845e1c, 0xafa00014, 0xafa20010, 0x8f47001c,
-0x24051800, 0x32c60020, 0xc002b3b, 0x0,
-0x3c050fff, 0x3c030001, 0x8c636ef4, 0x34a5ffff,
-0x2403021, 0x3c020001, 0x8c426ef8, 0x3c040800,
-0x651824, 0x31882, 0x641825, 0x451024,
-0x21082, 0x441025, 0xacc20080, 0x32c20180,
-0x10400056, 0xacc30020, 0x8f82005c, 0x3c030080,
-0x431024, 0x1040000d, 0x0, 0x8f820050,
-0xafa20010, 0x8f82005c, 0x240e0001, 0x3c040001,
-0x24845e28, 0xa3ae003f, 0xafa20014, 0x8f870040,
-0x24051900, 0xc002b3b, 0x2c03021, 0x8f820050,
-0x3c030010, 0x431024, 0x10400016, 0x0,
-0x8c020218, 0x30420040, 0x1040000f, 0x24020001,
-0x8f820050, 0x8c030218, 0x240e0001, 0x3c040001,
-0x24845d50, 0xa3ae003f, 0xafa20010, 0xafa30014,
-0x8f870040, 0x24052000, 0xc002b3b, 0x2c03021,
-0x10000004, 0x0, 0x3c010001, 0x370821,
-0xa02240f4, 0x3c040001, 0x24845e34, 0x3c050001,
-0x24a55ac0, 0x3c060001, 0x24c65b38, 0xc53023,
-0x8f420008, 0x27b30030, 0x2603821, 0x27b10034,
-0x34420e00, 0xaf420008, 0xc0017a3, 0xafb10010,
-0x3c040001, 0x24845e4c, 0x3c050001, 0x24a5d8b4,
-0x3c060001, 0x24c6e3c8, 0xc53023, 0x2603821,
-0xaf42010c, 0xc0017a3, 0xafb10010, 0x3c040001,
-0x24845e64, 0x3c050001, 0x24a5e9ac, 0x3c060001,
-0x24c6f0f0, 0xc53023, 0x2603821, 0x3c010001,
-0xac226f04, 0xc0017a3, 0xafb10010, 0x3c040001,
-0x24845e7c, 0x10000027, 0x24052100, 0x3c040001,
-0x24845e84, 0x3c050001, 0x24a59fc8, 0x3c060001,
-0x24c6a104, 0xc53023, 0x27b10030, 0x2203821,
-0x27b30034, 0xc0017a3, 0xafb30010, 0x3c040001,
-0x24845e94, 0x3c050001, 0x24a5cad4, 0x3c060001,
-0x24c6d8ac, 0xc53023, 0x2203821, 0xaf42010c,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845ea4,
-0x3c050001, 0x24a5e84c, 0x3c060001, 0x24c6e9a4,
-0xc53023, 0x2203821, 0x3c010001, 0xac226f04,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845eb8,
-0x24052150, 0x2c03021, 0x3821, 0x3c010001,
-0xac226f10, 0xafa00010, 0xc002b3b, 0xafa00014,
-0x3c110fff, 0x3c030001, 0x8c636f04, 0x3631ffff,
-0x2409821, 0x3c020001, 0x8c426f10, 0x3c0e0800,
-0x711824, 0x31882, 0x6e1825, 0x511024,
-0x21082, 0x4e1025, 0xae630038, 0xae620078,
-0x8c020218, 0x30420040, 0x14400004, 0x24020001,
-0x3c010001, 0x370821, 0xa02240f4, 0x3c040001,
-0x24845ec4, 0x3c050001, 0x24a5e3d0, 0x3c060001,
-0x24c6e52c, 0xc53023, 0x27be0030, 0x3c03821,
-0x27b50034, 0xc0017a3, 0xafb50010, 0x3c010001,
-0xac226efc, 0x511024, 0x21082, 0x3c0e0800,
-0x4e1025, 0xae620050, 0x32c22000, 0x10400006,
-0x3c03821, 0x3c020000, 0x24425cbc, 0x2221024,
-0x1000000f, 0x21082, 0x3c040001, 0x24845ed8,
-0x3c050001, 0x24a5e534, 0x3c060001, 0x24c6e6e4,
-0xc53023, 0xc0017a3, 0xafb50010, 0x3c010001,
-0xac226f14, 0x511024, 0x21082, 0x3c0e0800,
-0x4e1025, 0xae620048, 0x32c24000, 0x10400005,
-0x27a70030, 0x3c020000, 0x24425cbc, 0x1000000e,
-0x21100, 0x3c040001, 0x24845ef0, 0x3c050001,
-0x24a5e6ec, 0x3c060001, 0x24c6e844, 0xc53023,
-0x27a20034, 0xc0017a3, 0xafa20010, 0x3c010001,
-0xac226f08, 0x21100, 0x21182, 0x3c030800,
-0x431025, 0xae420060, 0x3c040001, 0x24845f08,
-0x3c050001, 0x24a58230, 0x3c060001, 0x24c68650,
-0xc53023, 0x27b10030, 0x2203821, 0x27b30034,
-0xc0017a3, 0xafb30010, 0x3c0e0fff, 0x35ceffff,
-0x3c040001, 0x24845f14, 0x3c050000, 0x24a56468,
-0x3c060000, 0x24c66588, 0xc53023, 0x2203821,
-0x240f021, 0x3c010001, 0xac226edc, 0x4e1024,
-0x21082, 0x3c150800, 0x551025, 0xafae0044,
-0xafc200b8, 0xc0017a3, 0xafb30010, 0x3c040001,
-0x24845f20, 0x3c050000, 0x24a56590, 0x3c060000,
-0x24c66808, 0x8fae0044, 0xc53023, 0x2203821,
-0x3c010001, 0xac226ed0, 0x4e1024, 0x21082,
-0x551025, 0xafc200e8, 0xc0017a3, 0xafb30010,
-0x3c040001, 0x24845f38, 0x3c050000, 0x24a56810,
-0x3c060000, 0x24c66940, 0x8fae0044, 0xc53023,
-0x2203821, 0x3c010001, 0xac226ec8, 0x4e1024,
-0x21082, 0x551025, 0xafc200c0, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845f50, 0x3c050001,
-0x24a5fad0, 0x3c060001, 0x24c6fba8, 0x8fae0044,
-0xc53023, 0x2203821, 0x3c010001, 0xac226ed4,
-0x4e1024, 0x21082, 0x551025, 0xafc200c8,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845f5c,
-0x3c050001, 0x24a5c93c, 0x3c060001, 0x24c6ca20,
-0xc53023, 0x2203821, 0xaf420110, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845f6c, 0x3c050001,
-0x24a5c910, 0x3c060001, 0x24c6c934, 0xc53023,
-0x2203821, 0xaf420124, 0xc0017a3, 0xafb30010,
-0x3c040001, 0x24845f7c, 0x3c050001, 0x24a55a80,
-0x3c060001, 0x24c65aac, 0xc53023, 0x2203821,
-0xaf420120, 0xaf420114, 0xc0017a3, 0xafb30010,
-0x3c040001, 0x24845f88, 0x3c050001, 0x24a5f298,
-0x3c060001, 0x24c6f6b4, 0xc53023, 0x2203821,
-0xaf420118, 0xc0017a3, 0xafb30010, 0x8fae0044,
-0x3c010001, 0xac226f18, 0x4e1024, 0x21082,
-0x551025, 0xc003fc3, 0xafc200d0, 0xc003c40,
-0x0, 0xc0027a8, 0x0, 0xac000228,
-0xac00022c, 0x96e20450, 0x2442ffff, 0xaf420038,
-0x96e20460, 0xaf420080, 0x32c24000, 0x14400003,
-0x0, 0x96e20480, 0xaf420084, 0x96e70490,
-0x50e00001, 0x24070800, 0x24e2ffff, 0xaf420088,
-0xaf42007c, 0x24020800, 0x10e2000f, 0x32c24000,
-0x10400003, 0x24020400, 0x10e2000b, 0x0,
-0x240e0001, 0x3c040001, 0x24845f98, 0xa3ae003f,
-0x96e60490, 0x24052170, 0x2c03821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8f430138, 0x8f440138,
-0x24020001, 0xa34205c2, 0xaf430094, 0xaf440098,
-0xafa00010, 0xafa00014, 0x8f460080, 0x8f470084,
-0x3c040001, 0x24845fa4, 0xc002b3b, 0x24052200,
-0xc0024a4, 0x3c110800, 0x3c1433d8, 0x3694cb58,
-0x3c020800, 0x34420080, 0x3c040001, 0x24845fb0,
-0x3c050000, 0x24a55d00, 0x3c060000, 0x24c65d1c,
-0xc53023, 0x27a70030, 0xaf820060, 0x2402ffff,
-0xaf820064, 0x27a20034, 0xc0017a3, 0xafa20010,
-0x3c010001, 0xac226eb8, 0x21100, 0x21182,
-0x511025, 0xc0018fc, 0xae420000, 0x8f820240,
-0x3c030001, 0x431025, 0xaf820240, 0x3c020000,
-0x24424034, 0xaf820244, 0xaf800240, 0x8f820060,
-0x511024, 0x14400005, 0x3c030800, 0x8f820060,
-0x431024, 0x1040fffd, 0x0, 0xc003c4d,
-0x8821, 0x3c020100, 0xafa20020, 0x8f530018,
-0x240200ff, 0x56620001, 0x26710001, 0x8c020228,
-0x1622000e, 0x1330c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x24845c24, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000003f, 0x34a50100, 0xd71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0xc01821, 0x8f440178, 0x8f45017c, 0x1021,
-0x24070004, 0xafa70010, 0xafb10014, 0x8f48000c,
-0x24c604c0, 0x2e63021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x1440000b, 0x24070008,
-0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24845c2c, 0x3c050009, 0xafa20014, 0x8fa60020,
-0x1000001c, 0x34a50200, 0x8f440160, 0x8f450164,
-0x8f43000c, 0xaf510018, 0x8f860120, 0x24020010,
-0xafa20010, 0xafb10014, 0xafa30018, 0x8f42010c,
-0x40f809, 0x24c6001c, 0x14400010, 0x0,
-0x8f420340, 0x24420001, 0xaf420340, 0x8f420340,
-0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24845c34, 0x3c050009, 0xafa20014, 0x8fa60020,
-0x34a50300, 0xc002b3b, 0x2603821, 0x8f4202e4,
-0x24420001, 0xaf4202e4, 0x8f4202e4, 0x93a2003f,
-0x10400069, 0x3c020700, 0x34423000, 0xafa20028,
-0x8f530018, 0x240200ff, 0x12620002, 0x8821,
-0x26710001, 0x8c020228, 0x1622000e, 0x1330c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x24845c24, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60028, 0x1000003f,
-0x34a50100, 0xd71021, 0x8fa30028, 0x8fa4002c,
-0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
-0x8f45017c, 0x1021, 0x24070004, 0xafa70010,
-0xafb10014, 0x8f48000c, 0x24c604c0, 0x2e63021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24845c2c, 0x3c050009,
-0xafa20014, 0x8fa60028, 0x1000001c, 0x34a50200,
-0x8f440160, 0x8f450164, 0x8f43000c, 0xaf510018,
-0x8f860120, 0x24020010, 0xafa20010, 0xafb10014,
-0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400010, 0x0, 0x8f420340, 0x24420001,
-0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24845c34, 0x3c050009,
-0xafa20014, 0x8fa60028, 0x34a50300, 0xc002b3b,
-0x2603821, 0x8f4202f0, 0x24420001, 0xaf4202f0,
-0x8f4202f0, 0x3c040001, 0x24845fc0, 0xafa00010,
-0xafa00014, 0x8fa60028, 0x24052300, 0xc002b3b,
-0x3821, 0x10000004, 0x0, 0x8c020264,
-0x10400005, 0x0, 0x8f8200a0, 0x30420004,
-0x1440fffa, 0x0, 0x8f820044, 0x34420004,
-0xaf820044, 0x8f420308, 0x24420001, 0xaf420308,
-0x8f420308, 0x8f8200d8, 0x8f8300d4, 0x431023,
-0x2442ff80, 0xaf420090, 0x8f420090, 0x2842ff81,
-0x10400006, 0x24020001, 0x8f420090, 0x8f430144,
-0x431021, 0xaf420090, 0x24020001, 0xaf42008c,
-0x32c20008, 0x10400006, 0x0, 0x8f820214,
-0x3c038100, 0x3042ffff, 0x431025, 0xaf820214,
-0x3c030001, 0x8c636d94, 0x30620002, 0x10400009,
-0x30620001, 0x3c040001, 0x24845fcc, 0x3c050000,
-0x24a56d50, 0x3c060000, 0x24c671c8, 0x10000012,
-0xc53023, 0x10400009, 0x0, 0x3c040001,
-0x24845fdc, 0x3c050000, 0x24a571d0, 0x3c060000,
-0x24c67678, 0x10000008, 0xc53023, 0x3c040001,
-0x24845fec, 0x3c050000, 0x24a56948, 0x3c060000,
-0x24c66d48, 0xc53023, 0x27a70030, 0x27a20034,
-0xc0017a3, 0xafa20010, 0x3c010001, 0xac226ecc,
-0x3c020001, 0x8c426ecc, 0x3c030800, 0x21100,
-0x21182, 0x431025, 0xae420040, 0x8f8200a0,
-0xafa20010, 0x8f8200b0, 0xafa20014, 0x8f86005c,
-0x8f87011c, 0x3c040001, 0x24845ffc, 0x3c010001,
-0xac366ea4, 0x3c010001, 0xac206e94, 0x3c010001,
-0xac3c6e8c, 0x3c010001, 0xac3b6ebc, 0x3c010001,
-0xac376ec0, 0x3c010001, 0xac3a6ea0, 0xc002b3b,
-0x24052400, 0x8f820200, 0xafa20010, 0x8f820220,
-0xafa20014, 0x8f860044, 0x8f870050, 0x3c040001,
-0x24846008, 0xc002b3b, 0x24052500, 0x8f830060,
-0x74100b, 0x242000a, 0x200f821, 0x0,
-0xd, 0x8fbf0060, 0x8fbe005c, 0x8fb50058,
-0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048,
-0x3e00008, 0x27bd0068, 0x27bdffe0, 0x3c040001,
-0x24846014, 0x24052600, 0x3021, 0x3821,
-0xafbf0018, 0xafa00010, 0xc002b3b, 0xafa00014,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x3e00008,
-0x0, 0x3e00008, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x3e00008, 0x0, 0x3e00008, 0x0,
-0x27bdfde0, 0x27a50018, 0x3c04dead, 0x3484beef,
-0xafbf0218, 0x8f820150, 0x3c03001f, 0x3463ffff,
-0xafa40018, 0xa22823, 0xa32824, 0x8ca20000,
-0x1044000a, 0x0, 0xafa50010, 0x8ca20000,
-0xafa20014, 0x8f860150, 0x8f870250, 0x3c040001,
-0x2484601c, 0xc002b3b, 0x24052700, 0x8fbf0218,
-0x3e00008, 0x27bd0220, 0x27bdffe0, 0x3c06abba,
-0x34c6babe, 0xafb00018, 0x3c100004, 0x3c07007f,
-0x34e7ffff, 0xafbf001c, 0x102840, 0x8e040000,
-0x8ca30000, 0xaca00000, 0xae060000, 0x8ca20000,
-0xaca30000, 0x10460005, 0xae040000, 0xa08021,
-0xf0102b, 0x1040fff5, 0x102840, 0x3c040001,
-0x24846028, 0x24052800, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x2001021,
-0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
-0x8c020224, 0x3047003f, 0x10e00010, 0x803021,
-0x2821, 0x24030020, 0xe31024, 0x10400002,
-0x63042, 0xa62821, 0x31842, 0x1460fffb,
-0xe31024, 0x2402f000, 0xa22824, 0x3402ffff,
-0x45102b, 0x14400003, 0x3c020001, 0x10000008,
-0x3c020001, 0x3442ffff, 0x851823, 0x43102b,
-0x14400003, 0xa01021, 0x3c02fffe, 0x821021,
-0x3e00008, 0x0, 0x27bdffd0, 0xafb50028,
-0x8fb50040, 0xafb20020, 0xa09021, 0xafb1001c,
-0x24c60003, 0xafbf002c, 0xafb30024, 0xafb00018,
-0x8ea20000, 0x2403fffc, 0xc38024, 0x50102b,
-0x1440001b, 0xe08821, 0x8e330000, 0xafb00010,
-0x8ea20000, 0xafa20014, 0x8e270000, 0x24053000,
-0xc002b3b, 0x2403021, 0x8e230000, 0x702021,
-0x64102b, 0x10400007, 0x2402821, 0x8ca20000,
-0xac620000, 0x24630004, 0x64102b, 0x1440fffb,
-0x24a50004, 0x8ea20000, 0x501023, 0xaea20000,
-0x8e220000, 0x501021, 0x1000000b, 0xae220000,
-0x2402002d, 0xa0820000, 0xafb00010, 0x8ea20000,
-0x2409821, 0xafa20014, 0x8e270000, 0x24053100,
-0xc002b3b, 0x2603021, 0x2601021, 0x8fbf002c,
-0x8fb50028, 0x8fb30024, 0x8fb20020, 0x8fb1001c,
-0x8fb00018, 0x3e00008, 0x27bd0030, 0x27bdffe8,
-0x3c1cc000, 0x3c05fffe, 0x3c030001, 0x8c636e84,
-0x3c040001, 0x8c846e90, 0x34a5bf08, 0x24021ffc,
-0x3c010001, 0xac226cd0, 0x3c0200c0, 0x3c010001,
-0xac226cd4, 0x3c020020, 0xafbf0010, 0x3c0100c0,
-0xac201ffc, 0x431023, 0x441023, 0x245bb000,
-0x365b821, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021,
-0x3c0400c0, 0x34840200, 0x3c1a00c0, 0x3c0300c0,
-0x346307c8, 0x24021dfc, 0x3c010001, 0xac226cd0,
-0x24021834, 0x3c010001, 0xac246cd4, 0x3c010001,
-0xac226cd0, 0x3c010001, 0xac236cd4, 0xc00180d,
-0x375a0200, 0x8fbf0010, 0x3e00008, 0x27bd0018,
-0x27bdffc8, 0x3c040001, 0x24846034, 0x24053200,
-0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
-0x3021, 0x3603821, 0xafbf0030, 0xafb3002c,
-0xafb20028, 0xafb10024, 0xafb00020, 0xafa2001c,
-0xafa30018, 0xafb70010, 0xc002b3b, 0xafba0014,
-0xc001916, 0x0, 0x8f820240, 0x34420004,
-0xaf820240, 0x24020001, 0xaf420000, 0x3c020001,
-0x571021, 0x904240f4, 0x10400092, 0x2403fffc,
-0x3c100001, 0x2610ac73, 0x3c120001, 0x2652a84c,
-0x2121023, 0x438024, 0x8fa3001c, 0x3c040001,
-0x24846040, 0x70102b, 0x1440001a, 0x27b30018,
-0x8fb10018, 0x24053000, 0x2403021, 0xafb00010,
-0xafa30014, 0xc002b3b, 0x2203821, 0x8fa30018,
-0x702021, 0x64102b, 0x10400007, 0x2403021,
-0x8cc20000, 0xac620000, 0x24630004, 0x64102b,
-0x1440fffb, 0x24c60004, 0x8fa2001c, 0x501023,
-0xafa2001c, 0x8e620000, 0x501021, 0x1000000a,
-0xae620000, 0x2408821, 0x24053100, 0xafb00010,
-0xafa30014, 0x8fa70018, 0x2203021, 0x2402002d,
-0xc002b3b, 0xa0820000, 0x24070020, 0x8fa3001c,
-0x3c040001, 0x2484605c, 0x24120020, 0x3c010001,
-0xac316eb0, 0x2c620020, 0x1440001d, 0x27b10018,
-0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f50,
-0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821,
-0x8fa30018, 0x3c040001, 0x24846f50, 0x24650020,
-0x65102b, 0x10400007, 0x0, 0x8c820000,
-0xac620000, 0x24630004, 0x65102b, 0x1440fffb,
-0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c,
-0x8e220000, 0x521021, 0x1000000b, 0xae220000,
-0x3c100001, 0x26106f50, 0x24053100, 0xafa70010,
-0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d,
-0xc002b3b, 0xa0820000, 0x24070020, 0x3c040001,
-0x24846070, 0x8fa3001c, 0x24120020, 0x3c010001,
-0xac306ee4, 0x2c620020, 0x1440001d, 0x27b10018,
-0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f70,
-0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821,
-0x8fa30018, 0x3c040001, 0x24846f70, 0x24650020,
-0x65102b, 0x10400007, 0x0, 0x8c820000,
-0xac620000, 0x24630004, 0x65102b, 0x1440fffb,
-0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c,
-0x8e220000, 0x521021, 0x1000000b, 0xae220000,
-0x3c100001, 0x26106f70, 0x24053100, 0xafa70010,
-0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d,
-0xc002b3b, 0xa0820000, 0x3c010001, 0x10000031,
-0xac306ee0, 0x3c100001, 0x2610821f, 0x3c120001,
-0x2652809c, 0x2121023, 0x438024, 0x8fa3001c,
-0x3c040001, 0x24846084, 0x70102b, 0x1440001a,
-0x27b30018, 0x8fb10018, 0x24053000, 0x2403021,
-0xafb00010, 0xafa30014, 0xc002b3b, 0x2203821,
-0x8fa30018, 0x702021, 0x64102b, 0x10400007,
-0x2403021, 0x8cc20000, 0xac620000, 0x24630004,
-0x64102b, 0x1440fffb, 0x24c60004, 0x8fa2001c,
-0x501023, 0xafa2001c, 0x8e620000, 0x501021,
-0x1000000a, 0xae620000, 0x2408821, 0x24053100,
-0xafb00010, 0xafa30014, 0x8fa70018, 0x2203021,
-0x2402002d, 0xc002b3b, 0xa0820000, 0x3c010001,
-0xac316eb0, 0x3c030001, 0x8c636eb0, 0x24020400,
-0x60f809, 0xaf820070, 0x8fbf0030, 0x8fb3002c,
-0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
-0x27bd0038, 0x0, 0x0, 0x8f820040,
-0x3c03f000, 0x431024, 0x3c036000, 0x14430006,
-0x0, 0x8f820050, 0x2403ff80, 0x431024,
-0x34420055, 0xaf820050, 0x8f820054, 0x244203e8,
-0xaf820058, 0x240201f4, 0xaf4200e0, 0x24020004,
-0xaf4200e8, 0x24020002, 0xaf4001b0, 0xaf4000e4,
-0xaf4200dc, 0xaf4000d8, 0xaf4000d4, 0x3e00008,
-0xaf4000d0, 0x8f820054, 0x24420005, 0x3e00008,
-0xaf820078, 0x27bdffe8, 0xafbf0010, 0x8f820054,
-0x244203e8, 0xaf820058, 0x3c020800, 0x2c21024,
-0x10400004, 0x3c02f7ff, 0x3442ffff, 0x2c2b024,
-0x36940040, 0x3c020001, 0x8c426da8, 0x10400017,
-0x3c020200, 0x3c030001, 0x8c636f1c, 0x10600016,
-0x282a025, 0x3c020001, 0x8c426e44, 0x14400012,
-0x3c020200, 0x3c020001, 0x8c426d94, 0x30420003,
-0x1440000d, 0x3c020200, 0x8f830224, 0x3c020002,
-0x8c428fec, 0x10620008, 0x3c020200, 0xc003daf,
-0x0, 0x10000004, 0x3c020200, 0xc004196,
-0x0, 0x3c020200, 0x2c21024, 0x10400003,
-0x0, 0xc001f4b, 0x0, 0x8f4200d8,
-0x8f4300dc, 0x24420001, 0xaf4200d8, 0x43102b,
-0x14400003, 0x0, 0xaf4000d8, 0x36940080,
-0x8c030238, 0x1060000c, 0x0, 0x8f4201b0,
-0x244203e8, 0xaf4201b0, 0x43102b, 0x14400006,
-0x0, 0x934205c5, 0x14400003, 0x0,
-0xc001da0, 0x0, 0x8fbf0010, 0x3e00008,
-0x27bd0018, 0x3e00008, 0x0, 0x27bdffd8,
-0xafbf0020, 0x8f43002c, 0x8f420038, 0x10620059,
-0x0, 0x3c020001, 0x571021, 0x904240f0,
-0x10400026, 0x24070008, 0x8f440170, 0x8f450174,
-0x8f48000c, 0x8f860120, 0x24020020, 0xafa20010,
-0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809,
-0x24c6001c, 0x14400011, 0x24020001, 0x3c010001,
-0x370821, 0xa02240f0, 0x8f820124, 0xafa20010,
-0x8f820128, 0x3c040001, 0x24846128, 0xafa20014,
-0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b,
-0x34a50900, 0x1000005c, 0x0, 0x8f420300,
-0x24420001, 0xaf420300, 0x8f420300, 0x8f42002c,
-0xa34005c1, 0x10000027, 0xaf420038, 0x8f440170,
-0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
-0x24020080, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
-0x24020001, 0x3c010001, 0x370821, 0xa02240f1,
-0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x24846134, 0xafa20014, 0x8f46002c, 0x8f870120,
-0x3c050009, 0xc002b3b, 0x34a51100, 0x10000036,
-0x0, 0x8f420300, 0x8f43002c, 0x24420001,
-0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1,
-0xaf430038, 0x3c010001, 0x370821, 0xa02040f1,
-0x3c010001, 0x370821, 0xa02040f0, 0x10000026,
-0xaf400034, 0x934205c1, 0x1040001d, 0x0,
-0xa34005c1, 0x8f820040, 0x30420001, 0x14400008,
-0x2021, 0x8c030104, 0x24020001, 0x50620005,
-0x24040001, 0x8c020264, 0x10400003, 0x801021,
-0x24040001, 0x801021, 0x10400006, 0x0,
-0x8f42030c, 0x24420001, 0xaf42030c, 0x10000008,
-0x8f42030c, 0x8f820044, 0x34420004, 0xaf820044,
-0x8f420308, 0x24420001, 0xaf420308, 0x8f420308,
-0x3c010001, 0x370821, 0xa02040f0, 0x3c010001,
-0x370821, 0xa02040f1, 0x8f420000, 0x10400007,
-0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd,
-0x0, 0x10000005, 0x0, 0xaf800048,
-0x8f820048, 0x1040fffd, 0x0, 0x8f820060,
-0x3c03ff7f, 0x3463ffff, 0x431024, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x10000002,
-0xaf80004c, 0xaf800048, 0x8fbf0020, 0x3e00008,
-0x27bd0028, 0x3e00008, 0x0, 0x27bdffd8,
-0xafbf0020, 0x8f430044, 0x8f42007c, 0x10620029,
-0x24070008, 0x8f440168, 0x8f45016c, 0x8f48000c,
-0x8f860120, 0x24020040, 0xafa20010, 0xafa30014,
-0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400011, 0x24020001, 0x3c010001, 0x370821,
-0xa02240f2, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x2484613c, 0xafa20014, 0x8f460044,
-0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51300,
-0x1000000f, 0x0, 0x8f420304, 0x24420001,
-0xaf420304, 0x8f420304, 0x8f420044, 0xaf42007c,
-0x3c010001, 0x370821, 0xa02040f2, 0x10000004,
-0xaf400078, 0x3c010001, 0x370821, 0xa02040f2,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x3c03feff, 0x3463ffff,
-0x431024, 0xaf820060, 0x8f420000, 0x10400003,
-0x0, 0x10000002, 0xaf80004c, 0xaf800048,
-0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008,
-0x0, 0x3c020001, 0x8c426da8, 0x27bdffa8,
-0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044,
-0xafb20040, 0xafb1003c, 0xafb00038, 0x104000d5,
-0x8f900044, 0x8f4200d0, 0x24430001, 0x2842000b,
-0x144000e4, 0xaf4300d0, 0x8f420004, 0x30420002,
-0x1440009c, 0xaf4000d0, 0x8f420004, 0x3c030001,
-0x8c636d98, 0x34420002, 0xaf420004, 0x24020001,
-0x14620003, 0x3c020600, 0x10000002, 0x34423000,
-0x34421000, 0xafa20020, 0x8f4a0018, 0xafaa0034,
-0x27aa0020, 0xafaa002c, 0x8faa0034, 0x240200ff,
-0x11420002, 0x1821, 0x25430001, 0x8c020228,
-0x609821, 0x1662000e, 0x3c050009, 0x8f42033c,
-0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228,
-0x8fa70034, 0x3c040001, 0x2484610c, 0xafa00014,
-0xafa20010, 0x8fa60020, 0x10000070, 0x34a50500,
-0x8faa0034, 0xa38c0, 0xf71021, 0x8fa30020,
-0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054,
-0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9,
-0x1040001b, 0xa821, 0xe09021, 0x265e04c0,
-0x8f440178, 0x8f45017c, 0x2401821, 0x240a0004,
-0xafaa0010, 0xafb30014, 0x8f48000c, 0x1021,
-0x2fe3021, 0xafa80018, 0x8f48010c, 0x24070008,
-0xa32821, 0xa3482b, 0x822021, 0x100f809,
-0x892021, 0x54400006, 0x24150001, 0x8f820054,
-0x2221023, 0x2c4203e9, 0x1440ffe9, 0x0,
-0x32a200ff, 0x54400018, 0xaf530018, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa002c, 0x8fa70034, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846118, 0xafa20014, 0x8d460000,
-0x3c050009, 0x10000035, 0x34a50600, 0x8f420308,
-0x24150001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001e, 0x32a200ff, 0x8f830054, 0x8f820054,
-0x247103e8, 0x2221023, 0x2c4203e9, 0x10400016,
-0xa821, 0x3c1e0020, 0x24120010, 0x8f42000c,
-0x8f440160, 0x8f450164, 0x8f860120, 0xafb20010,
-0xafb30014, 0x5e1025, 0xafa20018, 0x8f42010c,
-0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3,
-0x0, 0x8f820054, 0x2221023, 0x2c4203e9,
-0x1440ffee, 0x0, 0x32a200ff, 0x14400011,
-0x3c050009, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0x8fa70034,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846120,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
-0x0, 0x8f4202ec, 0x24420001, 0xaf4202ec,
-0x8f4202ec, 0x8f420004, 0x30420001, 0x50400029,
-0x36100040, 0x3c020400, 0x2c21024, 0x10400013,
-0x2404ffdf, 0x8f420250, 0x8f430254, 0x8f4401b4,
-0x14640006, 0x36100040, 0x8f420270, 0x8f430274,
-0x8f4401b8, 0x10640007, 0x2402ffdf, 0x8f420250,
-0x8f430254, 0x8f440270, 0x8f450274, 0x10000012,
-0x3a100020, 0x1000002b, 0x2028024, 0x8f420250,
-0x8f430254, 0x8f4501b4, 0x14650006, 0x2048024,
-0x8f420270, 0x8f430274, 0x8f4401b8, 0x50640021,
-0x36100040, 0x8f420250, 0x8f430254, 0x8f440270,
-0x8f450274, 0x3a100040, 0xaf4301b4, 0x10000019,
-0xaf4501b8, 0x8f4200d4, 0x24430001, 0x10000011,
-0x28420033, 0x8f420004, 0x30420001, 0x10400009,
-0x3c020400, 0x2c21024, 0x10400004, 0x2402ffdf,
-0x2028024, 0x1000000b, 0x36100040, 0x10000009,
-0x36100060, 0x8f4200d4, 0x36100040, 0x24430001,
-0x284201f5, 0x14400003, 0xaf4300d4, 0xaf4000d4,
-0x3a100020, 0xaf900044, 0x2402ff7f, 0x282a024,
-0x8fbf0050, 0x8fbe004c, 0x8fb50048, 0x8fb30044,
-0x8fb20040, 0x8fb1003c, 0x8fb00038, 0x3e00008,
-0x27bd0058, 0x3e00008, 0x0, 0x3c020001,
-0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
-0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
-0x104000c7, 0xafb00030, 0x8f4200d0, 0x24430001,
-0x2842000b, 0x144000da, 0xaf4300d0, 0x8f420004,
-0x30420002, 0x14400097, 0xaf4000d0, 0x8f420004,
-0x3c030001, 0x8c636d98, 0x34420002, 0xaf420004,
-0x24020001, 0x14620003, 0x3c020600, 0x10000002,
-0x34423000, 0x34421000, 0xafa20020, 0x1821,
-0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
-0xafaa002c, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006d, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846118, 0x3c050009, 0xafa20014,
-0x8d460000, 0x10000035, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001e, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400016,
-0x9821, 0x3c150020, 0x24110010, 0x8f42000c,
-0x8f440160, 0x8f450164, 0x8f860120, 0xafb10010,
-0xafb20014, 0x551025, 0xafa20018, 0x8f42010c,
-0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3,
-0x0, 0x8f820054, 0x2021023, 0x2c4203e9,
-0x1440ffee, 0x0, 0x326200ff, 0x14400011,
-0x0, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846120, 0x3c050009,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
-0x3c03821, 0x8f4202ec, 0x24420001, 0xaf4202ec,
-0x8f4202ec, 0x8f420004, 0x30420001, 0x10400018,
-0x24040001, 0x8f420250, 0x8f430254, 0x8f4501b4,
-0x3c010001, 0x14650006, 0xa0246cf1, 0x8f420270,
-0x8f430274, 0x8f4401b8, 0x10640021, 0x0,
-0x8f420250, 0x8f430254, 0x3c040001, 0x90846cf0,
-0x8f460270, 0x8f470274, 0x38840001, 0xaf4301b4,
-0xaf4701b8, 0x3c010001, 0x10000025, 0xa0246cf0,
-0x8f4200d4, 0x3c010001, 0xa0206cf0, 0x24430001,
-0x28420033, 0x1440001e, 0xaf4300d4, 0x3c020001,
-0x90426cf1, 0xaf4000d4, 0x10000017, 0x38420001,
-0x8f420004, 0x30420001, 0x10400008, 0x0,
-0xc00565a, 0x2021, 0x3c010001, 0xa0206cf1,
-0x3c010001, 0x1000000e, 0xa0206cf0, 0x8f4200d4,
-0x3c010001, 0xa0206cf0, 0x24430001, 0x284201f5,
-0x14400007, 0xaf4300d4, 0x3c020001, 0x90426cf1,
-0xaf4000d4, 0x421026, 0x3c010001, 0xa0226cf1,
-0x3c030001, 0x8c636d98, 0x24020002, 0x1462000c,
-0x3c030002, 0x3c030001, 0x90636cf1, 0x24020001,
-0x5462001f, 0x2021, 0x3c020001, 0x90426cf0,
-0x1443001b, 0x24040005, 0x10000019, 0x24040006,
-0x3c020002, 0x8c428ff4, 0x431024, 0x1040000b,
-0x24020001, 0x3c030001, 0x90636cf1, 0x54620010,
-0x2021, 0x3c020001, 0x90426cf0, 0x1443000c,
-0x24040003, 0x1000000a, 0x24040004, 0x3c030001,
-0x90636cf1, 0x14620006, 0x2021, 0x3c020001,
-0x90426cf0, 0x24040001, 0x50440001, 0x24040002,
-0xc00565a, 0x0, 0x2402ff7f, 0x282a024,
-0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
-0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
-0x27bd0050, 0x3e00008, 0x0, 0x3c020001,
-0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
-0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
-0x104000de, 0xafb00030, 0x8f4200d0, 0x3c040001,
-0x8c846d98, 0x24430001, 0x2842000b, 0xaf4400e8,
-0x144000fe, 0xaf4300d0, 0x8f420004, 0x30420002,
-0x14400095, 0xaf4000d0, 0x8f420004, 0x34420002,
-0xaf420004, 0x24020001, 0x14820003, 0x3c020600,
-0x10000002, 0x34423000, 0x34421000, 0xafa20020,
-0x1821, 0x8f5e0018, 0x27aa0020, 0x240200ff,
-0x13c20002, 0xafaa002c, 0x27c30001, 0x8c020228,
-0x609021, 0x1642000e, 0x1e38c0, 0x8f42033c,
-0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228,
-0x3c040001, 0x2484610c, 0x3c050009, 0xafa00014,
-0xafa20010, 0x8fa60020, 0x1000006d, 0x34a50500,
-0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0,
-0xac4404c4, 0x8f830054, 0x8f820054, 0x247003e8,
-0x2021023, 0x2c4203e9, 0x1040001b, 0x9821,
-0xe08821, 0x263504c0, 0x8f440178, 0x8f45017c,
-0x2201821, 0x240a0004, 0xafaa0010, 0xafb20014,
-0x8f48000c, 0x1021, 0x2f53021, 0xafa80018,
-0x8f48010c, 0x24070008, 0xa32821, 0xa3482b,
-0x822021, 0x100f809, 0x892021, 0x54400006,
-0x24130001, 0x8f820054, 0x2021023, 0x2c4203e9,
-0x1440ffe9, 0x0, 0x326200ff, 0x54400017,
-0xaf520018, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846118, 0x3c050009,
-0xafa20014, 0x8d460000, 0x10000035, 0x34a50600,
-0x8f420308, 0x24130001, 0x24420001, 0xaf420308,
-0x8f420308, 0x1000001e, 0x326200ff, 0x8f830054,
-0x8f820054, 0x247003e8, 0x2021023, 0x2c4203e9,
-0x10400016, 0x9821, 0x3c150020, 0x24110010,
-0x8f42000c, 0x8f440160, 0x8f450164, 0x8f860120,
-0xafb10010, 0xafb20014, 0x551025, 0xafa20018,
-0x8f42010c, 0x24070008, 0x40f809, 0x24c6001c,
-0x1440ffe3, 0x0, 0x8f820054, 0x2021023,
-0x2c4203e9, 0x1440ffee, 0x0, 0x326200ff,
-0x14400011, 0x0, 0x8f420378, 0x24420001,
-0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846120,
-0x3c050009, 0xafa20014, 0x8d460000, 0x34a50700,
-0xc002b3b, 0x3c03821, 0x8f4202ec, 0x24420001,
-0xaf4202ec, 0x8f4202ec, 0x8f420004, 0x30420001,
-0x10400033, 0x3c020400, 0x2c21024, 0x10400017,
-0x0, 0x934205c0, 0x8f440250, 0x8f450254,
-0x8f4301b4, 0x34420020, 0x14a30006, 0xa34205c0,
-0x8f420270, 0x8f430274, 0x8f4401b8, 0x10640008,
-0x0, 0x8f420250, 0x8f430254, 0x934405c0,
-0x8f460270, 0x8f470274, 0x10000016, 0x38840040,
-0x934205c0, 0x10000048, 0x304200bf, 0x934205c0,
-0x8f440250, 0x8f450254, 0x8f4301b4, 0x304200bf,
-0x14a30006, 0xa34205c0, 0x8f420270, 0x8f430274,
-0x8f4401b8, 0x1064000b, 0x0, 0x8f420250,
-0x8f430254, 0x934405c0, 0x8f460270, 0x8f470274,
-0x38840020, 0xaf4301b4, 0xaf4701b8, 0x10000033,
-0xa34405c0, 0x934205c0, 0x1000002f, 0x34420020,
-0x934205c0, 0x8f4300d4, 0x34420020, 0xa34205c0,
-0x24620001, 0x10000023, 0x28630033, 0x8f4200e4,
-0x8f4300e0, 0x24420001, 0xaf4200e4, 0x43102a,
-0x14400006, 0x24030001, 0x8f4200e8, 0x14430002,
-0xaf4000e4, 0x24030004, 0xaf4300e8, 0x8f420004,
-0x30420001, 0x1040000d, 0x3c020400, 0x2c21024,
-0x10400007, 0x0, 0x934205c0, 0x34420040,
-0xa34205c0, 0x934205c0, 0x1000000f, 0x304200df,
-0x934205c0, 0x1000000c, 0x34420060, 0x934205c0,
-0x8f4300d4, 0x34420020, 0xa34205c0, 0x24620001,
-0x286300fb, 0x14600005, 0xaf4200d4, 0x934205c0,
-0xaf4000d4, 0x38420040, 0xa34205c0, 0x934205c0,
-0x8f4300e8, 0x3042007f, 0xa34205c0, 0x24020001,
-0x14620005, 0x0, 0x934405c0, 0x42102,
-0x10000003, 0x348400f0, 0x934405c0, 0x3484000f,
-0xc005640, 0x0, 0x2402ff7f, 0x282a024,
-0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
-0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
-0x27bd0050, 0x3e00008, 0x0, 0x27bdffb0,
-0x274401c0, 0x26e30028, 0x24650400, 0x65102b,
-0xafbf0048, 0xafbe0044, 0xafb50040, 0xafb3003c,
-0xafb20038, 0xafb10034, 0x10400007, 0xafb00030,
-0x8c820000, 0xac620000, 0x24630004, 0x65102b,
-0x1440fffb, 0x24840004, 0x8c020080, 0xaee20044,
-0x8c0200c0, 0xaee20040, 0x8c020084, 0xaee20030,
-0x8c020084, 0xaee2023c, 0x8c020088, 0xaee20240,
-0x8c02008c, 0xaee20244, 0x8c020090, 0xaee20248,
-0x8c020094, 0xaee2024c, 0x8c020098, 0xaee20250,
-0x8c02009c, 0xaee20254, 0x8c0200a0, 0xaee20258,
-0x8c0200a4, 0xaee2025c, 0x8c0200a8, 0xaee20260,
-0x8c0200ac, 0xaee20264, 0x8c0200b0, 0xaee20268,
-0x8c0200b4, 0xaee2026c, 0x8c0200b8, 0xaee20270,
-0x8c0200bc, 0x24040001, 0xaee20274, 0xaee00034,
-0x41080, 0x571021, 0x8ee30034, 0x8c42023c,
-0x24840001, 0x621821, 0x2c82000f, 0xaee30034,
-0x1440fff8, 0x41080, 0x8c0200cc, 0xaee20048,
-0x8c0200d0, 0xaee2004c, 0x8c0200e0, 0xaee201f8,
-0x8c0200e4, 0xaee201fc, 0x8c0200e8, 0xaee20200,
-0x8c0200ec, 0xaee20204, 0x8c0200f0, 0xaee20208,
-0x8ee400c0, 0x8ee500c4, 0x8c0200fc, 0x45102b,
-0x1040000b, 0x0, 0x8ee200c0, 0x8ee300c4,
-0x24040001, 0x24050000, 0x651821, 0x65302b,
-0x441021, 0x461021, 0xaee200c0, 0xaee300c4,
-0x8c0200fc, 0x8ee400c0, 0x8ee500c4, 0x2408ffff,
-0x24090000, 0x401821, 0x1021, 0x882024,
-0xa92824, 0x822025, 0xa32825, 0xaee400c0,
-0xaee500c4, 0x8ee400d0, 0x8ee500d4, 0x8c0200f4,
-0x45102b, 0x1040000b, 0x0, 0x8ee200d0,
-0x8ee300d4, 0x24040001, 0x24050000, 0x651821,
-0x65302b, 0x441021, 0x461021, 0xaee200d0,
-0xaee300d4, 0x8c0200f4, 0x8ee400d0, 0x8ee500d4,
-0x401821, 0x1021, 0x882024, 0xa92824,
-0x822025, 0xa32825, 0xaee400d0, 0xaee500d4,
-0x8ee400c8, 0x8ee500cc, 0x8c0200f8, 0x45102b,
-0x1040000b, 0x0, 0x8ee200c8, 0x8ee300cc,
-0x24040001, 0x24050000, 0x651821, 0x65302b,
-0x441021, 0x461021, 0xaee200c8, 0xaee300cc,
-0x8c0200f8, 0x8ee400c8, 0x8ee500cc, 0x401821,
-0x1021, 0x882024, 0xa92824, 0x822025,
-0xa32825, 0x24020008, 0xaee400c8, 0xaee500cc,
-0xafa20010, 0xafa00014, 0x8f42000c, 0x8c040208,
-0x8c05020c, 0xafa20018, 0x8f42010c, 0x26e60028,
-0x40f809, 0x24070400, 0x104000f0, 0x3c020400,
-0xafa20020, 0x934205c6, 0x10400089, 0x1821,
-0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
-0xafaa002c, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846118, 0x3c050009, 0xafa20014,
-0x8d460000, 0x10000033, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014,
-0x9821, 0x24110010, 0x8f42000c, 0x8f440160,
-0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffef, 0x0,
-0x326200ff, 0x54400012, 0x24020001, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846120, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x1021,
-0x1440005b, 0x24020001, 0x10000065, 0x0,
-0x8f510018, 0x240200ff, 0x12220002, 0x8021,
-0x26300001, 0x8c020228, 0x1602000e, 0x1130c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x248460f4, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f,
-0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
-0x8f45017c, 0x1021, 0x24070004, 0xafa70010,
-0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x248460fc, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200,
-0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018,
-0x8f860120, 0x24020010, 0xafa20010, 0xafb00014,
-0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x54400011, 0x24020001, 0x8f420340, 0x24420001,
-0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846104, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b,
-0x2203821, 0x1021, 0x1040000d, 0x24020001,
-0x8f4202e8, 0xa34005c6, 0xaf4001b0, 0x24420001,
-0xaf4202e8, 0x8f4202e8, 0x8ee20150, 0x24420001,
-0xaee20150, 0x10000003, 0x8ee20150, 0x24020001,
-0xa34205c6, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
-0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
-0x3e00008, 0x27bd0050, 0x27bdffd8, 0xafbf0020,
-0x8f8200b0, 0x30420004, 0x10400068, 0x0,
-0x8f430128, 0x8f820104, 0x14620005, 0x0,
-0x8f430130, 0x8f8200b4, 0x10620006, 0x0,
-0x8f820104, 0xaf420128, 0x8f8200b4, 0x1000005b,
-0xaf420130, 0x8f8200b0, 0x3c030080, 0x431024,
-0x1040000d, 0x0, 0x8f82011c, 0x34420002,
-0xaf82011c, 0x8f8200b0, 0x2403fffb, 0x431024,
-0xaf8200b0, 0x8f82011c, 0x2403fffd, 0x431024,
-0x1000004a, 0xaf82011c, 0x8f430128, 0x8f820104,
-0x14620005, 0x0, 0x8f430130, 0x8f8200b4,
-0x10620010, 0x0, 0x8f820104, 0xaf420128,
-0x8f8200b4, 0x8f430128, 0xaf420130, 0xafa30010,
-0x8f420130, 0x3c040001, 0x24846144, 0xafa20014,
-0x8f86011c, 0x8f8700b0, 0x3c050005, 0x10000031,
-0x34a50900, 0x8f420128, 0xafa20010, 0x8f420130,
-0x3c040001, 0x24846150, 0xafa20014, 0x8f86011c,
-0x8f8700b0, 0x3c050005, 0xc002b3b, 0x34a51000,
-0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104,
-0x8f8200b0, 0x34420001, 0xaf8200b0, 0x24020008,
-0xaf830104, 0xafa20010, 0xafa00014, 0x8f42000c,
-0x8c040208, 0x8c05020c, 0xafa20018, 0x8f42010c,
-0x26e60028, 0x40f809, 0x24070400, 0x8f82011c,
-0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc,
-0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f420128,
-0xafa20010, 0x8f420130, 0x3c040001, 0x2484615c,
-0xafa20014, 0x8f86011c, 0x8f8700b0, 0x3c050005,
-0x34a51100, 0xc002b3b, 0x0, 0x8f8200a0,
-0x30420004, 0x10400069, 0x0, 0x8f43012c,
-0x8f820124, 0x14620005, 0x0, 0x8f430134,
-0x8f8200a4, 0x10620006, 0x0, 0x8f820124,
-0xaf42012c, 0x8f8200a4, 0x1000005c, 0xaf420134,
-0x8f8200a0, 0x3c030080, 0x431024, 0x1040000d,
-0x0, 0x8f82011c, 0x34420002, 0xaf82011c,
-0x8f8200a0, 0x2403fffb, 0x431024, 0xaf8200a0,
-0x8f82011c, 0x2403fffd, 0x431024, 0x1000004b,
-0xaf82011c, 0x8f43012c, 0x8f820124, 0x14620005,
-0x0, 0x8f430134, 0x8f8200a4, 0x10620010,
-0x0, 0x8f820124, 0xaf42012c, 0x8f8200a4,
-0x8f43012c, 0xaf420134, 0xafa30010, 0x8f420134,
-0x3c040001, 0x24846168, 0xafa20014, 0x8f86011c,
-0x8f8700a0, 0x3c050005, 0x10000032, 0x34a51200,
-0x8f42012c, 0xafa20010, 0x8f420134, 0x3c040001,
-0x24846174, 0xafa20014, 0x8f86011c, 0x8f8700a0,
-0x3c050005, 0xc002b3b, 0x34a51300, 0x8f82011c,
-0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0,
-0x34420001, 0xaf8200a0, 0x24020080, 0xaf830124,
-0xafa20010, 0xafa00014, 0x8f420014, 0x8c040208,
-0x8c05020c, 0xafa20018, 0x8f420108, 0x3c060001,
-0x24c66ed8, 0x40f809, 0x24070004, 0x8f82011c,
-0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc,
-0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f42012c,
-0xafa20010, 0x8f420134, 0x3c040001, 0x24846180,
-0xafa20014, 0x8f86011c, 0x8f8700a0, 0x3c050005,
-0x34a51400, 0xc002b3b, 0x0, 0x8fbf0020,
-0x3e00008, 0x27bd0028, 0x3c081000, 0x24070001,
-0x3c060080, 0x3c050100, 0x8f820070, 0x481024,
-0x1040fffd, 0x0, 0x8f820054, 0x24420005,
-0xaf820078, 0x8c040234, 0x10800016, 0x1821,
-0x3c020001, 0x571021, 0x8c4240e8, 0x24420005,
-0x3c010001, 0x370821, 0xac2240e8, 0x3c020001,
-0x571021, 0x8c4240e8, 0x44102b, 0x14400009,
-0x0, 0x3c030080, 0x3c010001, 0x370821,
-0xac2040e8, 0x3c010001, 0x370821, 0x1000000b,
-0xa02740f0, 0x3c020001, 0x571021, 0x904240f0,
-0x54400006, 0x661825, 0x3c020001, 0x571021,
-0x904240f1, 0x54400001, 0x661825, 0x8c040230,
-0x10800013, 0x0, 0x3c020001, 0x571021,
-0x8c4240ec, 0x24420005, 0x3c010001, 0x370821,
-0xac2240ec, 0x3c020001, 0x571021, 0x8c4240ec,
-0x44102b, 0x14400006, 0x0, 0x3c010001,
-0x370821, 0xac2040ec, 0x10000006, 0x651825,
-0x3c020001, 0x571021, 0x904240f2, 0x54400001,
-0x651825, 0x1060ffbc, 0x0, 0x8f420000,
-0x10400007, 0x0, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x431025, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x1000ffa7, 0xaf80004c,
-0x1000ffa5, 0xaf800048, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0xafbf0018, 0x8f860064, 0x30c20004, 0x10400025,
-0x24040004, 0x8c020114, 0xaf420020, 0xaf840064,
-0x8f4202fc, 0x24420001, 0xaf4202fc, 0x8f4202fc,
-0x8f820064, 0x30420004, 0x14400005, 0x0,
-0x8c030114, 0x8f420020, 0x1462fff2, 0x0,
-0x8f420000, 0x10400007, 0x8f43003c, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x431025, 0xaf820060,
-0x8f420000, 0x10400073, 0x0, 0x1000006f,
-0x0, 0x30c20008, 0x10400020, 0x24040008,
-0x8c02011c, 0xaf420048, 0xaf840064, 0x8f4202a8,
-0x24420001, 0xaf4202a8, 0x8f4202a8, 0x8f820064,
-0x30420008, 0x14400005, 0x0, 0x8c03011c,
-0x8f420048, 0x1462fff2, 0x0, 0x8f420000,
-0x10400007, 0x0, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x1000ffd9, 0x34420200, 0x30c20020,
-0x10400023, 0x24040020, 0x8c02012c, 0xaf420068,
-0xaf840064, 0x8f4202d8, 0x24420001, 0xaf4202d8,
-0x8f4202d8, 0x8f820064, 0x30420020, 0x14400005,
-0x32c24000, 0x8c03012c, 0x8f420068, 0x1462fff2,
-0x32c24000, 0x14400002, 0x3c020001, 0x2c2b025,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x1000ffb4, 0x34420800,
-0x30c20010, 0x10400029, 0x24040010, 0x8c020124,
-0xaf420058, 0xaf840064, 0x8f4202d4, 0x24420001,
-0xaf4202d4, 0x8f4202d4, 0x8f820064, 0x30420010,
-0x14400005, 0x32c22000, 0x8c030124, 0x8f420058,
-0x1462fff2, 0x32c22000, 0x50400001, 0x36d68000,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x34420100, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x1000006c,
-0xaf80004c, 0x1000006a, 0xaf800048, 0x30c20001,
-0x10400004, 0x24020001, 0xaf820064, 0x10000064,
-0x0, 0x30c20002, 0x1440000b, 0x3c050003,
-0x3c040001, 0x24846244, 0x34a50500, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x2402ffc0,
-0x10000057, 0xaf820064, 0x8c05022c, 0x8c02010c,
-0x10a20048, 0x51080, 0x8c460300, 0x24a20001,
-0x3045003f, 0x24020003, 0xac05022c, 0x61e02,
-0x10620005, 0x24020010, 0x1062001d, 0x30c20fff,
-0x10000039, 0x0, 0x8f4302a8, 0x8f440000,
-0x30c20fff, 0xaf420048, 0x24630001, 0xaf4302a8,
-0x10800007, 0x8f4202a8, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x34420200, 0xaf820060, 0x8f420000,
-0x1040001f, 0x0, 0x1000001b, 0x0,
-0xaf420058, 0x32c22000, 0x50400001, 0x36d68000,
-0x8f4202d4, 0x8f430000, 0x24420001, 0xaf4202d4,
-0x10600007, 0x8f4202d4, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x34420100, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x10000006, 0xaf80004c,
-0x10000004, 0xaf800048, 0xc002196, 0xc02021,
-0x402821, 0x8c02010c, 0x14a20002, 0x24020002,
-0xaf820064, 0x8f820064, 0x30420002, 0x14400004,
-0x0, 0x8c02010c, 0x14a2ffac, 0x0,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x3e00008,
-0x0, 0x27bdffa0, 0xafb00040, 0x808021,
-0x101602, 0x2442ffff, 0x304300ff, 0x2c620013,
-0xafbf0058, 0xafbe0054, 0xafb50050, 0xafb3004c,
-0xafb20048, 0xafb10044, 0x104001f3, 0xafa50034,
-0x31080, 0x3c010001, 0x220821, 0x8c226288,
-0x400008, 0x0, 0x101302, 0x30440fff,
-0x24020001, 0x10820005, 0x24020002, 0x1082000c,
-0x2402fffe, 0x10000024, 0x3c050003, 0x8f430004,
-0x3c020001, 0x8c426f04, 0xaf440200, 0xaf440204,
-0x3c040001, 0x8c846e80, 0x10000009, 0x34630001,
-0x8f430004, 0xaf440200, 0xaf440204, 0x3c040001,
-0x8c846e80, 0x621824, 0x3c020001, 0x2442ca28,
-0x21100, 0x21182, 0xaf430004, 0x3c030800,
-0x431025, 0xac820038, 0x8f840054, 0x41442,
-0x41c82, 0x431021, 0x41cc2, 0x431023,
-0x41d02, 0x431021, 0x41d42, 0x431023,
-0x10000009, 0xaf420208, 0x3c040001, 0x24846250,
-0x34a51000, 0x2003021, 0x3821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8f4202a0, 0x24420001,
-0xaf4202a0, 0x1000021f, 0x8f4202a0, 0x27b00028,
-0x2002021, 0x24050210, 0xc002bbf, 0x24060008,
-0xc002518, 0x2002021, 0x10000216, 0x0,
-0x8faa0034, 0x27a40028, 0xa1880, 0x25420001,
-0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034,
-0x21080, 0x8c430300, 0x25420001, 0x3042003f,
-0xafa20034, 0xac02022c, 0xafa50028, 0xc002518,
-0xafa3002c, 0x10000203, 0x0, 0x27b00028,
-0x2002021, 0x24050210, 0xc002bbf, 0x24060008,
-0xc002657, 0x2002021, 0x100001fa, 0x0,
-0x8faa0034, 0x27a40028, 0xa1880, 0x25420001,
-0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034,
-0x21080, 0x8c430300, 0x25420001, 0x3042003f,
-0xafa20034, 0xac02022c, 0xafa50028, 0xc002657,
-0xafa3002c, 0x100001e7, 0x0, 0x101302,
-0x30430fff, 0x24020001, 0x10620005, 0x24020002,
-0x1062001e, 0x3c020002, 0x10000033, 0x3c050003,
-0x3c030002, 0x2c31024, 0x54400037, 0x2c3b025,
-0x8f820228, 0x3c010001, 0x370821, 0xac2238d8,
-0x8f82022c, 0x3c010001, 0x370821, 0xac2238dc,
-0x8f820230, 0x3c010001, 0x370821, 0xac2238e0,
-0x8f820234, 0x3c010001, 0x370821, 0xac2238e4,
-0x2402ffff, 0xaf820228, 0xaf82022c, 0xaf820230,
-0xaf820234, 0x10000020, 0x2c3b025, 0x2c21024,
-0x10400012, 0x3c02fffd, 0x3c020001, 0x571021,
-0x8c4238d8, 0xaf820228, 0x3c020001, 0x571021,
-0x8c4238dc, 0xaf82022c, 0x3c020001, 0x571021,
-0x8c4238e0, 0xaf820230, 0x3c020001, 0x571021,
-0x8c4238e4, 0xaf820234, 0x3c02fffd, 0x3442ffff,
-0x10000009, 0x2c2b024, 0x3c040001, 0x2484625c,
-0x34a51100, 0x2003021, 0x3821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8f4202cc, 0x24420001,
-0xaf4202cc, 0x1000019f, 0x8f4202cc, 0x101302,
-0x30450fff, 0x24020001, 0x10a20005, 0x24020002,
-0x10a2000d, 0x3c0408ff, 0x10000014, 0x3c050003,
-0x3c0208ff, 0x3442ffff, 0x8f830220, 0x3c040004,
-0x2c4b025, 0x621824, 0x34630008, 0xaf830220,
-0x10000012, 0xaf450298, 0x3484fff7, 0x3c03fffb,
-0x8f820220, 0x3463ffff, 0x2c3b024, 0x441024,
-0xaf820220, 0x10000009, 0xaf450298, 0x3c040001,
-0x24846268, 0x34a51200, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202bc,
-0x24420001, 0xaf4202bc, 0x10000176, 0x8f4202bc,
-0x27840208, 0x24050200, 0xc002bbf, 0x24060008,
-0x27440224, 0x24050200, 0xc002bbf, 0x24060008,
-0x8f4202c4, 0x24420001, 0xaf4202c4, 0x10000169,
-0x8f4202c4, 0x101302, 0x30430fff, 0x24020001,
-0x10620011, 0x28620002, 0x50400005, 0x24020002,
-0x10600007, 0x0, 0x10000017, 0x0,
-0x1062000f, 0x0, 0x10000013, 0x0,
-0x8c060248, 0x2021, 0xc005104, 0x24050004,
-0x10000007, 0x0, 0x8c060248, 0x2021,
-0xc005104, 0x24050004, 0x10000010, 0x0,
-0x8c06024c, 0x2021, 0xc005104, 0x24050001,
-0x1000000a, 0x0, 0x3c040001, 0x24846274,
-0x3c050003, 0x34a51300, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202c0,
-0x24420001, 0xaf4202c0, 0x1000013a, 0x8f4202c0,
-0xc002426, 0x0, 0x10000136, 0x0,
-0x24020001, 0xa34205c5, 0x24100100, 0x8f4401a8,
-0x8f4501ac, 0xafb00010, 0xafa00014, 0x8f420014,
-0xafa20018, 0x8f420108, 0x26e60028, 0x40f809,
-0x24070400, 0x1040fff5, 0x0, 0x10000125,
-0x0, 0x3c03ffff, 0x34637fff, 0x8f420368,
-0x8f440360, 0x2c3b024, 0x1821, 0xaf400058,
-0xaf40005c, 0xaf400060, 0xaf400064, 0x441023,
-0xaf420368, 0x3c020900, 0xaf400360, 0xafa20020,
-0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
-0xafaa003c, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484620c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8faa003c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846218, 0x3c050009, 0xafa20014,
-0x8d460000, 0x10000033, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014,
-0x9821, 0x24110010, 0x8f42000c, 0x8f440160,
-0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffef, 0x0,
-0x326200ff, 0x14400011, 0x0, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa003c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846220, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b0,
-0x24420001, 0xaf4202b0, 0x8f4202b0, 0x8f4202f8,
-0x24420001, 0xaf4202f8, 0x1000008a, 0x8f4202f8,
-0x8c02025c, 0x27440224, 0xaf4201f0, 0x8c020260,
-0x24050200, 0x24060008, 0xc002bbf, 0xaf4201f8,
-0x8f820220, 0x30420008, 0x14400002, 0x24020001,
-0x24020002, 0xaf420298, 0x8f4202ac, 0x24420001,
-0xaf4202ac, 0x10000077, 0x8f4202ac, 0x3c0200ff,
-0x3442ffff, 0x2021824, 0x32c20180, 0x14400006,
-0x3402fffb, 0x43102b, 0x14400003, 0x0,
-0x1000006c, 0xaf4300bc, 0x3c040001, 0x24846280,
-0x3c050003, 0x34a51500, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020700,
-0x34421000, 0x101e02, 0x621825, 0xafa30020,
-0x8f510018, 0x240200ff, 0x12220002, 0x8021,
-0x26300001, 0x8c020228, 0x1602000e, 0x1130c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x248461f4, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f,
-0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
-0x8f45017c, 0x1021, 0x24070004, 0xafa70010,
-0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x248461fc, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200,
-0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018,
-0x8f860120, 0x24020010, 0xafa20010, 0xafb00014,
-0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400010, 0x0, 0x8f420340, 0x24420001,
-0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846204, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b,
-0x2203821, 0x8f4202e0, 0x24420001, 0xaf4202e0,
-0x8f4202e0, 0x8f4202f0, 0x24420001, 0xaf4202f0,
-0x8f4202f0, 0x8fa20034, 0x8fbf0058, 0x8fbe0054,
-0x8fb50050, 0x8fb3004c, 0x8fb20048, 0x8fb10044,
-0x8fb00040, 0x3e00008, 0x27bd0060, 0x27bdfff8,
-0x2408ffff, 0x10a00014, 0x4821, 0x3c0aedb8,
-0x354a8320, 0x90870000, 0x24840001, 0x3021,
-0x1071026, 0x30420001, 0x10400002, 0x81842,
-0x6a1826, 0x604021, 0x24c60001, 0x2cc20008,
-0x1440fff7, 0x73842, 0x25290001, 0x125102b,
-0x1440fff0, 0x0, 0x1001021, 0x3e00008,
-0x27bd0008, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
-0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
-0xafb00030, 0x8f870220, 0xafa70024, 0x8f870200,
-0xafa7002c, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x34420004, 0xaf820220, 0x8f820200,
-0x3c03c0ff, 0x3463ffff, 0x431024, 0x34420004,
-0xaf820200, 0x8f530358, 0x8f55035c, 0x8f5e0360,
-0x8f470364, 0xafa70014, 0x8f470368, 0xafa7001c,
-0x8f4202d0, 0x274401c0, 0x24420001, 0xaf4202d0,
-0x8f5002d0, 0x8f510204, 0x8f520200, 0xc002ba8,
-0x24050400, 0xaf530358, 0xaf55035c, 0xaf5e0360,
-0x8fa70014, 0xaf470364, 0x8fa7001c, 0xaf470368,
-0xaf5002d0, 0xaf510204, 0xaf520200, 0x8c02025c,
-0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200,
-0x24060008, 0xaf4201f8, 0x24020006, 0xc002bbf,
-0xaf4201f4, 0x3c023b9a, 0x3442ca00, 0xaf4201fc,
-0x240203e8, 0x24040002, 0x24030001, 0xaf420294,
-0xaf440290, 0xaf43029c, 0x8f820220, 0x30420008,
-0x10400004, 0x0, 0xaf430298, 0x10000003,
-0x3021, 0xaf440298, 0x3021, 0x3c030001,
-0x661821, 0x90636d00, 0x3461021, 0x24c60001,
-0xa043022c, 0x2cc2000f, 0x1440fff8, 0x3461821,
-0x24c60001, 0x8f820040, 0x24040080, 0x24050080,
-0x21702, 0x24420030, 0xa062022c, 0x3461021,
-0xc002ba8, 0xa040022c, 0x8fa70024, 0x30e20004,
-0x14400006, 0x0, 0x8f820220, 0x3c0308ff,
-0x3463fffb, 0x431024, 0xaf820220, 0x8fa7002c,
-0x30e20004, 0x14400006, 0x0, 0x8f820200,
-0x3c03c0ff, 0x3463fffb, 0x431024, 0xaf820200,
-0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
-0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
-0x27bd0050, 0x0, 0x0, 0xaf400104,
-0x24040001, 0x410c0, 0x2e21821, 0x24820001,
-0x3c010001, 0x230821, 0xa42234d0, 0x402021,
-0x2c820080, 0x1440fff8, 0x410c0, 0x24020001,
-0x3c010001, 0x370821, 0xa42038d0, 0xaf420100,
-0xaf800228, 0xaf80022c, 0xaf800230, 0xaf800234,
-0x3e00008, 0x0, 0x27bdffe8, 0xafbf0014,
-0xafb00010, 0x8f420104, 0x28420005, 0x10400026,
-0x808021, 0x3c020001, 0x8f430104, 0x344230d0,
-0x2e22021, 0x318c0, 0x621821, 0x2e31821,
-0x83102b, 0x10400015, 0x1021, 0x96070000,
-0x24840006, 0x24660006, 0x9482fffc, 0x14470009,
-0x2821, 0x9483fffe, 0x96020002, 0x14620006,
-0xa01021, 0x94820000, 0x96030004, 0x431026,
-0x2c450001, 0xa01021, 0x14400009, 0x24840008,
-0x86102b, 0x1440fff0, 0x1021, 0x304200ff,
-0x14400030, 0x24020001, 0x1000002e, 0x1021,
-0x1000fffa, 0x24020001, 0x2002021, 0xc00240c,
-0x24050006, 0x3042007f, 0x218c0, 0x2e31021,
-0x3c010001, 0x220821, 0x942230d0, 0x1040fff2,
-0x2e31021, 0x3c060001, 0xc23021, 0x94c630d0,
-0x10c0ffed, 0x3c080001, 0x350834d2, 0x96070000,
-0x610c0, 0x572021, 0x882021, 0x94820000,
-0x14470009, 0x2821, 0x94830002, 0x96020002,
-0x14620006, 0xa01021, 0x94820004, 0x96030004,
-0x431026, 0x2c450001, 0xa01021, 0x14400007,
-0x610c0, 0x2e21021, 0x3c060001, 0xc23021,
-0x94c634d0, 0x14c0ffeb, 0x610c0, 0x10c0ffd2,
-0x24020001, 0x8fbf0014, 0x8fb00010, 0x3e00008,
-0x27bd0018, 0x3e00008, 0x0, 0x27bdffb0,
-0x801021, 0xafb00030, 0x24500002, 0x2002021,
-0x24050006, 0xafb10034, 0x408821, 0xafbf0048,
-0xafbe0044, 0xafb50040, 0xafb3003c, 0xc00240c,
-0xafb20038, 0x3047007f, 0x710c0, 0x2e21021,
-0x3c050001, 0xa22821, 0x94a530d0, 0x50a0001c,
-0xa03021, 0x3c090001, 0x352934d2, 0x96280002,
-0x510c0, 0x572021, 0x892021, 0x94820000,
-0x14480009, 0x3021, 0x94830002, 0x96020002,
-0x14620006, 0xc01021, 0x94820004, 0x96030004,
-0x431026, 0x2c460001, 0xc01021, 0x14400007,
-0x510c0, 0x2e21021, 0x3c050001, 0xa22821,
-0x94a534d0, 0x14a0ffeb, 0x510c0, 0xa03021,
-0x10c00014, 0x610c0, 0x571821, 0x3c010001,
-0x230821, 0x8c2334d0, 0x571021, 0xafa30010,
-0x3c010001, 0x220821, 0x8c2234d4, 0x3c040001,
-0x24846394, 0xafa20014, 0x8e260000, 0x8e270004,
-0x3c050004, 0xc002b3b, 0x34a50400, 0x10000063,
-0x3c020800, 0x8f450100, 0x10a00006, 0x510c0,
-0x2e21021, 0x3c010001, 0x220821, 0x942234d0,
-0xaf420100, 0xa03021, 0x14c00011, 0x628c0,
-0x710c0, 0x2e21021, 0xafa70010, 0x3c010001,
-0x220821, 0x942230d0, 0x3c040001, 0x248463a0,
-0xafa20014, 0x8e260000, 0x8e270004, 0x3c050004,
-0xc002b3b, 0x34a50500, 0x10000048, 0x3c020800,
-0xb71821, 0x3c020001, 0x96040000, 0x344234d2,
-0x621821, 0xa4640000, 0x8e020002, 0x720c0,
-0xac620002, 0x2e41021, 0x3c030001, 0x621821,
-0x946330d0, 0x2e51021, 0x3c010001, 0x220821,
-0xa42334d0, 0x2e41021, 0x3c010001, 0x220821,
-0xa42630d0, 0x8f420104, 0x24420001, 0x28420080,
-0x1040000f, 0x3c020002, 0x8f420104, 0x3c040001,
-0x348430d2, 0x96030000, 0x210c0, 0x571021,
-0x441021, 0xa4430000, 0x8e030002, 0xac430002,
-0x8f420104, 0x24420001, 0xaf420104, 0x3c020002,
-0x2c21024, 0x10400011, 0x72142, 0x3c030001,
-0x346338d8, 0x24020003, 0x441023, 0x21080,
-0x572021, 0x832021, 0x571021, 0x431021,
-0x30e5001f, 0x8c430000, 0x24020001, 0xa21004,
-0x621825, 0x1000000c, 0xac830000, 0x24020003,
-0x441023, 0x21080, 0x5c2821, 0x5c1021,
-0x30e4001f, 0x8c430228, 0x24020001, 0x821004,
-0x621825, 0xaca30228, 0x3c020800, 0x34421000,
-0x1821, 0xafa20020, 0x8f5e0018, 0x27aa0020,
-0x240200ff, 0x13c20002, 0xafaa002c, 0x27c30001,
-0x8c020228, 0x609021, 0x1642000e, 0x1e38c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x2484635c, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006b,
-0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b,
-0x9821, 0xe08821, 0x263504c0, 0x8f440178,
-0x8f45017c, 0x2201821, 0x240a0004, 0xafaa0010,
-0xafb20014, 0x8f48000c, 0x1021, 0x2f53021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x54400006, 0x24130001, 0x8f820054, 0x2021023,
-0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff,
-0x54400017, 0xaf520018, 0x8f420378, 0x24420001,
-0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846368,
-0x3c050009, 0xafa20014, 0x8d460000, 0x10000033,
-0x34a50600, 0x8f420308, 0x24130001, 0x24420001,
-0xaf420308, 0x8f420308, 0x1000001c, 0x326200ff,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x10400014, 0x9821, 0x24110010,
-0x8f42000c, 0x8f440160, 0x8f450164, 0x8f860120,
-0xafb10010, 0xafb20014, 0xafa20018, 0x8f42010c,
-0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe5,
-0x0, 0x8f820054, 0x2021023, 0x2c4203e9,
-0x1440ffef, 0x0, 0x326200ff, 0x14400011,
-0x0, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846370, 0x3c050009,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
-0x3c03821, 0x8f4202b4, 0x24420001, 0xaf4202b4,
-0x8f4202b4, 0x8f4202f4, 0x24420001, 0xaf4202f4,
-0x8f4202f4, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
-0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
-0x3e00008, 0x27bd0050, 0x27bdffa0, 0x801021,
-0xafb00040, 0x24500002, 0x2002021, 0x24050006,
-0xafb10044, 0x408821, 0xafbf0058, 0xafbe0054,
-0xafb50050, 0xafb3004c, 0xc00240c, 0xafb20048,
-0x3048007f, 0x810c0, 0x2e21021, 0x3c060001,
-0xc23021, 0x94c630d0, 0x10c0001c, 0x3821,
-0x3c0a0001, 0x354a34d2, 0x96290002, 0x610c0,
-0x572021, 0x8a2021, 0x94820000, 0x14490009,
-0x2821, 0x94830002, 0x96020002, 0x14620006,
-0xa01021, 0x94820004, 0x96030004, 0x431026,
-0x2c450001, 0xa01021, 0x14400008, 0x610c0,
-0xc03821, 0x2e21021, 0x3c060001, 0xc23021,
-0x94c634d0, 0x14c0ffea, 0x610c0, 0x14c00011,
-0xafa70028, 0x810c0, 0x2e21021, 0xafa80010,
-0x3c010001, 0x220821, 0x942230d0, 0x3c040001,
-0x248463ac, 0xafa20014, 0x8e260000, 0x8e270004,
-0x3c050004, 0xc002b3b, 0x34a50900, 0x10000075,
-0x3c020800, 0x10e0000c, 0x610c0, 0x2e21021,
-0x3c030001, 0x621821, 0x946334d0, 0x710c0,
-0x2e21021, 0x3c010001, 0x220821, 0xa42334d0,
-0x1000000b, 0x3c040001, 0x2e21021, 0x3c030001,
-0x621821, 0x946334d0, 0x810c0, 0x2e21021,
-0x3c010001, 0x220821, 0xa42330d0, 0x3c040001,
-0x348430d0, 0x8f430100, 0x610c0, 0x2e21021,
-0x3c010001, 0x220821, 0xa42334d0, 0x8f420104,
-0x2e43821, 0x2821, 0x18400029, 0xaf460100,
-0x24e60006, 0x94c3fffc, 0x96020000, 0x14620009,
-0x2021, 0x94c3fffe, 0x96020002, 0x14620006,
-0x801021, 0x94c20000, 0x96030004, 0x431026,
-0x2c440001, 0x801021, 0x50400014, 0x24a50001,
-0x8f420104, 0x2442ffff, 0xa2102a, 0x1040000b,
-0x24e40004, 0x94820006, 0x8c830008, 0xa482fffe,
-0xac830000, 0x8f420104, 0x24a50001, 0x2442ffff,
-0xa2102a, 0x1440fff7, 0x24840008, 0x8f420104,
-0x2442ffff, 0x10000006, 0xaf420104, 0x8f420104,
-0x24c60008, 0xa2102a, 0x1440ffda, 0x24e70008,
-0x810c0, 0x2e21021, 0x3c010001, 0x220821,
-0x942230d0, 0x14400023, 0x3c020800, 0x3c020002,
-0x2c21024, 0x10400012, 0x82142, 0x3c030001,
-0x346338d8, 0x24020003, 0x441023, 0x21080,
-0x572021, 0x832021, 0x571021, 0x431021,
-0x3105001f, 0x24030001, 0x8c420000, 0xa31804,
-0x31827, 0x431024, 0x1000000d, 0xac820000,
-0x24020003, 0x441023, 0x21080, 0x5c2821,
-0x5c1021, 0x3104001f, 0x24030001, 0x8c420228,
-0x831804, 0x31827, 0x431024, 0xaca20228,
-0x3c020800, 0x34422000, 0x1821, 0xafa20020,
-0x8f5e0018, 0x27ab0020, 0x240200ff, 0x13c20002,
-0xafab0034, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484635c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240b0004, 0xafab0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8fab0034, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846368, 0x3c050009, 0xafa20014,
-0x8d660000, 0x10000033, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014,
-0x9821, 0x24110010, 0x8f42000c, 0x8f440160,
-0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffef, 0x0,
-0x326200ff, 0x14400011, 0x0, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8fab0034, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846370, 0x3c050009, 0xafa20014, 0x8d660000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b8,
-0x24420001, 0xaf4202b8, 0x8f4202b8, 0x8f4202f4,
-0x24420001, 0xaf4202f4, 0x8f4202f4, 0x8fbf0058,
-0x8fbe0054, 0x8fb50050, 0x8fb3004c, 0x8fb20048,
-0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0060,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0x27644000, 0xafbf0018, 0xc002ba8, 0x24051000,
-0x3c030001, 0x34632cc0, 0x3c040001, 0x34842ec8,
-0x24020020, 0xaf82011c, 0x2e31021, 0xaf800100,
-0xaf800104, 0xaf800108, 0xaf800110, 0xaf800114,
-0xaf800118, 0xaf800120, 0xaf800124, 0xaf800128,
-0xaf800130, 0xaf800134, 0xaf800138, 0xaf4200ec,
-0x2e31021, 0xaf4200f0, 0x2e41021, 0xaf4200f4,
-0x2e41021, 0xaf4200f8, 0x3c020001, 0x571021,
-0x904240f4, 0x1440001c, 0x3c050001, 0x8f82011c,
-0x3c040001, 0x24846470, 0x3c050001, 0x34420001,
-0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c,
-0x34a50100, 0xc002b3b, 0x3821, 0x8c020218,
-0x30420040, 0x10400014, 0x0, 0x8f82011c,
-0x3c040001, 0x2484647c, 0x3c050001, 0x34420004,
-0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c,
-0x10000007, 0x34a50200, 0x3c040001, 0x24846484,
-0xafa00010, 0xafa00014, 0x8f86011c, 0x34a50300,
-0xc002b3b, 0x3821, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x8fa90010, 0x8f83012c, 0x8faa0014,
-0x8fab0018, 0x1060000a, 0x27624fe0, 0x14620002,
-0x24680020, 0x27684800, 0x8f820128, 0x11020004,
-0x0, 0x8f820124, 0x15020007, 0x0,
-0x8f430334, 0x1021, 0x24630001, 0xaf430334,
-0x10000039, 0x8f430334, 0xac640000, 0xac650004,
-0xac660008, 0xa467000e, 0xac690018, 0xac6a001c,
-0xac6b0010, 0xac620014, 0xaf880120, 0x8f4200fc,
-0x8f4400f4, 0x2442ffff, 0xaf4200fc, 0x8c820000,
-0x10490005, 0x3042ff8f, 0x10400019, 0x3122ff8f,
-0x10400018, 0x3c020001, 0x8c830004, 0x2c620010,
-0x10400013, 0x3c020001, 0x24630001, 0xac830004,
-0x8f4300f8, 0x344230c8, 0x2e21021, 0x54620004,
-0x24620008, 0x3c020001, 0x34422ec8, 0x2e21021,
-0x14440015, 0x24020001, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x1000000f, 0x24020001,
-0x3c020001, 0x344230c8, 0x2e21021, 0x54820004,
-0x24820008, 0x3c020001, 0x34422ec8, 0x2e21021,
-0x402021, 0x24020001, 0xaf4400f4, 0xac890000,
-0xac820004, 0x24020001, 0x3e00008, 0x0,
-0x3e00008, 0x0, 0x8fa90010, 0x8f83010c,
-0x8faa0014, 0x8fab0018, 0x1060000a, 0x276247e0,
-0x14620002, 0x24680020, 0x27684000, 0x8f820108,
-0x11020004, 0x0, 0x8f820104, 0x15020007,
-0x0, 0x8f430338, 0x1021, 0x24630001,
-0xaf430338, 0x10000035, 0x8f430338, 0xac640000,
-0xac650004, 0xac660008, 0xa467000e, 0xac690018,
-0xac6a001c, 0xac6b0010, 0xac620014, 0xaf880100,
-0x8f4400ec, 0x8c820000, 0x30420006, 0x10400019,
-0x31220006, 0x10400018, 0x3c020001, 0x8c830004,
-0x2c620010, 0x10400013, 0x3c020001, 0x24630001,
-0xac830004, 0x8f4300f0, 0x34422ec0, 0x2e21021,
-0x54620004, 0x24620008, 0x3c020001, 0x34422cc0,
-0x2e21021, 0x14440015, 0x24020001, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x1000000f,
-0x24020001, 0x3c020001, 0x34422ec0, 0x2e21021,
-0x54820004, 0x24820008, 0x3c020001, 0x34422cc0,
-0x2e21021, 0x402021, 0x24020001, 0xaf4400ec,
-0xac890000, 0xac820004, 0x24020001, 0x3e00008,
-0x0, 0x3e00008, 0x0, 0x27bdffd8,
-0x3c040001, 0x2484648c, 0x3c050001, 0xafbf0024,
-0xafb20020, 0xafb1001c, 0xafb00018, 0x8f900104,
-0x8f9100b0, 0x8f92011c, 0x34a52500, 0x8f820100,
-0x2403021, 0x2203821, 0xafa20010, 0xc002b3b,
-0xafb00014, 0x8e020008, 0xafa20010, 0x8e02000c,
-0x3c040001, 0x24846498, 0xafa20014, 0x8e060000,
-0x8e070004, 0x3c050001, 0xc002b3b, 0x34a52510,
-0x8e020018, 0xafa20010, 0x8e02001c, 0x3c040001,
-0x248464a4, 0xafa20014, 0x8e060010, 0x8e070014,
-0x3c050001, 0xc002b3b, 0x34a52520, 0x3c027f00,
-0x2221024, 0x3c030800, 0x54430016, 0x3c030200,
-0x8f82009c, 0x3042ffff, 0x14400012, 0x3c030200,
-0x3c040001, 0x248464b0, 0x3c050002, 0x34a5f030,
-0x3021, 0x3821, 0x36420002, 0xaf82011c,
-0x36220001, 0xaf8200b0, 0xaf900104, 0xaf92011c,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x10000024,
-0x0, 0x2c31024, 0x1040000d, 0x2231024,
-0x1040000b, 0x36420002, 0xaf82011c, 0x36220001,
-0xaf8200b0, 0xaf900104, 0xaf92011c, 0x8f420330,
-0x24420001, 0xaf420330, 0x10000015, 0x8f420330,
-0x3c040001, 0x248464b8, 0x240202a9, 0xafa20010,
-0xafa00014, 0x8f860144, 0x3c070001, 0x24e764c0,
-0xc002b3b, 0x3405dead, 0x8f82011c, 0x34420002,
-0xaf82011c, 0x8f820220, 0x34420004, 0xaf820220,
-0x8f820140, 0x3c030001, 0x431025, 0xaf820140,
-0x8fbf0024, 0x8fb20020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x27bdffd8, 0x3c040001,
-0x248464e8, 0x3c050001, 0xafbf0024, 0xafb20020,
-0xafb1001c, 0xafb00018, 0x8f900124, 0x8f9100a0,
-0x8f92011c, 0x34a52600, 0x8f820120, 0x2403021,
-0x2203821, 0xafa20010, 0xc002b3b, 0xafb00014,
-0x8e020008, 0xafa20010, 0x8e02000c, 0x3c040001,
-0x248464f4, 0xafa20014, 0x8e060000, 0x8e070004,
-0x3c050001, 0xc002b3b, 0x34a52610, 0x8e020018,
-0xafa20010, 0x8e02001c, 0x3c040001, 0x24846500,
-0xafa20014, 0x8e060010, 0x8e070014, 0x3c050001,
-0xc002b3b, 0x34a52620, 0x3c027f00, 0x2221024,
-0x3c030800, 0x54430016, 0x3c030200, 0x8f8200ac,
-0x3042ffff, 0x14400012, 0x3c030200, 0x3c040001,
-0x2484650c, 0x3c050001, 0x34a5f030, 0x3021,
-0x3821, 0x36420002, 0xaf82011c, 0x36220001,
-0xaf8200a0, 0xaf900124, 0xaf92011c, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x10000024, 0x0,
-0x2c31024, 0x1040000d, 0x2231024, 0x1040000b,
-0x36420002, 0xaf82011c, 0x36220001, 0xaf8200a0,
-0xaf900124, 0xaf92011c, 0x8f42032c, 0x24420001,
-0xaf42032c, 0x10000015, 0x8f42032c, 0x3c040001,
-0x248464b8, 0x240202e2, 0xafa20010, 0xafa00014,
-0x8f860144, 0x3c070001, 0x24e764c0, 0xc002b3b,
-0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c,
-0x8f820220, 0x34420004, 0xaf820220, 0x8f820140,
-0x3c030001, 0x431025, 0xaf820140, 0x8fbf0024,
-0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008,
-0x27bd0028, 0x6021, 0x5021, 0x3021,
-0x2821, 0x6821, 0x4821, 0x7821,
-0x7021, 0x8f880124, 0x8f870104, 0x1580002e,
-0x8f8b011c, 0x11a00014, 0x31620800, 0x8f820120,
-0x10460029, 0x0, 0x3c040001, 0x8c846ee4,
-0x8cc20000, 0x8cc30004, 0xac820000, 0xac830004,
-0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e,
-0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014,
-0x10000012, 0x24c60020, 0x10400017, 0x0,
-0x3c040001, 0x8c846ee4, 0x8d020000, 0x8d030004,
-0xac820000, 0xac830004, 0x8d020008, 0xac820008,
-0x9502000e, 0xa482000e, 0x8d020010, 0x25060020,
-0xac820010, 0x8d020014, 0x240c0001, 0xc01821,
-0xac820014, 0x27624fe0, 0x43102b, 0x54400001,
-0x27634800, 0x603021, 0x1540002f, 0x31620100,
-0x11200014, 0x31628000, 0x8f820100, 0x1045002a,
-0x31620100, 0x3c040001, 0x8c846ee0, 0x8ca20000,
-0x8ca30004, 0xac820000, 0xac830004, 0x8ca20008,
-0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010,
-0x240a0001, 0xac820010, 0x8ca20014, 0x10000012,
-0x24a50020, 0x10400018, 0x31620100, 0x3c040001,
-0x8c846ee0, 0x8ce20000, 0x8ce30004, 0xac820000,
-0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e,
-0xa482000e, 0x8ce20010, 0x24e50020, 0xac820010,
-0x8ce20014, 0x240a0001, 0xa01821, 0xac820014,
-0x276247e0, 0x43102b, 0x54400001, 0x27634000,
-0x602821, 0x31620100, 0x5440001d, 0x31621000,
-0x11a00009, 0x31a20800, 0x10400004, 0x25020020,
-0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124,
-0x8f880124, 0x6821, 0x11800011, 0x31621000,
-0x3c040001, 0x8c846ee4, 0x8c820000, 0x8c830004,
-0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4,
-0x9482000e, 0xaf8200ac, 0x8c820010, 0x6021,
-0xaf8200a0, 0x8c8d0010, 0x8c8f0014, 0x31621000,
-0x1440ff82, 0x0, 0x1120000f, 0x31220800,
-0x10400004, 0x3c020002, 0x8f8200b8, 0xa5c20000,
-0x3c020002, 0x1221024, 0x10400004, 0x24e20020,
-0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104,
-0x8f870104, 0x4821, 0x1140ff70, 0x0,
-0x3c040001, 0x8c846ee0, 0x8c820000, 0x8c830004,
-0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4,
-0x9482000e, 0xaf82009c, 0x8c820010, 0x5021,
-0xaf8200b0, 0x8c890010, 0x1000ff60, 0x8c8e0014,
-0x3e00008, 0x0, 0x6021, 0x5821,
-0x3021, 0x2821, 0x6821, 0x5021,
-0x7821, 0x7021, 0x8f880124, 0x8f870104,
-0x3c180100, 0x1580002e, 0x8f89011c, 0x11a00014,
-0x31220800, 0x8f820120, 0x10460029, 0x0,
-0x3c040001, 0x8c846ee4, 0x8cc20000, 0x8cc30004,
-0xac820000, 0xac830004, 0x8cc20008, 0xac820008,
-0x94c2000e, 0xa482000e, 0x8cc20010, 0x240c0001,
-0xac820010, 0x8cc20014, 0x10000012, 0x24c60020,
-0x10400017, 0x0, 0x3c040001, 0x8c846ee4,
-0x8d020000, 0x8d030004, 0xac820000, 0xac830004,
-0x8d020008, 0xac820008, 0x9502000e, 0xa482000e,
-0x8d020010, 0x25060020, 0xac820010, 0x8d020014,
-0x240c0001, 0xc01821, 0xac820014, 0x27624fe0,
-0x43102b, 0x54400001, 0x27634800, 0x603021,
-0x1560002f, 0x31220100, 0x11400014, 0x31228000,
-0x8f820100, 0x1045002a, 0x31220100, 0x3c040001,
-0x8c846ee0, 0x8ca20000, 0x8ca30004, 0xac820000,
-0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e,
-0xa482000e, 0x8ca20010, 0x240b0001, 0xac820010,
-0x8ca20014, 0x10000012, 0x24a50020, 0x10400018,
-0x31220100, 0x3c040001, 0x8c846ee0, 0x8ce20000,
-0x8ce30004, 0xac820000, 0xac830004, 0x8ce20008,
-0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010,
-0x24e50020, 0xac820010, 0x8ce20014, 0x240b0001,
-0xa01821, 0xac820014, 0x276247e0, 0x43102b,
-0x54400001, 0x27634000, 0x602821, 0x31220100,
-0x5440001d, 0x31221000, 0x11a00009, 0x31a20800,
-0x10400004, 0x25020020, 0x8f8200a8, 0xa5e20000,
-0x25020020, 0xaf820124, 0x8f880124, 0x6821,
-0x11800011, 0x31221000, 0x3c040001, 0x8c846ee4,
-0x8c820000, 0x8c830004, 0xaf820080, 0xaf830084,
-0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac,
-0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010,
-0x8c8f0014, 0x31221000, 0x14400022, 0x0,
-0x1140000f, 0x31420800, 0x10400004, 0x3c020002,
-0x8f8200b8, 0xa5c20000, 0x3c020002, 0x1421024,
-0x10400004, 0x24e20020, 0x8f8200b4, 0xaf8200d4,
-0x24e20020, 0xaf820104, 0x8f870104, 0x5021,
-0x11600010, 0x0, 0x3c040001, 0x8c846ee0,
-0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094,
-0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c,
-0x8c820010, 0x5821, 0xaf8200b0, 0x8c8a0010,
-0x8c8e0014, 0x8f820070, 0x3c031000, 0x431024,
-0x1040ff5c, 0x0, 0x8f820054, 0x24420005,
-0xaf820078, 0x8c040234, 0x10800016, 0x1821,
-0x3c020001, 0x571021, 0x8c4240e8, 0x24420005,
-0x3c010001, 0x370821, 0xac2240e8, 0x3c020001,
-0x571021, 0x8c4240e8, 0x44102b, 0x14400009,
-0x24020001, 0x3c030080, 0x3c010001, 0x370821,
-0xac2040e8, 0x3c010001, 0x370821, 0x1000000c,
-0xa02240f0, 0x3c020001, 0x571021, 0x904240f0,
-0x14400006, 0x3c020080, 0x3c020001, 0x571021,
-0x904240f1, 0x10400002, 0x3c020080, 0x621825,
-0x8c040230, 0x10800013, 0x0, 0x3c020001,
-0x571021, 0x8c4240ec, 0x24420005, 0x3c010001,
-0x370821, 0xac2240ec, 0x3c020001, 0x571021,
-0x8c4240ec, 0x44102b, 0x14400006, 0x0,
-0x3c010001, 0x370821, 0xac2040ec, 0x10000006,
-0x781825, 0x3c020001, 0x571021, 0x904240f2,
-0x54400001, 0x781825, 0x1060ff1a, 0x0,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x431025, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x1000ff05,
-0xaf80004c, 0x1000ff03, 0xaf800048, 0x3e00008,
-0x0, 0x0, 0x0, 0x3c020001,
-0x8c426d28, 0x27bdffe8, 0xafbf0014, 0x14400012,
-0xafb00010, 0x3c100001, 0x26106f90, 0x2002021,
-0xc002ba8, 0x24052000, 0x26021fe0, 0x3c010001,
-0xac226eec, 0x3c010001, 0xac226ee8, 0xac020250,
-0x24022000, 0xac100254, 0xac020258, 0x24020001,
-0x3c010001, 0xac226d28, 0x8fbf0014, 0x8fb00010,
-0x3e00008, 0x27bd0018, 0x3c090001, 0x8d296eec,
-0x8c820000, 0x8fa30010, 0x8fa80014, 0xad220000,
-0x8c820004, 0xad250008, 0xad220004, 0x8f820054,
-0xad260010, 0xad270014, 0xad230018, 0xad28001c,
-0xad22000c, 0x2529ffe0, 0x3c020001, 0x24426f90,
-0x122102b, 0x10400003, 0x0, 0x3c090001,
-0x8d296ee8, 0x3c020001, 0x8c426d10, 0xad220000,
-0x3c020001, 0x8c426d10, 0x3c010001, 0xac296eec,
-0xad220004, 0xac090250, 0x3e00008, 0x0,
-0x27bdffd0, 0xafb00010, 0x3c100001, 0x8e106eec,
-0x3c020001, 0x8c426d10, 0xafb10014, 0x808821,
-0xafbe0024, 0x8fbe0040, 0x8fa40048, 0xafb20018,
-0xa09021, 0xafbf0028, 0xafb50020, 0xafb3001c,
-0xae020000, 0x3c020001, 0x8c426d10, 0xc09821,
-0xe0a821, 0x10800006, 0xae020004, 0x26050008,
-0xc002bb3, 0x24060018, 0x10000005, 0x2610ffe0,
-0x26040008, 0xc002ba8, 0x24050018, 0x2610ffe0,
-0x3c030001, 0x24636f90, 0x203102b, 0x10400003,
-0x0, 0x3c100001, 0x8e106ee8, 0x8e220000,
-0xae020000, 0x8e220004, 0xae120008, 0xae020004,
-0x8f820054, 0xae130010, 0xae150014, 0xae1e0018,
-0x8fa80044, 0xae08001c, 0xae02000c, 0x2610ffe0,
-0x203102b, 0x10400003, 0x0, 0x3c100001,
-0x8e106ee8, 0x3c020001, 0x8c426d10, 0xae020000,
-0x3c020001, 0x8c426d10, 0x3c010001, 0xac306eec,
-0xae020004, 0xac100250, 0x8fbf0028, 0x8fbe0024,
-0x8fb50020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
-0x8fb00010, 0x3e00008, 0x27bd0030, 0x851821,
-0x83102b, 0x10400006, 0x0, 0xac800000,
-0x24840004, 0x83102b, 0x5440fffd, 0xac800000,
-0x3e00008, 0x0, 0xa61821, 0xa3102b,
-0x10400007, 0x0, 0x8c820000, 0xaca20000,
-0x24a50004, 0xa3102b, 0x1440fffb, 0x24840004,
-0x3e00008, 0x0, 0x861821, 0x83102b,
-0x10400007, 0x0, 0x8ca20000, 0xac820000,
-0x24840004, 0x83102b, 0x1440fffb, 0x24a50004,
-0x3e00008, 0x0, 0x63080, 0x861821,
-0x83102b, 0x10400006, 0x0, 0xac850000,
-0x24840004, 0x83102b, 0x5440fffd, 0xac850000,
-0x3e00008, 0x0, 0x0, 0x26e50028,
-0xa03021, 0x274301c0, 0x8f4d0358, 0x8f47035c,
-0x8f480360, 0x8f490364, 0x8f4a0368, 0x8f4b0204,
-0x8f4c0200, 0x24640400, 0x64102b, 0x10400008,
-0x3c0208ff, 0x8cc20000, 0xac620000, 0x24630004,
-0x64102b, 0x1440fffb, 0x24c60004, 0x3c0208ff,
-0x3442ffff, 0x3c03c0ff, 0xaf4d0358, 0xaf47035c,
-0xaf480360, 0xaf490364, 0xaf4a0368, 0xaf4b0204,
-0xaf4c0200, 0x8f840220, 0x3463ffff, 0x8f860200,
-0x821024, 0x34420004, 0xc31824, 0x34630004,
-0xaf820220, 0xaf830200, 0x8ca20214, 0xac020084,
-0x8ca20218, 0xac020088, 0x8ca2021c, 0xac02008c,
-0x8ca20220, 0xac020090, 0x8ca20224, 0xac020094,
-0x8ca20228, 0xac020098, 0x8ca2022c, 0xac02009c,
-0x8ca20230, 0xac0200a0, 0x8ca20234, 0xac0200a4,
-0x8ca20238, 0xac0200a8, 0x8ca2023c, 0xac0200ac,
-0x8ca20240, 0xac0200b0, 0x8ca20244, 0xac0200b4,
-0x8ca20248, 0xac0200b8, 0x8ca2024c, 0xac0200bc,
-0x8ca2001c, 0xac020080, 0x8ca20018, 0xac0200c0,
-0x8ca20020, 0xac0200cc, 0x8ca20024, 0xac0200d0,
-0x8ca201d0, 0xac0200e0, 0x8ca201d4, 0xac0200e4,
-0x8ca201d8, 0xac0200e8, 0x8ca201dc, 0xac0200ec,
-0x8ca201e0, 0xac0200f0, 0x8ca20098, 0x8ca3009c,
-0xac0300fc, 0x8ca200a8, 0x8ca300ac, 0xac0300f4,
-0x8ca200a0, 0x8ca300a4, 0x30840004, 0xac0300f8,
-0x14800007, 0x30c20004, 0x8f820220, 0x3c0308ff,
-0x3463fffb, 0x431024, 0xaf820220, 0x30c20004,
-0x14400006, 0x0, 0x8f820200, 0x3c03c0ff,
-0x3463fffb, 0x431024, 0xaf820200, 0x8f4202dc,
-0xa34005c5, 0x24420001, 0xaf4202dc, 0x8f4202dc,
-0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
-0xafb00020, 0x8f430024, 0x8f420020, 0x10620038,
-0x0, 0x8f430020, 0x8f420024, 0x622023,
-0x4810003, 0x0, 0x8f420040, 0x822021,
-0x8f430030, 0x8f420024, 0x43102b, 0x14400005,
-0x0, 0x8f430040, 0x8f420024, 0x10000005,
-0x621023, 0x8f420030, 0x8f430024, 0x431023,
-0x2442ffff, 0x406021, 0x8c102a, 0x54400001,
-0x806021, 0x8f4a0024, 0x8f490040, 0x8f480024,
-0x8f440180, 0x8f450184, 0x8f460024, 0x8f4b001c,
-0x24070001, 0xafa70010, 0x84100, 0x1001821,
-0x14c5021, 0x2529ffff, 0x1498024, 0xafb00014,
-0x8f470014, 0x1021, 0x63100, 0xafa70018,
-0xa32821, 0xa3382b, 0x822021, 0x872021,
-0x8f420108, 0x1663021, 0x40f809, 0xc3900,
-0x54400001, 0xaf500024, 0x8f430024, 0x8f420020,
-0x14620018, 0x0, 0x8f420000, 0x10400007,
-0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd,
-0x0, 0x10000005, 0x0, 0xaf800048,
-0x8f820048, 0x1040fffd, 0x0, 0x8f820060,
-0x2403ffef, 0x431024, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x10000002, 0xaf80004c,
-0xaf800048, 0x8fbf0024, 0x8fb00020, 0x3e00008,
-0x27bd0028, 0x3e00008, 0x0, 0x27bdffc0,
-0x32c20020, 0xafbf0038, 0xafb30034, 0xafb20030,
-0xafb1002c, 0x10400004, 0xafb00028, 0x8f530028,
-0x10000002, 0x0, 0x8f530020, 0x8f420030,
-0x105300eb, 0x21100, 0x8f43001c, 0x628021,
-0x8e040000, 0x8e050004, 0x96120008, 0x8f420090,
-0x9611000a, 0x3246ffff, 0x46102a, 0x10400017,
-0x0, 0x8f8200d8, 0x8f430098, 0x431023,
-0x2442dcbe, 0xaf420090, 0x8f420090, 0x2842dcbf,
-0x10400005, 0x0, 0x8f420090, 0x8f430144,
-0x431021, 0xaf420090, 0x8f420090, 0x46102a,
-0x10400006, 0x0, 0x8f420348, 0x24420001,
-0xaf420348, 0x100000e1, 0x8f420348, 0x8f8200fc,
-0x14400006, 0x0, 0x8f420344, 0x24420001,
-0xaf420344, 0x100000d9, 0x8f420344, 0x934205c2,
-0x1040000b, 0x32c20008, 0x10400008, 0x32220200,
-0x10400006, 0x3c034000, 0x9602000e, 0xaf4300ac,
-0x21400, 0x10000002, 0xaf4200b0, 0xaf4000ac,
-0x32220004, 0x1040007f, 0x32220800, 0x10400003,
-0x3247ffff, 0x10000002, 0x24020020, 0x24020004,
-0xafa20010, 0x8f420030, 0xafa20014, 0x8f420010,
-0x3c030002, 0x431025, 0xafa20018, 0x8f460098,
-0x8f420108, 0x40f809, 0x0, 0x104000b7,
-0x0, 0x8f42009c, 0x8f430094, 0x2421021,
-0xaf42009c, 0xae03000c, 0x8f4200ac, 0x10400008,
-0x3c034000, 0x8f420094, 0x431025, 0xafa20020,
-0x8f42009c, 0x8f4300b0, 0x10000004, 0x431025,
-0x8f420094, 0xafa20020, 0x8f42009c, 0xafa20024,
-0x8f8200fc, 0x8fa30020, 0x8fa40024, 0xac430000,
-0xac440004, 0x24420008, 0xaf8200f0, 0x8f42009c,
-0x8f440270, 0x8f450274, 0x401821, 0x1021,
-0xa32821, 0xa3302b, 0x822021, 0x862021,
-0x32230060, 0x24020040, 0xaf440270, 0xaf450274,
-0x10620017, 0x2c620041, 0x10400005, 0x24020020,
-0x10620008, 0x24020001, 0x10000026, 0x0,
-0x24020060, 0x10620019, 0x24020001, 0x10000021,
-0x0, 0x8f420278, 0x8f43027c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
-0x8f420278, 0x8f43027c, 0x10000016, 0x24020001,
-0x8f420280, 0x8f430284, 0x24630001, 0x2c640001,
-0x441021, 0xaf420280, 0xaf430284, 0x8f420280,
-0x8f430284, 0x1000000b, 0x24020001, 0x8f420288,
-0x8f43028c, 0x24630001, 0x2c640001, 0x441021,
-0xaf420288, 0xaf43028c, 0x8f420288, 0x8f43028c,
-0x24020001, 0xa34205c2, 0x8f420098, 0x3244ffff,
-0x2406fff8, 0x8f45013c, 0x441021, 0x24420007,
-0x461024, 0x24840007, 0xaf420094, 0x8f420090,
-0x8f430094, 0x862024, 0x441023, 0x65182b,
-0x14600005, 0xaf420090, 0x8f420094, 0x8f430144,
-0x431023, 0xaf420094, 0x8f420094, 0x10000023,
-0xaf40009c, 0x3247ffff, 0x50e00022, 0x32c20020,
-0x14400002, 0x24020010, 0x24020002, 0xafa20010,
-0x8f420030, 0xafa20014, 0x8f420010, 0xafa20018,
-0x8f460098, 0x8f420108, 0x40f809, 0x0,
-0x1040003a, 0x3245ffff, 0x8f420098, 0x8f430090,
-0x8f46013c, 0x451021, 0xaf420098, 0x8f42009c,
-0x8f440098, 0xa34005c2, 0x651823, 0xaf430090,
-0x451021, 0x86202b, 0x14800005, 0xaf42009c,
-0x8f420098, 0x8f430144, 0x431023, 0xaf420098,
-0x32c20020, 0x10400005, 0x0, 0x8f420358,
-0x2442ffff, 0xaf420358, 0x8f420358, 0x8f420030,
-0x8f430040, 0x24420001, 0x2463ffff, 0x431024,
-0xaf420030, 0x8f420030, 0x14530018, 0x0,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x2403fff7, 0x431024,
-0xaf820060, 0x8f420000, 0x10400003, 0x0,
-0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf0038,
-0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028,
-0x3e00008, 0x27bd0040, 0x3e00008, 0x0,
-0x27bdffd0, 0x32c20020, 0xafbf002c, 0xafb20028,
-0xafb10024, 0x10400004, 0xafb00020, 0x8f520028,
-0x10000002, 0x0, 0x8f520020, 0x8f420030,
-0x105200b5, 0x21100, 0x8f43001c, 0x628021,
-0x8e040000, 0x8e050004, 0x96110008, 0x8f420090,
-0x9607000a, 0x3226ffff, 0x46102a, 0x10400017,
-0x0, 0x8f8200d8, 0x8f430098, 0x431023,
-0x2442dc46, 0xaf420090, 0x8f420090, 0x2842dc47,
-0x10400005, 0x0, 0x8f420090, 0x8f430144,
-0x431021, 0xaf420090, 0x8f420090, 0x46102a,
-0x10400006, 0x0, 0x8f420348, 0x24420001,
-0xaf420348, 0x100000ab, 0x8f420348, 0x8f8600fc,
-0x10c0000c, 0x0, 0x8f8200f4, 0x2403fff8,
-0x431024, 0x461023, 0x218c3, 0x58600001,
-0x24630100, 0x8f42008c, 0x43102b, 0x14400006,
-0x712c2, 0x8f420344, 0x24420001, 0xaf420344,
-0x10000098, 0x8f420344, 0x934305c2, 0x1060000f,
-0x30460001, 0x8f420010, 0x34480400, 0x32c20008,
-0x10400008, 0x30e20200, 0x10400006, 0x3c034000,
-0x9602000e, 0xaf4300ac, 0x21400, 0x10000004,
-0xaf4200b0, 0x10000002, 0xaf4000ac, 0x8f480010,
-0x30e20004, 0x10400045, 0x3227ffff, 0x8f4900ac,
-0x11200005, 0x30c200ff, 0x14400006, 0x24020040,
-0x10000004, 0x24020008, 0x14400002, 0x24020020,
-0x24020004, 0xafa20010, 0x8f430030, 0x11200004,
-0xafa30014, 0x8f4200b0, 0x621025, 0xafa20014,
-0x3c020002, 0x1021025, 0xafa20018, 0x8f460098,
-0x8f420108, 0x40f809, 0x0, 0x10400069,
-0x3224ffff, 0x8f42008c, 0x8f430094, 0x24420001,
-0xaf42008c, 0x24020001, 0xae03000c, 0xa34205c2,
-0x8f420098, 0x2406fff8, 0x8f45013c, 0x441021,
-0x24420007, 0x461024, 0x24840007, 0xaf420094,
-0x8f420090, 0x8f430094, 0x862024, 0x441023,
-0x65182b, 0x14600005, 0xaf420090, 0x8f420094,
-0x8f430144, 0x431023, 0xaf420094, 0x8f430094,
-0x8f420140, 0x43102b, 0x10400009, 0x0,
-0x8f43013c, 0x8f440094, 0x8f420090, 0x8f450138,
-0x641823, 0x431023, 0xaf420090, 0xaf450094,
-0x8f420094, 0x1000001f, 0xaf420098, 0x10e0001d,
-0x30c200ff, 0x14400002, 0x24020010, 0x24020002,
-0xafa20010, 0x8f420030, 0xafa80018, 0xafa20014,
-0x8f460098, 0x8f420108, 0x40f809, 0x0,
-0x10400030, 0x3225ffff, 0x8f420098, 0x8f44013c,
-0x451021, 0xaf420098, 0x8f420090, 0x8f430098,
-0xa34005c2, 0x451023, 0x64182b, 0x14600005,
-0xaf420090, 0x8f420098, 0x8f430144, 0x431023,
-0xaf420098, 0x8f420030, 0x8f430040, 0x24420001,
-0x2463ffff, 0x431024, 0xaf420030, 0x8f420030,
-0x14520018, 0x0, 0x8f420000, 0x10400007,
-0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd,
-0x0, 0x10000005, 0x0, 0xaf800048,
-0x8f820048, 0x1040fffd, 0x0, 0x8f820060,
-0x2403fff7, 0x431024, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x10000002, 0xaf80004c,
-0xaf800048, 0x8fbf002c, 0x8fb20028, 0x8fb10024,
-0x8fb00020, 0x3e00008, 0x27bd0030, 0x3e00008,
-0x0, 0x27bdffd8, 0x3c020001, 0x34422ec0,
-0xafbf0020, 0x8f4300f0, 0x8f840108, 0x2e21021,
-0x54620004, 0x24620008, 0x3c020001, 0x34422cc0,
-0x2e21021, 0x401821, 0xaf4300f0, 0xac600000,
-0x8f4200ec, 0x8c660004, 0x14620004, 0x3c020001,
-0x24820020, 0x1000000f, 0xaf820108, 0x8f4300f0,
-0x34422ec0, 0x2e21021, 0x54620004, 0x24620008,
-0x3c020001, 0x34422cc0, 0x2e21021, 0x401821,
-0x8c620004, 0x21140, 0x821021, 0xaf820108,
-0xac600000, 0x8c850018, 0x30a20036, 0x1040006c,
-0x30a20001, 0x8c82001c, 0x8f430040, 0x8f440034,
-0x24420001, 0x2463ffff, 0x431024, 0x862021,
-0xaf42002c, 0x30a20030, 0x14400006, 0xaf440034,
-0x8f420034, 0x8c03023c, 0x43102b, 0x144000b4,
-0x0, 0x32c20010, 0x10400028, 0x24070008,
-0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c,
-0x8f860120, 0x24020080, 0xafa20010, 0xafa30014,
-0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400011, 0x24020001, 0x3c010001, 0x370821,
-0xa02240f1, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x248467c4, 0xafa20014, 0x8f46002c,
-0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51100,
-0x10000036, 0x0, 0x8f420300, 0x8f43002c,
-0x24420001, 0xaf420300, 0x8f420300, 0x24020001,
-0xa34205c1, 0x10000026, 0xaf430038, 0x8f440170,
-0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
-0x24020020, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
-0x24020001, 0x3c010001, 0x370821, 0xa02240f0,
-0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x248467b8, 0xafa20014, 0x8f46002c, 0x8f870120,
-0x3c050009, 0xc002b3b, 0x34a50900, 0x1000000f,
-0x0, 0x8f420300, 0x24420001, 0xaf420300,
-0x8f420300, 0x8f42002c, 0xa34005c1, 0xaf420038,
-0x3c010001, 0x370821, 0xa02040f1, 0x3c010001,
-0x370821, 0xa02040f0, 0xaf400034, 0x8f420314,
-0x24420001, 0xaf420314, 0x10000059, 0x8f420314,
-0x10400022, 0x30a27000, 0x8c85001c, 0x8f420028,
-0xa22023, 0x4810003, 0x0, 0x8f420040,
-0x822021, 0x8f420358, 0x8f430000, 0xaf450028,
-0x441021, 0x10600007, 0xaf420358, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x34420008, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x10000038,
-0xaf80004c, 0x10000036, 0xaf800048, 0x1040002f,
-0x30a21000, 0x1040000c, 0x30a24000, 0x8c83001c,
-0x8f420050, 0x622023, 0x4820001, 0x24840200,
-0x8f42035c, 0x441021, 0xaf42035c, 0x8f420368,
-0x1000001a, 0xaf430050, 0x1040000c, 0x32c28000,
-0x8c83001c, 0x8f420070, 0x622023, 0x4820001,
-0x24840400, 0x8f420364, 0x441021, 0xaf420364,
-0x8f420368, 0x1000000d, 0xaf430070, 0x1040000e,
-0x3c020800, 0x8c83001c, 0x8f420060, 0x622023,
-0x4820001, 0x24840100, 0x8f420360, 0x441021,
-0xaf420360, 0x8f420368, 0xaf430060, 0x441021,
-0xaf420368, 0x3c020800, 0x2c21024, 0x50400008,
-0x36940040, 0x10000006, 0x0, 0x30a20100,
-0x10400003, 0x0, 0xc002bd8, 0x0,
-0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008,
-0x0, 0x27bdffa8, 0xafbf0050, 0xafbe004c,
-0xafb50048, 0xafb30044, 0xafb20040, 0xafb1003c,
-0xafb00038, 0x8f910108, 0x26220020, 0xaf820108,
-0x8e320018, 0xa821, 0x32420024, 0x104001ba,
-0xf021, 0x8e26001c, 0x8f43001c, 0x61100,
-0x621821, 0x8c70000c, 0x9604000c, 0x962d0016,
-0x9473000a, 0x2c8305dd, 0x38828870, 0x2c420001,
-0x621825, 0x10600015, 0x2821, 0x32c20040,
-0x10400015, 0x24020800, 0x96030014, 0x14620012,
-0x3402aaaa, 0x9603000e, 0x14620007, 0x2021,
-0x96030010, 0x24020300, 0x14620004, 0x801021,
-0x96020012, 0x2c440001, 0x801021, 0x54400006,
-0x24050016, 0x10000004, 0x0, 0x24020800,
-0x50820001, 0x2405000e, 0x934205c3, 0x14400008,
-0x5821, 0x240b0001, 0x32620180, 0xaf4500a8,
-0xaf5000a0, 0x10400002, 0xaf4600a4, 0xa34b05c3,
-0x10a00085, 0x2054021, 0x91020000, 0x3821,
-0x3042000f, 0x25080, 0x32c20002, 0x10400012,
-0x10a1821, 0x32620002, 0x10400010, 0x32c20001,
-0x1002021, 0x94820000, 0x24840002, 0xe23821,
-0x83102b, 0x1440fffb, 0x30e2ffff, 0x71c02,
-0x623821, 0x71c02, 0x30e2ffff, 0x623821,
-0x71027, 0xa502000a, 0x32c20001, 0x1040006a,
-0x32620001, 0x10400068, 0x0, 0x8f4200a8,
-0x10400065, 0x0, 0x8f4200a0, 0x8f4300a8,
-0x431021, 0x904c0009, 0x318900ff, 0x39230006,
-0x3182b, 0x39220011, 0x2102b, 0x621824,
-0x1060000c, 0x3c050006, 0x8f4200a4, 0x3c040001,
-0x248467d4, 0xafa20010, 0x8f4200a0, 0x34a54600,
-0x1203821, 0xc002b3b, 0xafa20014, 0x1000004e,
-0x0, 0x32c20004, 0x14400013, 0x2821,
-0x316200ff, 0x14400004, 0x0, 0x95020002,
-0x1000000d, 0x4a2823, 0x9505000c, 0x9502000e,
-0x95030010, 0xa22821, 0xa32821, 0x95030012,
-0x91040009, 0x95020002, 0xa32821, 0xa42821,
-0x4a1023, 0xa22821, 0x2002021, 0x94820000,
-0x24840002, 0xe23821, 0x88102b, 0x1440fffb,
-0x71c02, 0x30e2ffff, 0x623821, 0x71c02,
-0x30e2ffff, 0x623821, 0x1a52821, 0x51c02,
-0x30a2ffff, 0x622821, 0x51c02, 0x30a2ffff,
-0x622821, 0xa72823, 0x51402, 0xa22821,
-0x30a5ffff, 0x50a00001, 0x3405ffff, 0x316200ff,
-0x14400008, 0x318300ff, 0x8f4300a0, 0x8f4200a8,
-0x624021, 0x91020000, 0x3042000f, 0x25080,
-0x318300ff, 0x24020006, 0x14620003, 0x10a1021,
-0x10000002, 0x24440010, 0x24440006, 0x316200ff,
-0x14400006, 0x0, 0x94820000, 0xa22821,
-0x51c02, 0x30a2ffff, 0x622821, 0x934205c3,
-0x10400003, 0x32620100, 0x50400003, 0xa4850000,
-0x52827, 0xa4850000, 0x9622000e, 0x8f43009c,
-0x621821, 0x32a200ff, 0x10400007, 0xaf43009c,
-0x3c024000, 0x2021025, 0xafa20020, 0x8f42009c,
-0x10000003, 0x5e1025, 0xafb00020, 0x8f42009c,
-0xafa20024, 0x32620080, 0x10400010, 0x32620100,
-0x8f4200b4, 0x24430001, 0x210c0, 0x571021,
-0xaf4300b4, 0x8fa30020, 0x8fa40024, 0x3c010001,
-0x220821, 0xac2338e8, 0x3c010001, 0x220821,
-0xac2438ec, 0x100000a5, 0x32c20020, 0x10400064,
-0x0, 0x8f4200b4, 0x24430001, 0x210c0,
-0x571021, 0xaf4300b4, 0x8fa30020, 0x8fa40024,
-0x3c010001, 0x220821, 0xac2338e8, 0x3c010001,
-0x220821, 0xac2438ec, 0x8f4200b4, 0x10400051,
-0x3821, 0x3c090001, 0x352938e8, 0x3c08001f,
-0x3508ffff, 0x240bffff, 0x340affff, 0x710c0,
-0x571021, 0x491021, 0x8c430000, 0x8c440004,
-0xafa30028, 0xafa4002c, 0x8f8200fc, 0x8fa30028,
-0x8fa4002c, 0xac430000, 0xac440004, 0x24420008,
-0xaf8200f0, 0x8f42008c, 0x2442ffff, 0xaf42008c,
-0x97a2002e, 0x8f440270, 0x8f450274, 0x401821,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaf440270, 0xaf450274, 0x8fa20028,
-0x481024, 0x90430000, 0x30630001, 0x1460000b,
-0x402021, 0x8f420278, 0x8f43027c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
-0x8f420278, 0x1000001a, 0x8f43027c, 0x8c820000,
-0x144b000e, 0x0, 0x94820004, 0x144a000b,
-0x0, 0x8f420288, 0x8f43028c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420288, 0xaf43028c,
-0x8f420288, 0x1000000a, 0x8f43028c, 0x8f420280,
-0x8f430284, 0x24630001, 0x2c640001, 0x441021,
-0xaf420280, 0xaf430284, 0x8f420280, 0x8f430284,
-0x8f4200b4, 0x24e70001, 0xe2102b, 0x1440ffb8,
-0x710c0, 0xa34005c3, 0x1000003f, 0xaf4000b4,
-0x8f8200fc, 0x8fa30020, 0x8fa40024, 0xac430000,
-0xac440004, 0x24420008, 0xaf8200f0, 0x8f42009c,
-0x8f46008c, 0x8f440270, 0x8f450274, 0x401821,
-0x1021, 0x24c6ffff, 0xaf46008c, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xaf440270,
-0xaf450274, 0x92020000, 0x30420001, 0x1440000c,
-0x2402ffff, 0x8f420278, 0x8f43027c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
-0x8f420278, 0x8f43027c, 0x1000001c, 0x32c20020,
-0x8e030000, 0x1462000f, 0x3402ffff, 0x96030004,
-0x1462000c, 0x0, 0x8f420288, 0x8f43028c,
-0x24630001, 0x2c640001, 0x441021, 0xaf420288,
-0xaf43028c, 0x8f420288, 0x8f43028c, 0x1000000b,
-0x32c20020, 0x8f420280, 0x8f430284, 0x24630001,
-0x2c640001, 0x441021, 0xaf420280, 0xaf430284,
-0x8f420280, 0x8f430284, 0x32c20020, 0x10400005,
-0xaf40009c, 0x8f420358, 0x2442ffff, 0xaf420358,
-0x8f420358, 0x8e22001c, 0x8f430040, 0x24420001,
-0x2463ffff, 0x431024, 0xaf42002c, 0x32420060,
-0x14400008, 0x32c20010, 0x8f420034, 0x24420001,
-0xaf420034, 0x8c03023c, 0x43102b, 0x14400102,
-0x32c20010, 0x10400018, 0x24070008, 0x8f440170,
-0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
-0x24020080, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x10400047,
-0x24020001, 0x8f420300, 0x8f43002c, 0x24420001,
-0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1,
-0x1000007c, 0xaf430038, 0x8f440170, 0x8f450174,
-0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020020,
-0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c,
-0x40f809, 0x24c6001c, 0x10400057, 0x24020001,
-0x10000065, 0x0, 0x32420012, 0x10400075,
-0x32420001, 0x9622000e, 0x8f43009c, 0x621821,
-0x32c20020, 0x10400005, 0xaf43009c, 0x8f420358,
-0x2442ffff, 0xaf420358, 0x8f420358, 0x8e22001c,
-0x8f430040, 0x24420001, 0x2463ffff, 0x431024,
-0xaf42002c, 0x32420010, 0x14400008, 0x32c20010,
-0x8f420034, 0x24420001, 0xaf420034, 0x8c03023c,
-0x43102b, 0x144000bc, 0x32c20010, 0x10400028,
-0x24070008, 0x8f440170, 0x8f450174, 0x8f43002c,
-0x8f48000c, 0x8f860120, 0x24020080, 0xafa20010,
-0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809,
-0x24c6001c, 0x14400011, 0x24020001, 0x3c010001,
-0x370821, 0xa02240f1, 0x8f820124, 0xafa20010,
-0x8f820128, 0x3c040001, 0x248467c4, 0xafa20014,
-0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b,
-0x34a51100, 0x10000036, 0x0, 0x8f420300,
-0x8f43002c, 0x24420001, 0xaf420300, 0x8f420300,
-0x24020001, 0xa34205c1, 0x10000026, 0xaf430038,
-0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c,
-0x8f860120, 0x24020020, 0xafa20010, 0xafa30014,
-0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400011, 0x24020001, 0x3c010001, 0x370821,
-0xa02240f0, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x248467b8, 0xafa20014, 0x8f46002c,
-0x8f870120, 0x3c050009, 0xc002b3b, 0x34a50900,
-0x1000000f, 0x0, 0x8f420300, 0x24420001,
-0xaf420300, 0x8f420300, 0x8f42002c, 0xa34005c1,
-0xaf420038, 0x3c010001, 0x370821, 0xa02040f1,
-0x3c010001, 0x370821, 0xa02040f0, 0xaf400034,
-0x8f420314, 0x24420001, 0xaf420314, 0x10000062,
-0x8f420314, 0x10400022, 0x32427000, 0x8e25001c,
-0x8f420028, 0xa22023, 0x4810003, 0x0,
-0x8f420040, 0x822021, 0x8f420358, 0x8f430000,
-0xaf450028, 0x441021, 0x10600007, 0xaf420358,
-0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
-0x10000005, 0x0, 0xaf800048, 0x8f820048,
-0x1040fffd, 0x0, 0x8f820060, 0x34420008,
-0xaf820060, 0x8f420000, 0x10400003, 0x0,
-0x10000041, 0xaf80004c, 0x1000003f, 0xaf800048,
-0x1040002f, 0x32421000, 0x1040000c, 0x32424000,
-0x8e23001c, 0x8f420050, 0x622023, 0x4820001,
-0x24840200, 0x8f42035c, 0x441021, 0xaf42035c,
-0x8f420368, 0x1000001a, 0xaf430050, 0x1040000c,
-0x32c28000, 0x8e23001c, 0x8f420070, 0x622023,
-0x4820001, 0x24840400, 0x8f420364, 0x441021,
-0xaf420364, 0x8f420368, 0x1000000d, 0xaf430070,
-0x1040000e, 0x3c020800, 0x8e23001c, 0x8f420060,
-0x622023, 0x4820001, 0x24840100, 0x8f420360,
-0x441021, 0xaf420360, 0x8f420368, 0xaf430060,
-0x441021, 0xaf420368, 0x3c020800, 0x2c21024,
-0x50400011, 0x36940040, 0x1000000f, 0x0,
-0x32420048, 0x10400007, 0x24150001, 0x8e22001c,
-0x3c03ffff, 0x43f024, 0x3042ffff, 0x1000fd75,
-0xae22001c, 0x32420100, 0x10400003, 0x0,
-0xc002bd8, 0x0, 0x8fbf0050, 0x8fbe004c,
-0x8fb50048, 0x8fb30044, 0x8fb20040, 0x8fb1003c,
-0x8fb00038, 0x3e00008, 0x27bd0058, 0x3e00008,
-0x0, 0x0, 0x0, 0x8f8300e4,
-0x8f8200e0, 0x2404fff8, 0x441024, 0x621026,
-0x2102b, 0x21023, 0x3e00008, 0x621024,
-0x3e00008, 0x0, 0x27bdffe0, 0xafbf001c,
-0xafb00018, 0x8f8600c4, 0x8f8400e0, 0x8f8500e4,
-0x2402fff8, 0x821824, 0x10a30009, 0x27623ff8,
-0x14a20002, 0x24a20008, 0x27623000, 0x408021,
-0x16030005, 0x30820004, 0x10400004, 0xc02021,
-0x10000022, 0x1021, 0x8e040000, 0x8f42011c,
-0x14a20003, 0x0, 0x8f420120, 0xaf420114,
-0x8ca30000, 0x8f420148, 0x831823, 0x43102b,
-0x10400003, 0x0, 0x8f420148, 0x621821,
-0x94a20006, 0x24420050, 0x62102b, 0x1440000f,
-0xa01021, 0xafa40010, 0xafa30014, 0x8ca60000,
-0x8ca70004, 0x3c040001, 0xc002b3b, 0x24846894,
-0x8f42020c, 0x24420001, 0xaf42020c, 0x8f42020c,
-0x1021, 0xaf9000e8, 0xaf9000e4, 0x8fbf001c,
-0x8fb00018, 0x3e00008, 0x27bd0020, 0x3e00008,
-0x0, 0x8f8400e0, 0x8f8800c4, 0x8f8300e8,
-0x2402fff8, 0x823824, 0xe32023, 0x2c821000,
-0x50400001, 0x24841000, 0x420c2, 0x801821,
-0x8f440258, 0x8f45025c, 0x1021, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xaf440258,
-0xaf45025c, 0x8f8300c8, 0x8f420148, 0x1032023,
-0x82102b, 0x14400004, 0x801821, 0x8f420148,
-0x822021, 0x801821, 0x8f440250, 0x8f450254,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaf440250, 0xaf450254, 0xaf8800c8,
-0xaf8700e4, 0xaf8700e8, 0x3e00008, 0x0,
-0x27bdff30, 0x240a0001, 0xafbf00c8, 0xafbe00c4,
-0xafb500c0, 0xafb300bc, 0xafb200b8, 0xafb100b4,
-0xafb000b0, 0xa3a00097, 0xafa00044, 0xafaa005c,
-0x934205c4, 0xa7a0008e, 0x1040000a, 0xa7a00086,
-0x8f4b00c4, 0xafab0064, 0x8f4a00c0, 0xafaa006c,
-0x8f4b00cc, 0xafab0074, 0x8f4a00c8, 0x10000129,
-0xafaa007c, 0x8f420114, 0x40f809, 0x0,
-0x403021, 0x10c0034f, 0x0, 0x8cc20000,
-0x8cc30004, 0xafa20020, 0xafa30024, 0x8fab0024,
-0x8faa0020, 0x3162ffff, 0x2442fffc, 0xafa2006c,
-0x3c020006, 0x2c21024, 0xafab007c, 0x14400015,
-0xafaa0064, 0x91420000, 0x30420001, 0x10400011,
-0x2402ffff, 0x8d430000, 0x14620004, 0x3402ffff,
-0x95430004, 0x1062000b, 0x0, 0xc0024bb,
-0x8fa40064, 0x304200ff, 0x14400006, 0x0,
-0x8f420118, 0x40f809, 0x0, 0x1000032d,
-0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
-0x431024, 0x3c03ffff, 0x431824, 0x14600003,
-0xafa20024, 0x10000040, 0x1821, 0x3c020080,
-0x621024, 0x10400007, 0x0, 0x8f42038c,
-0x24420001, 0xaf42038c, 0x8f42038c, 0x10000036,
-0x24030001, 0x8f420210, 0x24420001, 0xaf420210,
-0x8f420210, 0x3c020001, 0x621024, 0x10400006,
-0x3c020002, 0x8f4201c4, 0x24420001, 0xaf4201c4,
-0x8f4201c4, 0x3c020002, 0x621024, 0x10400006,
-0x3c020004, 0x8f42037c, 0x24420001, 0xaf42037c,
-0x8f42037c, 0x3c020004, 0x621024, 0x10400006,
-0x3c020008, 0x8f420380, 0x24420001, 0xaf420380,
-0x8f420380, 0x3c020008, 0x621024, 0x10400006,
-0x3c020010, 0x8f420384, 0x24420001, 0xaf420384,
-0x8f420384, 0x3c020010, 0x621024, 0x10400006,
-0x3c020020, 0x8f4201c0, 0x24420001, 0xaf4201c0,
-0x8f4201c0, 0x3c020020, 0x621024, 0x10400006,
-0x24030001, 0x8f420388, 0x24420001, 0xaf420388,
-0x8f420388, 0x24030001, 0x8c020260, 0x8fab006c,
-0x4b102b, 0x10400014, 0x307000ff, 0x8f4201e8,
-0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8faa007c,
-0x8f8200e0, 0x354a0100, 0xafaa007c, 0xafa20010,
-0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0,
-0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007,
-0xc002b3b, 0x34a50800, 0x12000010, 0x3c020080,
-0x2c21024, 0x1440000e, 0x32c20400, 0x8fab007c,
-0x3c020080, 0x34420100, 0x1621024, 0x10400005,
-0x0, 0x8f42020c, 0x24420001, 0xaf42020c,
-0x8f42020c, 0x100002b0, 0x8fa3006c, 0x32c20400,
-0x10400015, 0x34028100, 0x8faa0064, 0x9543000c,
-0x14620012, 0x3c020100, 0x240b0200, 0xa7ab008e,
-0x9542000e, 0x8d430008, 0x8d440004, 0x8d450000,
-0x8faa006c, 0x8fab0064, 0x254afffc, 0xafaa006c,
-0xa7a20086, 0xad63000c, 0xad640008, 0xad650004,
-0x256b0004, 0xafab0064, 0x3c020100, 0x2c21024,
-0x10400004, 0x0, 0x8faa006c, 0x254a0004,
-0xafaa006c, 0x8f4200bc, 0x5040000a, 0xafa00074,
-0x8fab006c, 0x4b102b, 0x50400006, 0xafa00074,
-0x8f4200bc, 0x1621023, 0xafa20074, 0x8f4a00bc,
-0xafaa006c, 0x8f420080, 0x8fab006c, 0x4b102b,
-0x10400056, 0x32c28000, 0x1040005e, 0x240a0003,
-0x32c21000, 0x1040005b, 0xafaa005c, 0x10000058,
-0x240b0004, 0x8f420350, 0x2403ffbf, 0x283a024,
-0x24420001, 0xaf420350, 0x1000024f, 0x8f420350,
-0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128,
-0x3c040001, 0x248468d0, 0x26620001, 0xafa20014,
-0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007,
-0xc002b3b, 0x34a52250, 0x1000023f, 0x0,
-0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128,
-0x3c040001, 0x248468d0, 0x24020002, 0xafa20014,
-0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007,
-0xc002b3b, 0x34a52450, 0x1000022f, 0x0,
-0x8ea20000, 0x8ea30004, 0x3c040001, 0x248468e8,
-0xafb00010, 0xafbe0014, 0x8ea70018, 0x34a52800,
-0xc002b3b, 0x603021, 0x10000223, 0x0,
-0xa6b1000a, 0x8f820124, 0x3c040001, 0x248468f0,
-0xafbe0014, 0xafa20010, 0x8f460044, 0x8f870120,
-0x3c050007, 0xc002b3b, 0x34a53000, 0x10000216,
-0x0, 0xa6b1000a, 0xa6b2000e, 0x8f820124,
-0x3c040001, 0x248468fc, 0xafbe0014, 0xafa20010,
-0x8f460044, 0x8f870120, 0x3c050007, 0xc002b3b,
-0x34a53200, 0x10000208, 0x0, 0x8f420084,
-0x8faa006c, 0x4a102b, 0x14400007, 0x3c020001,
-0x2c21024, 0x10400004, 0x0, 0x240b0002,
-0xafab005c, 0x8faa006c, 0x1140021b, 0x27ab0020,
-0xafab00a4, 0x3c0a001f, 0x354affff, 0xafaa009c,
-0x8fab005c, 0x240a0001, 0x556a0021, 0x240a0002,
-0x8f430054, 0x8f420050, 0x1062000b, 0x274b0054,
-0x8f5e0054, 0x3403ecc0, 0xafab004c, 0x27c20001,
-0x304201ff, 0xafa20054, 0x1e1140, 0x431021,
-0x1000006b, 0x2e2a821, 0x8f420044, 0x8faa006c,
-0x3c040001, 0x248468ac, 0xafaa0014, 0xafa20010,
-0x8f460054, 0x8f470050, 0x3c050007, 0xc002b3b,
-0x34a51300, 0x8f430350, 0x2402ffbf, 0x282a024,
-0x24630001, 0xaf430350, 0x100001d3, 0x8f420350,
-0x156a001d, 0x0, 0x8f430074, 0x8f420070,
-0x1062000a, 0x274b0074, 0x8f5e0074, 0xafab004c,
-0x27c20001, 0x304203ff, 0xafa20054, 0x1e1140,
-0x24426cc0, 0x1000004a, 0x2e2a821, 0x8f420044,
-0x8faa006c, 0x3c040001, 0x248468b8, 0x3c050007,
-0xafaa0014, 0xafa20010, 0x8f460074, 0x8f470070,
-0x34a51500, 0x240b0001, 0xc002b3b, 0xafab005c,
-0x1000ffc3, 0x0, 0x8f430064, 0x8f420060,
-0x1062001a, 0x274a0064, 0x8f5e0064, 0x8fab005c,
-0xafaa004c, 0x27c20001, 0x304200ff, 0xafa20054,
-0x24020004, 0x1562000e, 0x1e1140, 0x1e1180,
-0x24420cc0, 0x2e21021, 0xafa20044, 0x9442002a,
-0x8faa0044, 0x8fab006c, 0x4b102b, 0x10400024,
-0x25550020, 0x240a0001, 0x10000021, 0xa3aa0097,
-0x24424cc0, 0x1000001e, 0x2e2a821, 0x8f420044,
-0x8fab006c, 0x3c040001, 0x248468c4, 0xafab0014,
-0xafa20010, 0x8f460064, 0x8f470060, 0x3c050007,
-0xc002b3b, 0x34a51800, 0x3c020008, 0x2c21024,
-0x1440ff34, 0x0, 0x8f420370, 0x240a0001,
-0xafaa005c, 0x24420001, 0xaf420370, 0x1000ff90,
-0x8f420370, 0x27a30036, 0x131040, 0x621821,
-0x94620000, 0x441021, 0x10000020, 0xa4620000,
-0x8fab0064, 0xaeab0018, 0x93a20097, 0x10400072,
-0x9821, 0x8faa0044, 0x8fa4006c, 0x8fa300a4,
-0x25420020, 0xafa20028, 0x25420008, 0xafa20030,
-0x25420010, 0xafaa002c, 0xafa20034, 0x9542002a,
-0xa7a20038, 0x95420018, 0xa7a2003a, 0x9542001a,
-0xa7a2003c, 0x9542001c, 0xa7a2003e, 0x94620018,
-0x24630002, 0x822023, 0x1880ffde, 0x26730001,
-0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc,
-0x26650001, 0xa2102a, 0x1440002b, 0x24030001,
-0x8f83012c, 0x10600023, 0x0, 0x8f820124,
-0x431023, 0x22143, 0x58800001, 0x24840040,
-0x8f820128, 0x431023, 0x21943, 0x58600001,
-0x24630040, 0x64102a, 0x54400001, 0x602021,
-0xaf4400fc, 0x8f4200fc, 0xa2102a, 0x10400011,
-0x24030001, 0x10000015, 0x306200ff, 0x8fab0064,
-0x96070018, 0xafab0010, 0x8e220008, 0x3c040001,
-0x248468dc, 0x8c430004, 0x8c420000, 0x34a52400,
-0x2403021, 0xc002b3b, 0xafa30014, 0x1000002b,
-0x0, 0x8f420334, 0x1821, 0x24420001,
-0xaf420334, 0x8f420334, 0x306200ff, 0x5040fedc,
-0x3c020800, 0x12600021, 0x9021, 0x8fb100a4,
-0x2208021, 0x8e220008, 0x96070018, 0x8fa60064,
-0x8c440000, 0x8c450004, 0x240a0001, 0xafaa0010,
-0xafbe0014, 0x8f420008, 0xafa20018, 0x8f42010c,
-0x40f809, 0x0, 0x1040ffd8, 0x3c050007,
-0x96020018, 0x8fab0064, 0x8faa009c, 0x1625821,
-0x14b102b, 0x10400004, 0xafab0064, 0x8f420148,
-0x1625823, 0xafab0064, 0x26100002, 0x26520001,
-0x253102b, 0x1440ffe3, 0x26310004, 0x8fb0006c,
-0x10000036, 0x97b10038, 0x8f4200fc, 0x24050002,
-0xa2102a, 0x1440001b, 0x24030001, 0x8f83012c,
-0x10600013, 0x0, 0x8f820124, 0x431023,
-0x22143, 0x58800001, 0x24840040, 0x8f820128,
-0x431023, 0x21943, 0x58600001, 0x24630040,
-0x64102a, 0x54400001, 0x602021, 0xaf4400fc,
-0x8f4200fc, 0xa2102a, 0x14400006, 0x24030001,
-0x8f420334, 0x1821, 0x24420001, 0xaf420334,
-0x8f420334, 0x306200ff, 0x1040fea5, 0x3c020800,
-0x96b1000a, 0x8fb0006c, 0x3223ffff, 0x70102b,
-0x54400001, 0x608021, 0x8ea40000, 0x8ea50004,
-0x240b0001, 0xafab0010, 0xafbe0014, 0x8f420008,
-0x8fa60064, 0xafa20018, 0x8f42010c, 0x40f809,
-0x2003821, 0x1040fea2, 0x3c050007, 0x96a3000e,
-0x97aa008e, 0x11400007, 0x609021, 0x934205c4,
-0x14400004, 0x0, 0x97ab0086, 0x6a1825,
-0xa6ab0016, 0x8faa007c, 0x3c02ffff, 0x1421024,
-0x10400003, 0xa1402, 0x34630400, 0xa6a20014,
-0x8fab006c, 0x560b0072, 0xa6a3000e, 0x34620004,
-0xa6a2000e, 0x8faa0074, 0x16a1021, 0xa6a2000a,
-0x8f430044, 0x8f4401a0, 0x8f4501a4, 0x34028000,
-0xafa20010, 0x8f420044, 0x2a03021, 0x24070020,
-0xafa20014, 0x8f42000c, 0x31940, 0x604821,
-0xafa20018, 0x8f42010c, 0x4021, 0xa92821,
-0xa9182b, 0x882021, 0x40f809, 0x832021,
-0x5040fe7f, 0xa6b2000e, 0x8f420368, 0xafa0006c,
-0xa34005c4, 0x2442ffff, 0xaf420368, 0x8fab005c,
-0x240a0001, 0x8f420368, 0x156a0006, 0x240a0002,
-0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c,
-0x8f42035c, 0x156a0006, 0x0, 0x8f420364,
-0x2442ffff, 0xaf420364, 0x10000005, 0x8f420364,
-0x8f420360, 0x2442ffff, 0xaf420360, 0x8f420360,
-0x8faa0054, 0x8fab004c, 0xad6a0000, 0x8f420044,
-0x8f440088, 0x8f430078, 0x24420001, 0x441024,
-0x24630001, 0xaf420044, 0xaf430078, 0x8c020240,
-0x62182b, 0x14600075, 0x24070008, 0x8f440168,
-0x8f45016c, 0x8f430044, 0x8f48000c, 0x8f860120,
-0x24020040, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
-0x240b0001, 0x3c010001, 0x370821, 0xa02b40f2,
-0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x2484688c, 0xafa20014, 0x8f460044, 0x8f870120,
-0x3c050009, 0xc002b3b, 0x34a51300, 0x1000000b,
-0x0, 0x8f420304, 0x24420001, 0xaf420304,
-0x8f420304, 0x8f420044, 0xaf42007c, 0x3c010001,
-0x370821, 0xa02040f2, 0xaf400078, 0x8f420318,
-0x24420001, 0xaf420318, 0x10000048, 0x8f420318,
-0xa6b0000a, 0x8f430044, 0x8f4401a0, 0x8f4501a4,
-0x34028000, 0xafa20010, 0x8f420044, 0x2a03021,
-0x24070020, 0xafa20014, 0x8f42000c, 0x31940,
-0x604821, 0xafa20018, 0x8f42010c, 0x4021,
-0xa92821, 0xa9182b, 0x882021, 0x40f809,
-0x832021, 0x1040fe1f, 0x240a0001, 0xa34a05c4,
-0x8fab006c, 0x8faa0064, 0x1705823, 0xafab006c,
-0x8fab009c, 0x1505021, 0x16a102b, 0x10400004,
-0xafaa0064, 0x8f420148, 0x1425023, 0xafaa0064,
-0x8f420368, 0x2442ffff, 0xaf420368, 0x8faa005c,
-0x240b0001, 0x8f420368, 0x154b0006, 0x240b0002,
-0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c,
-0x8f42035c, 0x114b0006, 0x0, 0x8f420360,
-0x2442ffff, 0xaf420360, 0x10000005, 0x8f420360,
-0x8f420364, 0x2442ffff, 0xaf420364, 0x8f420364,
-0x8fab0054, 0x8faa004c, 0xad4b0000, 0x8f420044,
-0x8f440088, 0x8f430078, 0x24420001, 0x441024,
-0x24630001, 0xaf420044, 0xaf430078, 0x8faa006c,
-0x1540fe0b, 0x0, 0x8fab006c, 0x1160001e,
-0x0, 0x934205c4, 0x10400009, 0x0,
-0x8faa0064, 0xaf4a00c4, 0xaf4b00c0, 0x8fab007c,
-0xaf4b00c8, 0x8faa0074, 0x1000000e, 0xaf4a00cc,
-0x97ab008e, 0x1160000b, 0x34038100, 0x8fa20020,
-0x8c46000c, 0xa443000c, 0x97aa0086, 0x8c440004,
-0x8c450008, 0xa44a000e, 0xac440000, 0xac450004,
-0xac460008, 0x8f42034c, 0x24420001, 0xaf42034c,
-0x10000010, 0x8f42034c, 0x8fab007c, 0x3164ffff,
-0x2484fffc, 0x801821, 0x8f440250, 0x8f450254,
-0x8f460118, 0x1021, 0xa32821, 0xa3382b,
-0x822021, 0x872021, 0xaf440250, 0xc0f809,
-0xaf450254, 0x8fbf00c8, 0x8fbe00c4, 0x8fb500c0,
-0x8fb300bc, 0x8fb200b8, 0x8fb100b4, 0x8fb000b0,
-0x3e00008, 0x27bd00d0, 0x3e00008, 0x0,
-0x27bdff38, 0x240b0001, 0xafbf00c0, 0xafbe00bc,
-0xafb500b8, 0xafb300b4, 0xafb200b0, 0xafb100ac,
-0xafb000a8, 0xa3a00087, 0xafa00044, 0xafab005c,
-0x934205c4, 0xa7a00076, 0x10400007, 0xa7a0007e,
-0x8f4c00c0, 0xafac0064, 0x8f4b00c8, 0x8f5e00c4,
-0x10000130, 0xafab006c, 0x8f420114, 0x40f809,
-0x0, 0x403021, 0x10c002a1, 0x0,
-0x8cc20000, 0x8cc30004, 0xafa20020, 0xafa30024,
-0x8fac0024, 0x8fbe0020, 0x3182ffff, 0x2442fffc,
-0xafa20064, 0x3c020006, 0x2c21024, 0x14400015,
-0xafac006c, 0x93c20000, 0x30420001, 0x10400011,
-0x2402ffff, 0x8fc30000, 0x14620004, 0x3402ffff,
-0x97c30004, 0x1062000b, 0x0, 0xc0024bb,
-0x3c02021, 0x304200ff, 0x14400006, 0x0,
-0x8f420118, 0x40f809, 0x0, 0x10000280,
-0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
-0x431024, 0x3c03ffff, 0x431824, 0x14600003,
-0xafa20024, 0x10000040, 0x8021, 0x3c020080,
-0x621024, 0x10400007, 0x0, 0x8f42038c,
-0x24420001, 0xaf42038c, 0x8f42038c, 0x10000036,
-0x24100001, 0x8f420210, 0x24420001, 0xaf420210,
-0x8f420210, 0x3c020001, 0x621024, 0x10400006,
-0x3c020002, 0x8f4201c4, 0x24420001, 0xaf4201c4,
-0x8f4201c4, 0x3c020002, 0x621024, 0x10400006,
-0x3c020004, 0x8f42037c, 0x24420001, 0xaf42037c,
-0x8f42037c, 0x3c020004, 0x621024, 0x10400006,
-0x3c020008, 0x8f420380, 0x24420001, 0xaf420380,
-0x8f420380, 0x3c020008, 0x621024, 0x10400006,
-0x3c020010, 0x8f420384, 0x24420001, 0xaf420384,
-0x8f420384, 0x3c020010, 0x621024, 0x10400006,
-0x3c020020, 0x8f4201c0, 0x24420001, 0xaf4201c0,
-0x8f4201c0, 0x3c020020, 0x621024, 0x10400006,
-0x24100001, 0x8f420388, 0x24420001, 0xaf420388,
-0x8f420388, 0x24100001, 0x8c020260, 0x8fab0064,
-0x4b102b, 0x10400015, 0x320200ff, 0x8f4201e8,
-0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8fac006c,
-0x8f8200e0, 0x358c0100, 0xafac006c, 0xafa20010,
-0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0,
-0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007,
-0xc002b3b, 0x34a53600, 0x320200ff, 0x10400010,
-0x3c020080, 0x2c21024, 0x1440000e, 0x32c20400,
-0x8fab006c, 0x3c020080, 0x34420100, 0x1621024,
-0x10400005, 0x0, 0x8f42020c, 0x24420001,
-0xaf42020c, 0x8f42020c, 0x10000202, 0x8fa30064,
-0x32c20400, 0x10400012, 0x34028100, 0x97c3000c,
-0x1462000f, 0x0, 0x240c0200, 0xa7ac0076,
-0x97c2000e, 0x8fc30008, 0x8fc40004, 0x8fab0064,
-0x8fc50000, 0x256bfffc, 0xafab0064, 0xa7a2007e,
-0xafc3000c, 0xafc40008, 0xafc50004, 0x27de0004,
-0x8fa70064, 0x320200ff, 0x14400034, 0x3c020100,
-0x97c4000c, 0x2c8305dd, 0x38828870, 0x2c420001,
-0x621825, 0x10600015, 0x2821, 0x32c20800,
-0x10400015, 0x24020800, 0x97c30014, 0x14620012,
-0x3402aaaa, 0x97c3000e, 0x14620007, 0x2021,
-0x97c30010, 0x24020300, 0x14620004, 0x801021,
-0x97c20012, 0x2c440001, 0x801021, 0x54400006,
-0x24050016, 0x10000004, 0x0, 0x24020800,
-0x50820001, 0x2405000e, 0x10a00013, 0x3c52021,
-0x24830009, 0x3c02001f, 0x3442ffff, 0x43102b,
-0x10400003, 0x0, 0x8f420148, 0x621823,
-0x90620000, 0x38430006, 0x2c630001, 0x38420011,
-0x2c420001, 0x621825, 0x10600004, 0x3c020100,
-0x94820002, 0x453821, 0x3c020100, 0x2c21024,
-0x5040000e, 0xafa70064, 0x8fac0064, 0x10ec0008,
-0x3c050007, 0x3c040001, 0x24846908, 0x8fa60064,
-0x34a54000, 0xafa00010, 0xc002b3b, 0xafa00014,
-0x8fab0064, 0x256b0004, 0xafab0064, 0x8f420080,
-0x8fac0064, 0x4c102b, 0x1040002c, 0x32c28000,
-0x10400034, 0x240b0003, 0x32c21000, 0x10400031,
-0xafab005c, 0x1000002e, 0x240c0004, 0x8f420350,
-0x2403ffbf, 0x283a024, 0x24420001, 0xaf420350,
-0x10000173, 0x8f420350, 0x3c020800, 0x2c2b025,
-0x2402ffbf, 0x282a024, 0x8f830128, 0x3c040001,
-0x248468d0, 0x26620001, 0xafa20014, 0xafa30010,
-0x8f860120, 0x8f870124, 0x3c050007, 0xc002b3b,
-0x34a55300, 0x10000162, 0x0, 0x8ea20000,
-0x8ea30004, 0x3c040001, 0x248468e8, 0xafb00010,
-0xafb10014, 0x8ea70018, 0x34a55900, 0xc002b3b,
-0x603021, 0x10000156, 0x0, 0x8f420084,
-0x8fab0064, 0x4b102b, 0x14400007, 0x3c020001,
-0x2c21024, 0x10400004, 0x0, 0x240c0002,
-0xafac005c, 0x8fab0064, 0x11600166, 0x27ac0020,
-0xafac008c, 0x8fab005c, 0x240c0001, 0x556c0021,
-0x240c0002, 0x8f430054, 0x8f420050, 0x1062000b,
-0x274b0054, 0x8f510054, 0x3403ecc0, 0xafab004c,
-0x26220001, 0x304201ff, 0xafa20054, 0x111140,
-0x431021, 0x1000006b, 0x2e2a821, 0x8f420044,
-0x8fac0064, 0x3c040001, 0x248468ac, 0xafac0014,
-0xafa20010, 0x8f460054, 0x8f470050, 0x3c050007,
-0xc002b3b, 0x34a54300, 0x8f430350, 0x2402ffbf,
-0x282a024, 0x24630001, 0xaf430350, 0x10000124,
-0x8f420350, 0x156c001d, 0x0, 0x8f430074,
-0x8f420070, 0x1062000a, 0x274b0074, 0x8f510074,
-0xafab004c, 0x26220001, 0x304203ff, 0xafa20054,
-0x111140, 0x24426cc0, 0x1000004a, 0x2e2a821,
-0x8f420044, 0x8fac0064, 0x3c040001, 0x248468b8,
-0x3c050007, 0xafac0014, 0xafa20010, 0x8f460074,
-0x8f470070, 0x34a54500, 0x240b0001, 0xc002b3b,
-0xafab005c, 0x1000ffc3, 0x0, 0x8f430064,
-0x8f420060, 0x1062001a, 0x274c0064, 0x8f510064,
-0x8fab005c, 0xafac004c, 0x26220001, 0x304200ff,
-0xafa20054, 0x24020004, 0x1562000e, 0x111140,
-0x111180, 0x24420cc0, 0x2e21021, 0xafa20044,
-0x9442002a, 0x8fac0044, 0x8fab0064, 0x4b102b,
-0x10400024, 0x25950020, 0x240c0001, 0x10000021,
-0xa3ac0087, 0x24424cc0, 0x1000001e, 0x2e2a821,
-0x8f420044, 0x8fab0064, 0x3c040001, 0x248468c4,
-0xafab0014, 0xafa20010, 0x8f460064, 0x8f470060,
-0x3c050007, 0xc002b3b, 0x34a54800, 0x3c020008,
-0x2c21024, 0x1440ff61, 0x0, 0x8f420370,
-0x240c0001, 0xafac005c, 0x24420001, 0xaf420370,
-0x1000ff90, 0x8f420370, 0x27a30036, 0x131040,
-0x621821, 0x94620000, 0x441021, 0x1000001f,
-0xa4620000, 0xaebe0018, 0x93a20087, 0x10400084,
-0x9821, 0x8fab0044, 0x8fa40064, 0x8fa3008c,
-0x25620020, 0xafa20028, 0x25620008, 0xafa20030,
-0x25620010, 0xafab002c, 0xafa20034, 0x9562002a,
-0xa7a20038, 0x95620018, 0xa7a2003a, 0x9562001a,
-0xa7a2003c, 0x9562001c, 0xa7a2003e, 0x94620018,
-0x24630002, 0x822023, 0x1880ffdf, 0x26730001,
-0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc,
-0x262102a, 0x14400030, 0x24030001, 0x8f83012c,
-0x10600028, 0x0, 0x8f820124, 0x431023,
-0x22143, 0x58800001, 0x24840040, 0x8f820128,
-0x431023, 0x21943, 0x58600001, 0x24630040,
-0x64102a, 0x54400001, 0x602021, 0xaf4400fc,
-0x8f4200fc, 0x262102a, 0x10400016, 0x24030001,
-0x1000001a, 0x306200ff, 0x8fac008c, 0x101040,
-0x4c1021, 0x94470018, 0x101080, 0x4c1021,
-0xafbe0010, 0x8c420008, 0x3c040001, 0x248468dc,
-0x3c050007, 0x8c430004, 0x8c420000, 0x34a55500,
-0x2003021, 0xc002b3b, 0xafa30014, 0x10000039,
-0x0, 0x8f420334, 0x1821, 0x24420001,
-0xaf420334, 0x8f420334, 0x306200ff, 0x1040ff06,
-0x8021, 0x8f430008, 0x2402fbff, 0x1260002d,
-0x625024, 0x3c0b4000, 0x22b4025, 0x8fb1008c,
-0x2669ffff, 0x2209021, 0x8e420008, 0x96270018,
-0x8c440000, 0x8c450004, 0x56090004, 0x240b0001,
-0x240c0002, 0x10000002, 0xafac0010, 0xafab0010,
-0x16000004, 0xafa80014, 0x8f420008, 0x10000002,
-0xafa20018, 0xafaa0018, 0x8f42010c, 0x3c03021,
-0xafa80098, 0xafa9009c, 0x40f809, 0xafaa00a0,
-0x8fa80098, 0x8fa9009c, 0x8faa00a0, 0x1040ffc2,
-0x3c02001f, 0x96230018, 0x3442ffff, 0x3c3f021,
-0x5e102b, 0x10400003, 0x26310002, 0x8f420148,
-0x3c2f023, 0x26100001, 0x213102b, 0x1440ffda,
-0x26520004, 0x8fb00064, 0x1000001a, 0x0,
-0x96a3000a, 0x8fb00064, 0x70102b, 0x54400001,
-0x608021, 0x8ea40000, 0x8ea50004, 0x8fab005c,
-0x240c0002, 0xafac0010, 0x934305c4, 0xb1700,
-0x10600003, 0x2223025, 0x3c020800, 0xc23025,
-0xafa60014, 0x8f420008, 0xafa20018, 0x8f42010c,
-0x3c03021, 0x40f809, 0x2003821, 0x1040fecb,
-0x3c050007, 0x97ac0076, 0x11800007, 0x96a3000e,
-0x934205c4, 0x14400004, 0x0, 0x97ab007e,
-0x6c1825, 0xa6ab0016, 0x8fac006c, 0x3c02ffff,
-0x1821024, 0x10400003, 0xc1402, 0x34630400,
-0xa6a20014, 0xa6b0000a, 0x8fab0064, 0x560b0006,
-0x3d0f021, 0x34620004, 0xafa00064, 0xa6a2000e,
-0x1000000d, 0xa34005c4, 0x8fac0064, 0x3c02001f,
-0x3442ffff, 0x5e102b, 0x1906023, 0xafac0064,
-0xa6a3000e, 0x240b0001, 0x10400003, 0xa34b05c4,
-0x8f420148, 0x3c2f023, 0x8fab0054, 0x8fac004c,
-0xad8b0000, 0x8fac0064, 0x1580feba, 0x0,
-0x8fab0064, 0x1160001b, 0x0, 0x934205c4,
-0x10400006, 0x0, 0xaf5e00c4, 0xaf4b00c0,
-0x8fac006c, 0x1000000e, 0xaf4c00c8, 0x97ab0076,
-0x1160000b, 0x34038100, 0x8fa20020, 0x8c46000c,
-0xa443000c, 0x97ac007e, 0x8c440004, 0x8c450008,
-0xa44c000e, 0xac440000, 0xac450004, 0xac460008,
-0x8f42034c, 0x24420001, 0xaf42034c, 0x10000010,
-0x8f42034c, 0x8fab006c, 0x3164ffff, 0x2484fffc,
-0x801821, 0x8f440250, 0x8f450254, 0x8f460118,
-0x1021, 0xa32821, 0xa3382b, 0x822021,
-0x872021, 0xaf440250, 0xc0f809, 0xaf450254,
-0x8fbf00c0, 0x8fbe00bc, 0x8fb500b8, 0x8fb300b4,
-0x8fb200b0, 0x8fb100ac, 0x8fb000a8, 0x3e00008,
-0x27bd00c8, 0x3e00008, 0x0, 0x27bdffd8,
-0xafbf0024, 0xafb00020, 0x8f43004c, 0x8f420048,
-0x10620034, 0x0, 0x8f430048, 0x8f42004c,
-0x622023, 0x4820001, 0x24840200, 0x8f430054,
-0x8f42004c, 0x43102b, 0x14400004, 0x24020200,
-0x8f43004c, 0x10000005, 0x431023, 0x8f420054,
-0x8f43004c, 0x431023, 0x2442ffff, 0x405021,
-0x8a102a, 0x54400001, 0x805021, 0x8f49004c,
-0x8f48004c, 0x8f440188, 0x8f45018c, 0x8f46004c,
-0x24071000, 0xafa70010, 0x84140, 0x1001821,
-0x12a4821, 0x313001ff, 0xafb00014, 0x8f470014,
-0x1021, 0x63140, 0xafa70018, 0xa32821,
-0xa3382b, 0x822021, 0x872021, 0x3402ecc0,
-0xc23021, 0x8f420108, 0x2e63021, 0x40f809,
-0xa3940, 0x54400001, 0xaf50004c, 0x8f43004c,
-0x8f420048, 0x14620018, 0x0, 0x8f420000,
-0x10400007, 0x0, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x2403fdff, 0x431024, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x10000002,
-0xaf80004c, 0xaf800048, 0x8fbf0024, 0x8fb00020,
-0x3e00008, 0x27bd0028, 0x3e00008, 0x0,
-0x27bdffd8, 0xafbf0024, 0xafb00020, 0x8f43005c,
-0x8f420058, 0x10620049, 0x0, 0x8f430058,
-0x8f42005c, 0x622023, 0x4820001, 0x24840100,
-0x8f430064, 0x8f42005c, 0x43102b, 0x14400004,
-0x24020100, 0x8f43005c, 0x10000005, 0x431023,
-0x8f420064, 0x8f43005c, 0x431023, 0x2442ffff,
-0x403821, 0x87102a, 0x54400001, 0x803821,
-0x8f42005c, 0x471021, 0x305000ff, 0x32c21000,
-0x10400015, 0x24082000, 0x8f49005c, 0x8f440190,
-0x8f450194, 0x8f46005c, 0x73980, 0xafa80010,
-0xafb00014, 0x8f480014, 0x94980, 0x1201821,
-0x1021, 0xa32821, 0xa3482b, 0x822021,
-0x892021, 0x63180, 0xafa80018, 0x8f420108,
-0x10000014, 0x24c60cc0, 0x8f49005c, 0x8f440190,
-0x8f450194, 0x8f46005c, 0x73940, 0xafa80010,
-0xafb00014, 0x8f480014, 0x94940, 0x1201821,
-0x1021, 0xa32821, 0xa3482b, 0x822021,
-0x892021, 0x63140, 0xafa80018, 0x8f420108,
-0x24c64cc0, 0x40f809, 0x2e63021, 0x54400001,
-0xaf50005c, 0x8f43005c, 0x8f420058, 0x14620018,
-0x0, 0x8f420000, 0x10400007, 0x0,
-0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
-0x10000005, 0x0, 0xaf800048, 0x8f820048,
-0x1040fffd, 0x0, 0x8f820060, 0x2403feff,
-0x431024, 0xaf820060, 0x8f420000, 0x10400003,
-0x0, 0x10000002, 0xaf80004c, 0xaf800048,
-0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028,
-0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
-0xafb00020, 0x8f43006c, 0x8f420068, 0x10620033,
-0x0, 0x8f430068, 0x8f42006c, 0x622023,
-0x4820001, 0x24840400, 0x8f430074, 0x8f42006c,
-0x43102b, 0x14400004, 0x24020400, 0x8f43006c,
-0x10000005, 0x431023, 0x8f420074, 0x8f43006c,
-0x431023, 0x2442ffff, 0x405021, 0x8a102a,
-0x54400001, 0x805021, 0x8f49006c, 0x8f48006c,
-0x8f440198, 0x8f45019c, 0x8f46006c, 0x24074000,
-0xafa70010, 0x84140, 0x1001821, 0x12a4821,
-0x313003ff, 0xafb00014, 0x8f470014, 0x1021,
-0x63140, 0x24c66cc0, 0xafa70018, 0xa32821,
-0xa3382b, 0x822021, 0x872021, 0x8f420108,
-0x2e63021, 0x40f809, 0xa3940, 0x54400001,
-0xaf50006c, 0x8f43006c, 0x8f420068, 0x14620018,
-0x0, 0x8f420000, 0x10400007, 0x0,
-0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
-0x10000005, 0x0, 0xaf800048, 0x8f820048,
-0x1040fffd, 0x0, 0x8f820060, 0x2403f7ff,
-0x431024, 0xaf820060, 0x8f420000, 0x10400003,
-0x0, 0x10000002, 0xaf80004c, 0xaf800048,
-0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028,
-0x3e00008, 0x0, 0x8f4200fc, 0x3c030001,
-0x8f4400f8, 0x346330c8, 0x24420001, 0xaf4200fc,
-0x8f850128, 0x2e31021, 0x54820004, 0x24820008,
-0x3c020001, 0x34422ec8, 0x2e21021, 0x401821,
-0xaf4300f8, 0xac600000, 0x8f4200f4, 0x14620004,
-0x3c020001, 0x24a20020, 0x1000000f, 0xaf820128,
-0x8f4300f8, 0x344230c8, 0x2e21021, 0x54620004,
-0x24620008, 0x3c020001, 0x34422ec8, 0x2e21021,
-0x401821, 0x8c620004, 0x21140, 0xa21021,
-0xaf820128, 0xac600000, 0x8ca30018, 0x30620070,
-0x1040002d, 0x30620020, 0x10400004, 0x3c020010,
-0x2c21024, 0x1040000d, 0x0, 0x30620040,
-0x10400004, 0x3c020020, 0x2c21024, 0x10400007,
-0x0, 0x30620010, 0x1040001f, 0x3c020040,
-0x2c21024, 0x1440001c, 0x0, 0x8f820040,
-0x30420001, 0x14400008, 0x2021, 0x8c030104,
-0x24020001, 0x50620005, 0x24040001, 0x8c020264,
-0x10400003, 0x801021, 0x24040001, 0x801021,
-0x10400006, 0x0, 0x8f42030c, 0x24420001,
-0xaf42030c, 0x10000008, 0x8f42030c, 0x8f820044,
-0x34420004, 0xaf820044, 0x8f420308, 0x24420001,
-0xaf420308, 0x8f420308, 0x3e00008, 0x0,
-0x3e00008, 0x0, 0x27bdff98, 0xafbf0060,
-0xafbe005c, 0xafb50058, 0xafb30054, 0xafb20050,
-0xafb1004c, 0xafb00048, 0x8f4200fc, 0x24420001,
-0xaf4200fc, 0x8f880128, 0x25020020, 0xaf820128,
-0x8d030018, 0x30620070, 0x1040002e, 0x30620020,
-0x10400004, 0x3c020010, 0x2c21024, 0x1040000d,
-0x0, 0x30620040, 0x10400004, 0x3c020020,
-0x2c21024, 0x10400007, 0x0, 0x30620010,
-0x104001a9, 0x3c020040, 0x2c21024, 0x144001a6,
-0x0, 0x8f820040, 0x30420001, 0x14400008,
-0x2021, 0x8c030104, 0x24020001, 0x50620005,
-0x24040001, 0x8c020264, 0x10400003, 0x801021,
-0x24040001, 0x801021, 0x10400006, 0x0,
-0x8f42030c, 0x24420001, 0xaf42030c, 0x10000192,
-0x8f42030c, 0x8f820044, 0x34420004, 0xaf820044,
-0x8f420308, 0x24420001, 0xaf420308, 0x1000018a,
-0x8f420308, 0x30620002, 0x1040014b, 0x3c020800,
-0x8d1e001c, 0x1e5702, 0xafaa0034, 0x950a0016,
-0x3c22024, 0xafaa0024, 0x8faa0034, 0x24020001,
-0x15420006, 0x33deffff, 0x1e1140, 0x3403ecc0,
-0x431021, 0x10000010, 0x2e2a821, 0x24020002,
-0x15420005, 0x24020003, 0x1e1140, 0x24426cc0,
-0x10000009, 0x2e2a821, 0x15420005, 0x1e1180,
-0x1e1140, 0x24424cc0, 0x10000003, 0x2e2a821,
-0x571021, 0x24550ce0, 0x96a2000e, 0x304afffc,
-0x30420400, 0x10400003, 0xafaa002c, 0x100000e1,
-0x8821, 0x10800004, 0x8821, 0x97b10026,
-0x100000dd, 0xa6b10012, 0x8eb30018, 0x966a000c,
-0xa7aa003e, 0x97a5003e, 0x2ca305dd, 0x38a28870,
-0x2c420001, 0x621825, 0x10600015, 0x2021,
-0x32c20800, 0x10400015, 0x24020800, 0x96630014,
-0x14620012, 0x3402aaaa, 0x9663000e, 0x14620007,
-0x2821, 0x96630010, 0x24020300, 0x14620004,
-0xa01021, 0x96620012, 0x2c450001, 0xa01021,
-0x54400006, 0x24040016, 0x10000004, 0x0,
-0x24020800, 0x50a20001, 0x2404000e, 0x108000b9,
-0x2649021, 0x92420000, 0x3042000f, 0x28080,
-0x32c20100, 0x10400020, 0x2501821, 0x3c020020,
-0x43102b, 0x1440000e, 0x2402021, 0x2821,
-0x94820000, 0x24840002, 0xa22821, 0x83102b,
-0x1440fffb, 0x30a2ffff, 0x51c02, 0x622821,
-0x51c02, 0x30a2ffff, 0x10000009, 0x622821,
-0x8f470148, 0x8f420110, 0x102842, 0x3c060020,
-0x40f809, 0xafa80040, 0x3045ffff, 0x8fa80040,
-0x50a00001, 0x3405ffff, 0x8faa002c, 0x354a0002,
-0x10000002, 0xafaa002c, 0x2821, 0x32c20080,
-0x10400090, 0xa6a50010, 0x26430009, 0x3c02001f,
-0x3442ffff, 0x43102b, 0x10400003, 0x0,
-0x8f420148, 0x621823, 0x90660000, 0x30c200ff,
-0x38430006, 0x2c630001, 0x38420011, 0x2c420001,
-0x621825, 0x1060007f, 0x24020800, 0x8821,
-0x97a3003e, 0x1462000f, 0x2602021, 0x96710000,
-0x96620002, 0x96630004, 0x96640006, 0x2228821,
-0x2238821, 0x2248821, 0x96620008, 0x9663000a,
-0x9664000c, 0x2228821, 0x2238821, 0x10000007,
-0x2248821, 0x94820000, 0x24840002, 0x2228821,
-0x92102b, 0x1440fffb, 0x0, 0x111c02,
-0x3222ffff, 0x628821, 0x111c02, 0x3222ffff,
-0x628821, 0x32c20200, 0x10400003, 0x26440006,
-0x1000003e, 0x8021, 0x3c05001f, 0x34a5ffff,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x30421fff, 0x10400004,
-0x2644000c, 0x96420002, 0x10000030, 0x508023,
-0x96420002, 0x26430014, 0x508023, 0x3c020020,
-0x43102b, 0x1440000a, 0xd08021, 0x9642000c,
-0x2028021, 0x9642000e, 0x96430010, 0x96440012,
-0x2028021, 0x2038021, 0x10000020, 0x2048021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x24840002, 0x2028021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x24840002, 0x2028021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x24840002, 0x2028021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x2028021, 0x3c020100,
-0x2c21024, 0x1040000e, 0x0, 0x8faa002c,
-0x31420004, 0x1040000a, 0x0, 0x9504000e,
-0x2642021, 0xc003eec, 0x2484fffc, 0x3042ffff,
-0x2228821, 0x111c02, 0x3222ffff, 0x628821,
-0x8faa0024, 0x1518823, 0x111402, 0x2228821,
-0x2308821, 0x111402, 0x2228821, 0x3231ffff,
-0x52200001, 0x3411ffff, 0x8faa002c, 0x354a0001,
-0xafaa002c, 0xa6b10012, 0x97aa002e, 0xa6aa000e,
-0x8faa002c, 0x31420004, 0x10400002, 0x24091000,
-0x34098000, 0x8f480044, 0x8f4401a0, 0x8f4501a4,
-0xafa90010, 0x8f490044, 0x84140, 0x1001821,
-0xafa90014, 0x8f48000c, 0x2a03021, 0x24070020,
-0xafa80018, 0x8f48010c, 0x1021, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x0, 0x8f820128, 0x3c040001,
-0x24846914, 0xafbe0014, 0xafa20010, 0x8f860124,
-0x8f870120, 0x3c050007, 0xc002b3b, 0x34a59920,
-0x8f420368, 0x2442ffff, 0xaf420368, 0x8f420044,
-0x8f430088, 0x24420001, 0x431024, 0xaf420044,
-0x8faa0034, 0x8f440368, 0x24020001, 0x15420006,
-0x24020002, 0x8f42035c, 0x2442ffff, 0xaf42035c,
-0x10000049, 0x8f42035c, 0x15420006, 0x0,
-0x8f420364, 0x2442ffff, 0xaf420364, 0x10000042,
-0x8f420364, 0x8f420360, 0x2442ffff, 0xaf420360,
-0x1000003d, 0x8f420360, 0x30621000, 0x10400005,
-0x30628000, 0x8f420078, 0x24420001, 0x10000036,
-0xaf420078, 0x10400034, 0x0, 0x8f420078,
-0x24420001, 0xaf420078, 0x8c030240, 0x43102b,
-0x1440002d, 0x24070008, 0x8f440168, 0x8f45016c,
-0x8f430044, 0x8f48000c, 0x8f860120, 0x24020040,
-0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c,
-0x40f809, 0x24c6001c, 0x14400011, 0x24020001,
-0x3c010001, 0x370821, 0xa02240f2, 0x8f820124,
-0xafa20010, 0x8f820128, 0x3c040001, 0x2484688c,
-0xafa20014, 0x8f460044, 0x8f870120, 0x3c050009,
-0xc002b3b, 0x34a51300, 0x1000000b, 0x0,
-0x8f420304, 0x24420001, 0xaf420304, 0x8f420304,
-0x8f420044, 0xaf42007c, 0x3c010001, 0x370821,
-0xa02040f2, 0xaf400078, 0x8f420318, 0x24420001,
-0xaf420318, 0x8f420318, 0x8fbf0060, 0x8fbe005c,
-0x8fb50058, 0x8fb30054, 0x8fb20050, 0x8fb1004c,
-0x8fb00048, 0x3e00008, 0x27bd0068, 0x3e00008,
-0x0, 0x0, 0x0, 0x8f42013c,
-0xaf8200c0, 0x8f42013c, 0xaf8200c4, 0x8f42013c,
-0xaf8200c8, 0x8f420138, 0xaf8200d0, 0x8f420138,
-0xaf8200d4, 0x8f420138, 0x3e00008, 0xaf8200d8,
-0x27bdffe0, 0x27840208, 0x24050200, 0xafbf0018,
-0xc002bbf, 0x24060008, 0x8c020204, 0xc004012,
-0xaf820210, 0x3c020001, 0x8c426d94, 0x30420002,
-0x1040000e, 0x2021, 0x8c060248, 0x24020002,
-0x3c010001, 0xac226d98, 0xc005104, 0x24050002,
-0x2021, 0x8c060248, 0x24020001, 0x3c010001,
-0xac226d98, 0x10000011, 0x24050001, 0x8c060248,
-0x24020004, 0x3c010001, 0xac226d98, 0xc005104,
-0x24050004, 0x3c020001, 0x8c426d94, 0x30420001,
-0x10400008, 0x24020001, 0x3c010001, 0xac226d98,
-0x2021, 0x24050001, 0x3c06601b, 0xc005104,
-0x0, 0x3c040001, 0x248469d0, 0x8f420150,
-0x8f430154, 0x3c050008, 0x8f460158, 0x21640,
-0x31940, 0x34630403, 0x431025, 0x633c0,
-0x461025, 0xaf82021c, 0xafa00010, 0xafa00014,
-0x8f86021c, 0x34a50200, 0xc002b3b, 0x3821,
-0x3c010001, 0xac206d90, 0x3c010001, 0xac206da8,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0,
-0x3c050008, 0x34a50300, 0xafbf0018, 0xafa00010,
-0xafa00014, 0x8f860200, 0x3c040001, 0x248469dc,
-0xc002b3b, 0x3821, 0x8f420410, 0x24420001,
-0xaf420410, 0x8f420410, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x27bdffd8, 0xafbf0020, 0xafb1001c,
-0xafb00018, 0x8f4203a4, 0x24420001, 0xaf4203a4,
-0x8f4203a4, 0x8f900220, 0x8f8200e0, 0xafa20010,
-0x8f8200e4, 0xafa20014, 0x8f8600c4, 0x8f8700c8,
-0x3c040001, 0x248469e8, 0xc002b3b, 0x2002821,
-0x3c044000, 0x2041024, 0x504000b4, 0x3c040100,
-0x8f4203bc, 0x24420001, 0xaf4203bc, 0x8f4203bc,
-0x8f8700c4, 0x8f8300c8, 0x8f420148, 0x671823,
-0x43102b, 0x10400003, 0x0, 0x8f420148,
-0x621821, 0x10600005, 0x0, 0x8f42014c,
-0x43102b, 0x1040000b, 0x0, 0x8f8200e0,
-0x8f430124, 0xaf42011c, 0xaf430114, 0x8f820220,
-0x3c0308ff, 0x3463fffb, 0x431024, 0x100000ce,
-0x441025, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x34420004, 0xaf820220, 0x8f8200e0,
-0x8f430124, 0xaf42011c, 0xaf430114, 0x8f8600c8,
-0x8f840120, 0x8f830124, 0x10000005, 0x2821,
-0x14620002, 0x24620020, 0x27624800, 0x401821,
-0x1064000c, 0x30a200ff, 0x8c620018, 0x30420003,
-0x1040fff7, 0x27624fe0, 0x8f4203d0, 0x24050001,
-0x24420001, 0xaf4203d0, 0x8f4203d0, 0x8c660008,
-0x30a200ff, 0x14400058, 0x0, 0x934205c4,
-0x14400055, 0x0, 0x8f8700c4, 0x8f8800e0,
-0x8f8400e4, 0x2402fff8, 0x1024024, 0x1041023,
-0x218c3, 0x4620001, 0x24630200, 0x10600005,
-0x24020001, 0x10620009, 0x0, 0x1000001f,
-0x0, 0x8f4203c0, 0xe03021, 0x24420001,
-0xaf4203c0, 0x10000040, 0x8f4203c0, 0x8f4203c4,
-0x24420001, 0xaf4203c4, 0x8c860000, 0x8f420148,
-0x8f4303c4, 0xe61823, 0x43102b, 0x10400004,
-0x2c62233f, 0x8f420148, 0x621821, 0x2c62233f,
-0x14400031, 0x0, 0x8f42020c, 0x24420001,
-0xaf42020c, 0x8f42020c, 0xe03021, 0x24820008,
-0xaf8200e4, 0x10000028, 0xaf8200e8, 0x8f4203c8,
-0x24420001, 0xaf4203c8, 0x8f4203c8, 0x8c850000,
-0x8f420148, 0xa71823, 0x43102b, 0x10400003,
-0x0, 0x8f420148, 0x621821, 0x8f42014c,
-0x43102b, 0x5440000a, 0xa03021, 0x8f42020c,
-0x24420001, 0xaf42020c, 0x8f42020c, 0x24820008,
-0xaf8200e4, 0x8f8400e4, 0x1488ffec, 0xaf8400e8,
-0x1488000d, 0x27623000, 0x14820002, 0x2482fff8,
-0x27623ff8, 0x94430006, 0x3c02001f, 0x3442ffff,
-0xc33021, 0x46102b, 0x10400003, 0x0,
-0x8f420148, 0xc23023, 0xaf8600c8, 0x8f8300c4,
-0x8f420148, 0xc31823, 0x43102b, 0x10400003,
-0x0, 0x8f420148, 0x621821, 0x10600005,
-0x0, 0x8f42014c, 0x43102b, 0x50400008,
-0x3c02fdff, 0x8f820220, 0x3c0308ff, 0x3463fffb,
-0x431024, 0x3c034000, 0x1000003f, 0x431025,
-0x8f4303cc, 0x3442ffff, 0x282a024, 0x24630001,
-0xaf4303cc, 0x10000039, 0x8f4203cc, 0x2041024,
-0x1040000e, 0x3c110200, 0x8f4203a8, 0x24420001,
-0xaf4203a8, 0x8f4203a8, 0x8f820220, 0x3c0308ff,
-0x3463ffff, 0x431024, 0x441025, 0xc003daf,
-0xaf820220, 0x10000029, 0x0, 0x2111024,
-0x50400008, 0x3c110400, 0x8f4203ac, 0x24420001,
-0xaf4203ac, 0xc003daf, 0x8f4203ac, 0x10000019,
-0x0, 0x2111024, 0x1040001c, 0x0,
-0x8f830224, 0x24021402, 0x14620009, 0x3c050008,
-0x3c040001, 0x248469f4, 0xafa00010, 0xafa00014,
-0x8f860224, 0x34a50500, 0xc002b3b, 0x3821,
-0x8f4203b0, 0x24420001, 0xaf4203b0, 0x8f4203b0,
-0x8f820220, 0x2002021, 0x34420002, 0xc004e9c,
-0xaf820220, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x511025, 0xaf820220, 0x8fbf0020,
-0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0028,
-0x3e00008, 0x0, 0x3c020001, 0x8c426da8,
-0x27bdffb0, 0xafbf0048, 0xafbe0044, 0xafb50040,
-0xafb3003c, 0xafb20038, 0xafb10034, 0x1040000f,
-0xafb00030, 0x3c040001, 0x24846a00, 0x3c050008,
-0xafa00010, 0xafa00014, 0x8f860220, 0x34a50600,
-0x24020001, 0x3c010001, 0xac206da8, 0x3c010001,
-0xac226d9c, 0xc002b3b, 0x3821, 0x3c037fff,
-0x8c020268, 0x3463ffff, 0x3c04fdff, 0x431024,
-0xac020268, 0x8f420004, 0x3484ffff, 0x30420002,
-0x10400092, 0x284a024, 0x3c040600, 0x34842000,
-0x8f420004, 0x2821, 0x2403fffd, 0x431024,
-0xaf420004, 0xafa40020, 0x8f5e0018, 0x27aa0020,
-0x240200ff, 0x13c20002, 0xafaa002c, 0x27c50001,
-0x8c020228, 0xa09021, 0x1642000e, 0x1e38c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x24846998, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006d,
-0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b,
-0x9821, 0xe08821, 0x263504c0, 0x8f440178,
-0x8f45017c, 0x2201821, 0x240a0004, 0xafaa0010,
-0xafb20014, 0x8f48000c, 0x1021, 0x2f53021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x54400006, 0x24130001, 0x8f820054, 0x2021023,
-0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff,
-0x54400017, 0xaf520018, 0x8f420378, 0x24420001,
-0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x248469a4,
-0x3c050009, 0xafa20014, 0x8d460000, 0x10000035,
-0x34a50600, 0x8f420308, 0x24130001, 0x24420001,
-0xaf420308, 0x8f420308, 0x1000001e, 0x326200ff,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x10400016, 0x9821, 0x3c150020,
-0x24110010, 0x8f42000c, 0x8f440160, 0x8f450164,
-0x8f860120, 0xafb10010, 0xafb20014, 0x551025,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe3, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffee, 0x0,
-0x326200ff, 0x14400011, 0x0, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x248469ac, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202ec,
-0x24420001, 0xaf4202ec, 0x8f4202ec, 0x8fbf0048,
-0x8fbe0044, 0x8fb50040, 0x8fb3003c, 0x8fb20038,
-0x8fb10034, 0x8fb00030, 0x3e00008, 0x27bd0050,
-0x3c020001, 0x8c426da8, 0x27bdffe0, 0x1440000d,
-0xafbf0018, 0x3c040001, 0x24846a0c, 0x3c050008,
-0xafa00010, 0xafa00014, 0x8f860220, 0x34a50700,
-0x24020001, 0x3c010001, 0xac226da8, 0xc002b3b,
-0x3821, 0x3c020004, 0x2c21024, 0x10400007,
-0x0, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x34420008, 0xaf820220, 0x3c050001,
-0x8ca56d98, 0x24020001, 0x14a20007, 0x2021,
-0xc00529b, 0x24050001, 0xac02026c, 0x8c03026c,
-0x10000006, 0x3c020007, 0xc00529b, 0x2021,
-0xac020268, 0x8c030268, 0x3c020007, 0x621824,
-0x3c020002, 0x5062000d, 0x3c0205f5, 0x43102b,
-0x14400006, 0x3c020004, 0x3c020001, 0x10620009,
-0x3c020098, 0x1000000b, 0x0, 0x14620009,
-0x3c023b9a, 0x10000004, 0x3442ca00, 0x10000002,
-0x3442e100, 0x34429680, 0xaf4201fc, 0x8f4201fc,
-0xaee20064, 0x8fbf0018, 0x3e00008, 0x27bd0020,
-0x0, 0x0, 0x0, 0x86102b,
-0x50400001, 0x872023, 0xc41023, 0x24843,
-0x125102b, 0x1040001b, 0x91040, 0x824021,
-0x88102b, 0x10400007, 0x1821, 0x94820000,
-0x24840002, 0x621821, 0x88102b, 0x1440fffb,
-0x0, 0x602021, 0xc73023, 0xa91023,
-0x21040, 0xc22821, 0xc5102b, 0x10400007,
-0x1821, 0x94c20000, 0x24c60002, 0x621821,
-0xc5102b, 0x1440fffb, 0x0, 0x1000000d,
-0x832021, 0x51040, 0x822821, 0x85102b,
-0x10400007, 0x1821, 0x94820000, 0x24840002,
-0x621821, 0x85102b, 0x1440fffb, 0x0,
-0x602021, 0x41c02, 0x3082ffff, 0x622021,
-0x41c02, 0x3082ffff, 0x622021, 0x3e00008,
-0x3082ffff, 0x3e00008, 0x0, 0x802821,
-0x30a20001, 0x1040002b, 0x3c03001f, 0x3463ffff,
-0x24a20004, 0x62102b, 0x54400007, 0x65102b,
-0x90a20001, 0x90a40003, 0x90a30000, 0x90a50002,
-0x1000002a, 0x441021, 0x10400003, 0x0,
-0x8f420148, 0xa22823, 0x90a40000, 0x24a50001,
-0x65102b, 0x10400003, 0x0, 0x8f420148,
-0xa22823, 0x90a20000, 0x24a50001, 0x21200,
-0x822021, 0x65102b, 0x10400003, 0x0,
-0x8f420148, 0xa22823, 0x90a20000, 0x24a50001,
-0x822021, 0x65102b, 0x10400003, 0x0,
-0x8f420148, 0xa22823, 0x90a20000, 0x1000002d,
-0x21200, 0x3463ffff, 0x24a20004, 0x62102b,
-0x5440000a, 0x65102b, 0x90a20000, 0x90a40002,
-0x90a30001, 0x90a50003, 0x441021, 0x21200,
-0x651821, 0x10000020, 0x432021, 0x10400003,
-0x0, 0x8f420148, 0xa22823, 0x90a20000,
-0x24a50001, 0x22200, 0x65102b, 0x10400003,
-0x0, 0x8f420148, 0xa22823, 0x90a20000,
-0x24a50001, 0x822021, 0x65102b, 0x10400003,
-0x0, 0x8f420148, 0xa22823, 0x90a20000,
-0x24a50001, 0x21200, 0x822021, 0x65102b,
-0x10400003, 0x0, 0x8f420148, 0xa22823,
-0x90a20000, 0x822021, 0x41c02, 0x3082ffff,
-0x622021, 0x41c02, 0x3082ffff, 0x622021,
-0x3e00008, 0x3082ffff, 0x0, 0x8f820220,
-0x34420002, 0xaf820220, 0x3c020002, 0x8c428ff8,
-0x30424000, 0x10400054, 0x24040001, 0x8f820200,
-0x24067fff, 0x8f830200, 0x30450002, 0x2402fffd,
-0x621824, 0xaf830200, 0xaf840204, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x8f820224, 0x1444004d, 0x42040, 0xc4102b,
-0x1040fff1, 0x0, 0x8f820200, 0x451025,
-0xaf820200, 0x8f820220, 0x34428000, 0xaf820220,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820220, 0x3c030004, 0x431024,
-0x1440000f, 0x0, 0x8f820220, 0x3c03ffff,
-0x34637fff, 0x431024, 0xaf820220, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x8f820220, 0x3c030004, 0x431024, 0x1440000d,
-0x0, 0x8f820220, 0x34428000, 0xaf820220,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820220, 0x3c030004, 0x431024,
-0x1040001b, 0x1021, 0x8f830220, 0x24020001,
-0x10000015, 0x3c04f700, 0x8f820220, 0x3c04f700,
-0x441025, 0xaf820220, 0x8f820220, 0x2403fffd,
-0x431024, 0xaf820220, 0x8f820220, 0x3c030300,
-0x431024, 0x14400003, 0x0, 0x10000008,
-0x1021, 0x8f820220, 0x34420002, 0xaf820220,
-0x8f830220, 0x24020001, 0x641825, 0xaf830220,
-0x3e00008, 0x0, 0x2021, 0x3c050100,
-0x24020001, 0xaf80021c, 0xaf820200, 0xaf820220,
-0x27625000, 0xaf8200c0, 0x27625000, 0xaf8200c4,
-0x27625000, 0xaf8200c8, 0x27625000, 0xaf8200d0,
-0x27625000, 0xaf8200d4, 0x27625000, 0xaf8200d8,
-0x27623000, 0xaf8200e0, 0x27623000, 0xaf8200e4,
-0x27623000, 0xaf8200e8, 0x27622800, 0xaf8200f0,
-0x27622800, 0xaf8200f4, 0x27622800, 0xaf8200f8,
-0x418c0, 0x24840001, 0x3631021, 0xac453004,
-0x3631021, 0xac403000, 0x28820200, 0x1440fff9,
-0x418c0, 0x2021, 0x418c0, 0x24840001,
-0x3631021, 0xac402804, 0x3631021, 0xac402800,
-0x28820100, 0x1440fff9, 0x418c0, 0xaf80023c,
-0x24030080, 0x24040100, 0xac600000, 0x24630004,
-0x64102b, 0x5440fffd, 0xac600000, 0x8f830040,
-0x3c02f000, 0x621824, 0x3c025000, 0x1062000c,
-0x43102b, 0x14400006, 0x3c026000, 0x3c024000,
-0x10620008, 0x24020800, 0x10000008, 0x0,
-0x10620004, 0x24020800, 0x10000004, 0x0,
-0x24020700, 0x3c010001, 0xac226dac, 0x3e00008,
-0x0, 0x3c020001, 0x8c426dbc, 0x27bdffd0,
-0xafbf002c, 0xafb20028, 0xafb10024, 0xafb00020,
-0x3c010001, 0x10400005, 0xac206d94, 0xc004d9e,
-0x0, 0x3c010001, 0xac206dbc, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0xc004db9, 0x0, 0x24040001, 0x2821,
-0x27a60018, 0x34028000, 0xc0045be, 0xa7a20018,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x3c060001, 0x24c66f24, 0xc00457c,
-0x24050002, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630064, 0x8f820054, 0x621023, 0x2c420065,
-0x1440fffc, 0x24040001, 0x24050003, 0x3c100001,
-0x26106f26, 0xc00457c, 0x2003021, 0x97a60018,
-0x3c070001, 0x94e76f24, 0x3c040001, 0x24846ae0,
-0xafa00014, 0x96020000, 0x3c05000d, 0x34a50100,
-0xc002b3b, 0xafa20010, 0x97a20018, 0x1040004d,
-0x24036040, 0x96020000, 0x3042fff0, 0x1443000c,
-0x24020020, 0x3c030001, 0x94636f24, 0x1462000b,
-0x24027830, 0x24020003, 0x3c010001, 0xac226d94,
-0x24020005, 0x3c010001, 0x1000003f, 0xac226f34,
-0x3c030001, 0x94636f24, 0x24027830, 0x1462000c,
-0x24030010, 0x3c020001, 0x94426f26, 0x3042fff0,
-0x14430007, 0x24020003, 0x3c010001, 0xac226d94,
-0x24020006, 0x3c010001, 0x1000002f, 0xac226f34,
-0x3c020001, 0x8c426d94, 0x3c030001, 0x94636f24,
-0x34420001, 0x3c010001, 0xac226d94, 0x24020015,
-0x1462000b, 0x0, 0x3c020001, 0x94426f26,
-0x3042fff0, 0x3843f420, 0x2c630001, 0x3842f430,
-0x2c420001, 0x621825, 0x1460001b, 0x24020003,
-0x3c030001, 0x94636f24, 0x24027810, 0x14620016,
-0x24020002, 0x3c020001, 0x94426f26, 0x3042fff0,
-0x14400011, 0x24020002, 0x1000000f, 0x24020004,
-0x3c020001, 0x8c426d94, 0x34420008, 0x3c010001,
-0xac226d94, 0x1000005e, 0x24020004, 0x3c020001,
-0x8c426d94, 0x34420004, 0x3c010001, 0x100000af,
-0xac226d94, 0x24020001, 0x3c010001, 0xac226f40,
-0x3c020001, 0x8c426d94, 0x30420002, 0x144000b2,
-0x3c09fff0, 0x24020e00, 0xaf820238, 0x8f840054,
-0x8f820054, 0x24030008, 0x3c010001, 0xac236d98,
-0x10000002, 0x248401f4, 0x8f820054, 0x821023,
-0x2c4201f5, 0x1440fffc, 0x3c0200c8, 0x344201fb,
-0xaf820238, 0x8f830054, 0x8f820054, 0x10000002,
-0x246301f4, 0x8f820054, 0x621023, 0x2c4201f5,
-0x1440fffc, 0x8021, 0x24120001, 0x24110009,
-0xc004482, 0x0, 0x3c010001, 0xac326db4,
-0xc004547, 0x0, 0x3c020001, 0x8c426db4,
-0x1451fffb, 0x3c0200c8, 0x344201f6, 0xaf820238,
-0x8f830054, 0x8f820054, 0x10000002, 0x2463000a,
-0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc,
-0x0, 0x8f820220, 0x24040001, 0x34420002,
-0xaf820220, 0x8f830200, 0x24057fff, 0x2402fffd,
-0x621824, 0xaf830200, 0xaf840204, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x8f820224, 0x14440005, 0x34028000, 0x42040,
-0xa4102b, 0x1040fff0, 0x34028000, 0x1082ffa0,
-0x26100001, 0x2e020014, 0x1440ffcd, 0x24020004,
-0x3c010001, 0xac226d98, 0x8021, 0x24120009,
-0x3c11ffff, 0x36313f7f, 0xc004482, 0x0,
-0x24020001, 0x3c010001, 0xac226db4, 0xc004547,
-0x0, 0x3c020001, 0x8c426db4, 0x1452fffb,
-0x0, 0x8f820044, 0x511024, 0x34425080,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x2463000a, 0x8f820054, 0x621023, 0x2c42000b,
-0x1440fffc, 0x0, 0x8f820044, 0x511024,
-0x3442f080, 0xaf820044, 0x8f830054, 0x8f820054,
-0x10000002, 0x2463000a, 0x8f820054, 0x621023,
-0x2c42000b, 0x1440fffc, 0x0, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0x8f820220, 0x24040001, 0x34420002, 0xaf820220,
-0x8f830200, 0x24057fff, 0x2402fffd, 0x621824,
-0xaf830200, 0xaf840204, 0x8f830054, 0x8f820054,
-0x10000002, 0x24630001, 0x8f820054, 0x621023,
-0x2c420002, 0x1440fffc, 0x0, 0x8f820224,
-0x14440005, 0x34028000, 0x42040, 0xa4102b,
-0x1040fff0, 0x34028000, 0x1082ff50, 0x26100001,
-0x2e020064, 0x1440ffb0, 0x0, 0x3c020001,
-0x8c426d94, 0x30420004, 0x14400007, 0x3c09fff0,
-0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024,
-0xaf820044, 0x3c09fff0, 0x3529bdc0, 0x3c060001,
-0x8cc66d94, 0x3c040001, 0x24846ae0, 0x24020001,
-0x3c010001, 0xac226d9c, 0x8f820054, 0x3c070001,
-0x8ce76f40, 0x3c030001, 0x94636f24, 0x3c080001,
-0x95086f26, 0x3c05000d, 0x34a50100, 0x3c010001,
-0xac206d98, 0x491021, 0x3c010001, 0xac226f30,
-0xafa30010, 0xc002b3b, 0xafa80014, 0x8fbf002c,
-0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
-0x27bd0030, 0x27bdffe8, 0x3c050001, 0x8ca56d98,
-0x24060004, 0x24020001, 0x14a20014, 0xafbf0010,
-0x3c020002, 0x8c428ffc, 0x30428000, 0x10400005,
-0x3c04000f, 0x3c030001, 0x8c636f40, 0x10000005,
-0x34844240, 0x3c040004, 0x3c030001, 0x8c636f40,
-0x348493e0, 0x24020005, 0x14620016, 0x0,
-0x3c04003d, 0x10000013, 0x34840900, 0x3c020002,
-0x8c428ff8, 0x30428000, 0x10400005, 0x3c04001e,
-0x3c030001, 0x8c636f40, 0x10000005, 0x34848480,
-0x3c04000f, 0x3c030001, 0x8c636f40, 0x34844240,
-0x24020005, 0x14620003, 0x0, 0x3c04007a,
-0x34841200, 0x3c020001, 0x8c426f30, 0x8f830054,
-0x441021, 0x431023, 0x44102b, 0x1440004c,
-0x0, 0x3c020001, 0x8c426da0, 0x14400048,
-0x0, 0x3c010001, 0x10c00025, 0xac206db0,
-0x3c090001, 0x8d296d94, 0x24070001, 0x3c044000,
-0x3c080002, 0x25088ffc, 0x250afffc, 0x52842,
-0x14a00002, 0x24c6ffff, 0x24050008, 0xa91024,
-0x10400010, 0x0, 0x14a70008, 0x0,
-0x8d020000, 0x441024, 0x1040000a, 0x0,
-0x3c010001, 0x10000007, 0xac256db0, 0x8d420000,
-0x441024, 0x10400003, 0x0, 0x3c010001,
-0xac276db0, 0x3c020001, 0x8c426db0, 0x6182b,
-0x2c420001, 0x431024, 0x5440ffe5, 0x52842,
-0x8f820054, 0x3c030001, 0x8c636db0, 0x3c010001,
-0xac226f30, 0x1060003b, 0x24020005, 0x3c030001,
-0x8c636f40, 0x3c010001, 0xac256d98, 0x14620012,
-0x24020001, 0x3c020002, 0x8c428ff8, 0x3c032000,
-0x34635000, 0x431024, 0x14400006, 0x24020001,
-0x3c010001, 0xac206f1c, 0x3c010001, 0xac226d98,
-0x24020001, 0x3c010001, 0xac226e24, 0x3c010001,
-0xac226da4, 0x24020001, 0x3c010001, 0xac226d9c,
-0x3c020001, 0x8c426db0, 0x1040001e, 0x0,
-0x3c020001, 0x8c426d9c, 0x10400008, 0x24020001,
-0x3c010001, 0xac206d9c, 0xaee204b8, 0x3c010001,
-0xac206e1c, 0x3c010001, 0xac226dd4, 0x8ee304b8,
-0x24020008, 0x10620005, 0x24020001, 0xc004239,
-0x0, 0x1000000b, 0x0, 0x3c030001,
-0x8c636d98, 0x10620007, 0x2402000e, 0x3c030002,
-0x8c638f90, 0x10620003, 0x0, 0xc004e9c,
-0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018,
-0x27bdffe0, 0x3c03fdff, 0x3c040001, 0x8c846d98,
-0x3c020001, 0x8c426dc0, 0x3463ffff, 0x283a024,
-0x14820006, 0xafbf0018, 0x8ee304b8, 0x3c020001,
-0x8c426dc4, 0x10620006, 0x0, 0x8ee204b8,
-0x3c010001, 0xac246dc0, 0x3c010001, 0xac226dc4,
-0x3c030001, 0x8c636d98, 0x24020002, 0x1062019c,
-0x2c620003, 0x10400005, 0x24020001, 0x1062000a,
-0x0, 0x10000226, 0x0, 0x24020004,
-0x106200b6, 0x24020008, 0x1062010a, 0x24020001,
-0x1000021f, 0x0, 0x8ee204b8, 0x2443ffff,
-0x2c620008, 0x1040021c, 0x31080, 0x3c010001,
-0x220821, 0x8c226af8, 0x400008, 0x0,
-0x3c030001, 0x8c636f40, 0x24020005, 0x14620010,
-0x0, 0x3c020001, 0x8c426da4, 0x10400008,
-0x24020003, 0xc004482, 0x0, 0x24020002,
-0xaee204b8, 0x3c010001, 0x10000002, 0xac206da4,
-0xaee204b8, 0x3c010001, 0x10000203, 0xac206d30,
-0xc004482, 0x0, 0x3c020001, 0x8c426da4,
-0x3c010001, 0xac206d30, 0x1440017a, 0x24020002,
-0x1000019d, 0x24020007, 0x3c030001, 0x8c636f40,
-0x24020005, 0x14620003, 0x24020001, 0x3c010001,
-0xac226dd0, 0xc0045ff, 0x0, 0x3c030001,
-0x8c636dd0, 0x10000174, 0x24020011, 0x3c050001,
-0x8ca56d98, 0x3c060002, 0x8cc68ffc, 0xc005104,
-0x2021, 0x24020005, 0x3c010001, 0xac206da4,
-0x100001e1, 0xaee204b8, 0x3c040001, 0x24846aec,
-0x3c05000f, 0x34a50100, 0x3021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x100001d6,
-0x0, 0x8f820220, 0x3c030004, 0x431024,
-0x14400175, 0x24020007, 0x8f830054, 0x3c020001,
-0x8c426f28, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400003, 0x24020001, 0x3c010001, 0xac226d9c,
-0x3c020002, 0x8c428ffc, 0x30425000, 0x104001c2,
-0x0, 0x8f820220, 0x30428000, 0x1040017d,
-0x0, 0x10000175, 0x0, 0x3c050001,
-0x8ca56d98, 0xc00529b, 0x2021, 0xc00551b,
-0x2021, 0x3c030002, 0x8c638ff4, 0x46101b0,
-0x24020001, 0x3c020008, 0x621024, 0x10400006,
-0x0, 0x8f820214, 0x3c03ffff, 0x431024,
-0x10000005, 0x3442251f, 0x8f820214, 0x3c03ffff,
-0x431024, 0x3442241f, 0xaf820214, 0x8f820220,
-0x3c030200, 0x34420002, 0xaf820220, 0x24020008,
-0xaee204b8, 0x8f820220, 0x283a025, 0x3c030004,
-0x431024, 0x14400016, 0x0, 0x3c020002,
-0x8c428ffc, 0x30425000, 0x1040000d, 0x0,
-0x8f820220, 0x30428000, 0x10400006, 0x0,
-0x8f820220, 0x3c03ffff, 0x34637fff, 0x10000003,
-0x431024, 0x8f820220, 0x34428000, 0xaf820220,
-0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0x3c030001, 0x8c636f40, 0x24020005, 0x1462000a,
-0x0, 0x3c020001, 0x94426f26, 0x24429fbc,
-0x2c420004, 0x10400004, 0x24040018, 0x24050002,
-0xc004ddb, 0x24060020, 0xc003e6d, 0x0,
-0x3c010001, 0x10000170, 0xac206e20, 0x8ee204b8,
-0x2443ffff, 0x2c620008, 0x1040016b, 0x31080,
-0x3c010001, 0x220821, 0x8c226b18, 0x400008,
-0x0, 0xc004547, 0x0, 0x3c030001,
-0x8c636db4, 0x100000e8, 0x24020009, 0x3c020002,
-0x8c428ff8, 0x30424000, 0x10400004, 0x0,
-0x8f820044, 0x10000006, 0x3442f080, 0x8f820044,
-0x3c03ffff, 0x34633f7f, 0x431024, 0x3442a080,
-0xaf820044, 0x8f830054, 0x100000ea, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400147, 0x24020005,
-0x100000d8, 0x0, 0x8f820220, 0x3c03f700,
-0x431025, 0xaf820220, 0xaf800204, 0x3c010002,
-0x100000d6, 0xac208fe0, 0x8f830054, 0x3c020001,
-0x8c426f28, 0x2463fff6, 0x431023, 0x2c42000a,
-0x14400135, 0x24020007, 0x100000d7, 0x0,
-0xc003f50, 0x0, 0x1040012d, 0x24020001,
-0x8f820214, 0x3c03ffff, 0x3c040001, 0x8c846f1c,
-0x431024, 0x3442251f, 0xaf820214, 0x24020008,
-0x10800005, 0xaee204b8, 0x3c020001, 0x8c426e44,
-0x10400064, 0x24020001, 0x8f820220, 0x3c030008,
-0x431024, 0x1040006a, 0x3c020200, 0x10000078,
-0x0, 0x8ee204b8, 0x2443ffff, 0x2c620007,
-0x10400115, 0x31080, 0x3c010001, 0x220821,
-0x8c226b38, 0x400008, 0x0, 0xc003daf,
-0x0, 0x3c010001, 0xac206d9c, 0xaf800204,
-0x3c010002, 0xc004482, 0xac208fe0, 0x24020001,
-0x3c010001, 0xac226db4, 0x24020002, 0x10000102,
-0xaee204b8, 0xc004547, 0x0, 0x3c030001,
-0x8c636db4, 0x10000084, 0x24020009, 0x3c020002,
-0x8c428ff8, 0x30424000, 0x10400003, 0x3c0200c8,
-0x10000002, 0x344201f6, 0x344201fe, 0xaf820238,
-0x8f830054, 0x1000008b, 0x24020004, 0x8f830054,
-0x3c020001, 0x8c426f28, 0x2463d8f0, 0x431023,
-0x2c422710, 0x144000e8, 0x24020005, 0x10000079,
-0x0, 0x8f820220, 0x3c03f700, 0x431025,
-0xaf820220, 0xaf800204, 0x3c010002, 0x10000077,
-0xac208fe0, 0x8f830054, 0x3c020001, 0x8c426f28,
-0x2463fff6, 0x431023, 0x2c42000a, 0x144000d6,
-0x24020007, 0x10000078, 0x0, 0xc003f50,
-0x0, 0x104000ce, 0x24020001, 0x8f820214,
-0x3c03ffff, 0x3c040001, 0x8c846f1c, 0x431024,
-0x3442251f, 0xaf820214, 0x24020008, 0x1080000f,
-0xaee204b8, 0x3c020001, 0x8c426e44, 0x1440000b,
-0x0, 0x8f820220, 0x34420002, 0xaf820220,
-0x24020001, 0x3c010002, 0xac228f90, 0xc004e9c,
-0x8f840220, 0x10000016, 0x0, 0x8f820220,
-0x3c030008, 0x431024, 0x14400011, 0x3c020200,
-0x282a025, 0x2402000e, 0x3c010002, 0xac228f90,
-0xc00551b, 0x2021, 0x8f820220, 0x34420002,
-0xc003e6d, 0xaf820220, 0x3c050001, 0x8ca56d98,
-0xc00529b, 0x2021, 0x100000a3, 0x0,
-0x3c020001, 0x8c426e44, 0x1040009f, 0x0,
-0x3c020001, 0x8c426e40, 0x2442ffff, 0x3c010001,
-0xac226e40, 0x14400098, 0x24020002, 0x3c010001,
-0xac206e44, 0x3c010001, 0x10000093, 0xac226e40,
-0x8ee204b8, 0x2443ffff, 0x2c620007, 0x1040008e,
-0x31080, 0x3c010001, 0x220821, 0x8c226b58,
-0x400008, 0x0, 0x3c020001, 0x8c426da4,
-0x10400018, 0x24020005, 0xc004482, 0x0,
-0x24020002, 0xaee204b8, 0x3c010001, 0x1000007e,
-0xac206da4, 0xc004963, 0x0, 0x3c030001,
-0x8c636dd4, 0x24020006, 0x14620077, 0x24020003,
-0x10000075, 0xaee204b8, 0x3c050001, 0x8ca56d98,
-0x3c060002, 0x8cc68ff8, 0xc005104, 0x2021,
-0x24020005, 0x1000006c, 0xaee204b8, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0x8f830054,
-0x24020006, 0xaee204b8, 0x3c010001, 0x10000062,
-0xac236f28, 0x8f820220, 0x3c030004, 0x431024,
-0x10400003, 0x24020007, 0x1000005b, 0xaee204b8,
-0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400003, 0x24020001,
-0x3c010001, 0xac226d9c, 0x3c020002, 0x8c428ff8,
-0x30425000, 0x1040004c, 0x0, 0x8f820220,
-0x30428000, 0x10400007, 0x0, 0x8f820220,
-0x3c03ffff, 0x34637fff, 0x431024, 0x10000042,
-0xaf820220, 0x8f820220, 0x34428000, 0x1000003e,
-0xaf820220, 0x3c050001, 0x8ca56d98, 0xc00529b,
-0x2021, 0xc00551b, 0x2021, 0x3c020002,
-0x8c428ff0, 0x4410032, 0x24020001, 0x8f820214,
-0x3c03ffff, 0x431024, 0x3442251f, 0xaf820214,
-0x24020008, 0xaee204b8, 0x8f820220, 0x34420002,
-0xaf820220, 0x8f820220, 0x3c030004, 0x431024,
-0x14400016, 0x0, 0x3c020002, 0x8c428ff8,
-0x30425000, 0x1040000d, 0x0, 0x8f820220,
-0x30428000, 0x10400006, 0x0, 0x8f820220,
-0x3c03ffff, 0x34637fff, 0x10000003, 0x431024,
-0x8f820220, 0x34428000, 0xaf820220, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0x3c020001,
-0x94426f26, 0x24429fbc, 0x2c420004, 0x10400004,
-0x24040018, 0x24050002, 0xc004ddb, 0x24060020,
-0xc003e6d, 0x0, 0x10000003, 0x0,
-0x3c010001, 0xac226d9c, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220,
-0x34420004, 0xaf820220, 0x8f820200, 0x3c050001,
-0x8ca56d98, 0x34420004, 0xaf820200, 0x24020002,
-0x10a2004b, 0x2ca20003, 0x10400005, 0x24020001,
-0x10a2000a, 0x0, 0x100000b1, 0x0,
-0x24020004, 0x10a20072, 0x24020008, 0x10a20085,
-0x3c02f0ff, 0x100000aa, 0x0, 0x8f830050,
-0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c846f40,
-0x621824, 0x3c020700, 0x621825, 0x24020e00,
-0x2484fffb, 0x2c840002, 0xaf830050, 0xaf850200,
-0xaf850220, 0x14800006, 0xaf820238, 0x8f820044,
-0x3c03ffff, 0x34633f7f, 0x431024, 0xaf820044,
-0x3c030001, 0x8c636f40, 0x24020005, 0x14620004,
-0x0, 0x8f820044, 0x34425000, 0xaf820044,
-0x3c020001, 0x8c426d88, 0x3c030001, 0x8c636f40,
-0x34420022, 0x2463fffc, 0x2c630002, 0x1460000c,
-0xaf820200, 0x3c020001, 0x8c426dac, 0x3c030001,
-0x8c636d90, 0x3c040001, 0x8c846d8c, 0x34428000,
-0x621825, 0x641825, 0x1000000a, 0x34620002,
-0x3c020001, 0x8c426d90, 0x3c030001, 0x8c636dac,
-0x3c040001, 0x8c846d8c, 0x431025, 0x441025,
-0x34420002, 0xaf820220, 0x1000002f, 0x24020001,
-0x24020e01, 0xaf820238, 0x8f830050, 0x3c02f0ff,
-0x3442ffff, 0x3c040001, 0x8c846f1c, 0x621824,
-0x3c020d00, 0x621825, 0x24020001, 0xaf830050,
-0xaf820200, 0xaf820220, 0x10800005, 0x3c033f00,
-0x3c020001, 0x8c426d80, 0x10000004, 0x34630070,
-0x3c020001, 0x8c426d80, 0x34630072, 0x431025,
-0xaf820200, 0x3c030001, 0x8c636d84, 0x3c02f700,
-0x621825, 0x3c020001, 0x8c426d90, 0x3c040001,
-0x8c846dac, 0x3c050001, 0x8ca56f40, 0x431025,
-0x441025, 0xaf820220, 0x24020005, 0x14a20006,
-0x24020001, 0x8f820044, 0x2403afff, 0x431024,
-0xaf820044, 0x24020001, 0x1000003d, 0xaf820238,
-0x8f830050, 0x3c02f0ff, 0x3442ffff, 0x3c040001,
-0x8c846f1c, 0x621824, 0x3c020a00, 0x621825,
-0x24020001, 0xaf830050, 0xaf820200, 0x1080001e,
-0xaf820220, 0x3c020001, 0x8c426e44, 0x1440001a,
-0x3c033f00, 0x3c020001, 0x8c426d80, 0x1000001a,
-0x346300e0, 0x8f830050, 0x3c040001, 0x8c846f1c,
-0x3442ffff, 0x621824, 0x1080000f, 0xaf830050,
-0x3c020001, 0x8c426e44, 0x1440000b, 0x3c043f00,
-0x3c030001, 0x8c636d80, 0x348400e0, 0x24020001,
-0xaf820200, 0xaf820220, 0x641825, 0xaf830200,
-0x10000008, 0x3c05f700, 0x3c020001, 0x8c426d80,
-0x3c033f00, 0x346300e2, 0x431025, 0xaf820200,
-0x3c05f700, 0x34a58000, 0x3c030001, 0x8c636d84,
-0x3c020001, 0x8c426d90, 0x3c040001, 0x8c846dac,
-0x651825, 0x431025, 0x441025, 0xaf820220,
-0x3e00008, 0x0, 0x3c030001, 0x8c636db4,
-0x3c020001, 0x8c426db8, 0x10620003, 0x24020002,
-0x3c010001, 0xac236db8, 0x1062001d, 0x2c620003,
-0x10400025, 0x24020001, 0x14620023, 0x24020004,
-0x3c030001, 0x8c636d98, 0x10620006, 0x24020008,
-0x1462000c, 0x3c0200c8, 0x344201fb, 0x10000009,
-0xaf820238, 0x24020e01, 0xaf820238, 0x8f820044,
-0x3c03ffff, 0x34633f7f, 0x431024, 0x34420080,
-0xaf820044, 0x8f830054, 0x24020002, 0x3c010001,
-0xac226db4, 0x3c010001, 0x1000000b, 0xac236f2c,
-0x8f830054, 0x3c020001, 0x8c426f2c, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400003, 0x24020009,
-0x3c010001, 0xac226db4, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x27bdffd8,
-0xafb20018, 0x809021, 0xafb3001c, 0xa09821,
-0xafb10014, 0xc08821, 0xafb00010, 0x8021,
-0xafbf0020, 0xa6200000, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x2501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x2501024, 0x24100010, 0x2701024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x2701024, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x0, 0x8fbf0020, 0x8fb3001c,
-0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008,
-0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821,
-0xafb20018, 0xa09021, 0xafb3001c, 0xc09821,
-0xafb00010, 0x8021, 0xafbf0020, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x2301024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x2301024, 0x24100010, 0x2501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2501024, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96620000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8fbf0020,
-0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
-0x3e00008, 0x27bd0028, 0x3c040001, 0x8c846dd0,
-0x3c020001, 0x8c426e18, 0x27bdffd8, 0xafbf0020,
-0xafb1001c, 0x10820003, 0xafb00018, 0x3c010001,
-0xac246e18, 0x3c030001, 0x8c636f40, 0x24020005,
-0x14620005, 0x2483ffff, 0xc004963, 0x0,
-0x1000034c, 0x0, 0x2c620013, 0x10400349,
-0x31080, 0x3c010001, 0x220821, 0x8c226b80,
-0x400008, 0x0, 0xc004db9, 0x8021,
-0x34028000, 0xa7a20010, 0x27b10010, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x1000030e, 0x24020002, 0x27b10010, 0xa7a00010,
-0x8021, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x0, 0x97a20010, 0x30428000,
-0x144002dc, 0x24020003, 0x100002d8, 0x0,
-0x24021200, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0xc004d78, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x34108000, 0x96220000, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fff8, 0x0, 0xc004db9,
-0x0, 0x8f830054, 0x10000296, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c426f3c, 0x2463ff9c,
-0x431023, 0x2c420064, 0x1440029e, 0x24020002,
-0x3c030001, 0x8c636f40, 0x10620297, 0x2c620003,
-0x14400296, 0x24020011, 0x24020003, 0x10620005,
-0x24020004, 0x10620291, 0x2402000f, 0x1000028f,
-0x24020011, 0x1000028d, 0x24020005, 0x24020014,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020012,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020012, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8f830054,
-0x10000248, 0x24020006, 0x8f830054, 0x3c020001,
-0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064,
-0x14400250, 0x24020007, 0x1000024c, 0x0,
-0x24020006, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020013, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020013,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x10000207, 0x24020008, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440020f, 0x24020009, 0x1000020b,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x10000193, 0x2402000a, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440019b, 0x2402000b, 0x10000197,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020017,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020017,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x1000011f, 0x2402000c, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x14400127, 0x24020012, 0x10000123,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020014,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020014,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x100000ab, 0x24020013, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x144000b3, 0x2402000d, 0x100000af,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x10000037, 0x2402000e, 0x24020840,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020013,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020013, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8f830054,
-0x24020010, 0x3c010001, 0xac226dd0, 0x3c010001,
-0x1000000c, 0xac236f3c, 0x8f830054, 0x3c020001,
-0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064,
-0x14400004, 0x0, 0x24020011, 0x3c010001,
-0xac226dd0, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x3c030001, 0x8c636d98,
-0x27bdffc8, 0x24020002, 0xafbf0034, 0xafb20030,
-0xafb1002c, 0x14620004, 0xafb00028, 0x3c120002,
-0x10000003, 0x8e528ff8, 0x3c120002, 0x8e528ffc,
-0x3c030001, 0x8c636dd4, 0x3c020001, 0x8c426e1c,
-0x50620004, 0x2463ffff, 0x3c010001, 0xac236e1c,
-0x2463ffff, 0x2c620006, 0x10400377, 0x31080,
-0x3c010001, 0x220821, 0x8c226bd8, 0x400008,
-0x0, 0x2021, 0x2821, 0xc004ddb,
-0x34068000, 0x24040010, 0x24050002, 0x24060002,
-0x24020002, 0xc004ddb, 0xa7a20018, 0x24020002,
-0x3c010001, 0x10000364, 0xac226dd4, 0x27b10018,
-0xa7a00018, 0x8021, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0xc004d78, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0xc004db9,
-0x34108000, 0xc004db9, 0x0, 0xc004d58,
-0x0, 0x50400005, 0x108042, 0x96220000,
-0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004db9, 0x0, 0x97a20018,
-0x30428000, 0x14400004, 0x24020003, 0x3c010001,
-0xac226dd4, 0x24020003, 0x3c010001, 0x1000032a,
-0xac226dd4, 0x24040010, 0x24050002, 0x24060002,
-0x24020002, 0xc004ddb, 0xa7a20018, 0x3c030001,
-0x8c636e20, 0x24020001, 0x146201e1, 0x8021,
-0x27b10018, 0xa7a00018, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x32020018, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020018, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0x27b10018, 0xa7a00018,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x24040018, 0x2821, 0xc004ddb, 0x24060404,
-0xa7a0001a, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0x32020018, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020018, 0xc004db9, 0x34108000, 0xc004db9,
-0x0, 0xc004d58, 0x0, 0x50400005,
-0x108042, 0x97a2001a, 0x501025, 0xa7a2001a,
-0x108042, 0x1600fff7, 0x0, 0xc004db9,
-0x8021, 0xa7a0001a, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x32020018, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020018, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x97a2001a, 0x501025,
-0xa7a2001a, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0xa7a0001c, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x24100010, 0xc004d78, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0x24100010,
-0x3202001e, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x3202001e,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x97a2001c, 0x501025, 0xa7a2001c, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0xa7a0001c, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0xc004d78, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0x24100010, 0x3202001e, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x3202001e, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x97a2001c, 0x501025,
-0xa7a2001c, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0x24020002, 0xa7a2001e,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0x24100010, 0x3202001e, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x3202001e, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x34108000, 0x97a2001e, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fff8, 0x0, 0xc004db9,
-0x8021, 0xa7a00020, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0x24100010, 0x3202001e,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x3202001e, 0xc004db9,
-0x34108000, 0xc004db9, 0x0, 0xc004d58,
-0x0, 0x50400005, 0x108042, 0x97a20020,
-0x501025, 0xa7a20020, 0x108042, 0x1600fff7,
-0x0, 0xc004db9, 0x8021, 0xa7a00020,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0x24100010, 0x3202001e, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x3202001e, 0xc004db9, 0x34108000, 0xc004db9,
-0x0, 0xc004d58, 0x0, 0x50400005,
-0x108042, 0x97a20020, 0x501025, 0xa7a20020,
-0x108042, 0x1600fff7, 0x0, 0xc004db9,
-0x8021, 0xa7a00022, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x97a20022, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x24040018, 0x24050002, 0xc004ddb, 0x24060004,
-0x3c100001, 0x8e106e24, 0x24020001, 0x1602011d,
-0x0, 0x3c020001, 0x94426f26, 0x3c010001,
-0xac206e24, 0x24429fbc, 0x2c420004, 0x1040000c,
-0x24040009, 0x24050001, 0xc004ddb, 0x24060400,
-0x24040018, 0x24050001, 0xc004ddb, 0x24060020,
-0x24040018, 0x24050001, 0xc004ddb, 0x24062000,
-0x3c024000, 0x2421024, 0x10400123, 0x3c022000,
-0x2421024, 0x10400004, 0x0, 0x3c010001,
-0x10000003, 0xac306f1c, 0x3c010001, 0xac206f1c,
-0x3c030001, 0x8c636f34, 0x24020005, 0x146200f9,
-0x0, 0x3c020001, 0x8c426f1c, 0x10400067,
-0x3c020004, 0x2421024, 0x10400011, 0xa7a00018,
-0x3c020008, 0x2421024, 0x10400002, 0x24020200,
-0xa7a20018, 0x3c020010, 0x2421024, 0x10400004,
-0x0, 0x97a20018, 0x34420100, 0xa7a20018,
-0x97a60018, 0x24040009, 0x10000004, 0x2821,
-0x24040009, 0x2821, 0x3021, 0xc004ddb,
-0x0, 0x24020001, 0xa7a2001a, 0x3c020008,
-0x2421024, 0x1040000c, 0x3c020002, 0x2421024,
-0x10400002, 0x24020101, 0xa7a2001a, 0x3c020001,
-0x2421024, 0x10400005, 0x3c020010, 0x97a2001a,
-0x34420040, 0xa7a2001a, 0x3c020010, 0x2421024,
-0x1040000e, 0x3c020002, 0x2421024, 0x10400005,
-0x3c020001, 0x97a2001a, 0x34420080, 0xa7a2001a,
-0x3c020001, 0x2421024, 0x10400005, 0x3c0300a0,
-0x97a2001a, 0x34420020, 0xa7a2001a, 0x3c0300a0,
-0x2431024, 0x54430004, 0x3c020020, 0x97a2001a,
-0x1000000c, 0x34420400, 0x2421024, 0x50400004,
-0x3c020080, 0x97a2001a, 0x10000006, 0x34420800,
-0x2421024, 0x10400004, 0x0, 0x97a2001a,
-0x34420c00, 0xa7a2001a, 0x97a6001a, 0x24040004,
-0xc004ddb, 0x2821, 0x3c020004, 0x2421024,
-0x10400004, 0xa7a0001c, 0x32425000, 0x14400004,
-0x0, 0x32424000, 0x10400005, 0x2021,
-0xc004cf9, 0x2402021, 0x10000096, 0x0,
-0x97a6001c, 0x2821, 0x34c61200, 0xc004ddb,
-0xa7a6001c, 0x1000008f, 0x0, 0x2421024,
-0x10400004, 0xa7a00018, 0x32425000, 0x14400004,
-0x0, 0x32424000, 0x10400005, 0x3c020010,
-0xc004cf9, 0x2402021, 0x10000019, 0xa7a0001a,
-0x2421024, 0x10400004, 0x0, 0x97a20018,
-0x10000004, 0xa7a20018, 0x97a20018, 0x34420100,
-0xa7a20018, 0x3c020001, 0x2421024, 0x10400004,
-0x0, 0x97a20018, 0x10000004, 0xa7a20018,
-0x97a20018, 0x34422000, 0xa7a20018, 0x97a60018,
-0x2021, 0xc004ddb, 0x2821, 0xa7a0001a,
-0x8021, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x97a2001a, 0x501025,
-0xa7a2001a, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0xa7a0001a, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x97a2001a, 0x501025, 0xa7a2001a, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x0,
-0x3c040001, 0x24846bcc, 0x97a60018, 0x97a7001a,
-0x3c020001, 0x8c426d98, 0x3c030001, 0x8c636f1c,
-0x3c05000d, 0x34a50205, 0xafa20010, 0xc002b3b,
-0xafa30014, 0x8f830054, 0x24020004, 0x3c010001,
-0xac226dd4, 0x3c010001, 0x10000017, 0xac236f38,
-0x8f830054, 0x3c020001, 0x8c426f38, 0x2463ff9c,
-0x431023, 0x2c420064, 0x1440000f, 0x0,
-0x8f820220, 0x24030005, 0x3c010001, 0xac236dd4,
-0x3c03f700, 0x431025, 0x10000007, 0xaf820220,
-0x24020006, 0x3c010001, 0xac226dd4, 0x24020011,
-0x3c010001, 0xac226dd0, 0x8fbf0034, 0x8fb20030,
-0x8fb1002c, 0x8fb00028, 0x3e00008, 0x27bd0038,
-0x27bdffd8, 0xafb00018, 0x808021, 0xafb1001c,
-0x8821, 0x32024000, 0x10400013, 0xafbf0020,
-0x3c020010, 0x2021024, 0x2c420001, 0x21023,
-0x30434100, 0x3c020001, 0x2021024, 0x14400006,
-0x34714000, 0x3c020002, 0x2021024, 0x14400002,
-0x34716000, 0x34714040, 0x2021, 0x2821,
-0x10000036, 0x2203021, 0x32021000, 0x10400035,
-0x2021, 0x2821, 0xc004ddb, 0x24060040,
-0x24040018, 0x2821, 0xc004ddb, 0x24060c00,
-0x24040017, 0x2821, 0xc004ddb, 0x24060400,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x24040017, 0x2821, 0xc004ddb, 0x24062500,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x24040017, 0x2821, 0xc004ddb, 0x24064600,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x24040017, 0x2821, 0xc004ddb, 0x24066700,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x2404001f, 0x2821, 0xc004ddb, 0x24060010,
-0x24040009, 0x2821, 0xc004ddb, 0x24061500,
-0x24040009, 0x2821, 0x24061d00, 0xc004ddb,
-0x0, 0x3c040001, 0x24846bf0, 0x3c05000e,
-0x34a50100, 0x2003021, 0x2203821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8fbf0020, 0x8fb1001c,
-0x8fb00018, 0x3e00008, 0x27bd0028, 0x8f850044,
-0x8f820044, 0x3c030001, 0x431025, 0x3c030008,
-0xaf820044, 0x8f840054, 0x8f820054, 0xa32824,
-0x10000002, 0x24840001, 0x8f820054, 0x821023,
-0x2c420002, 0x1440fffc, 0x0, 0x8f820044,
-0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x3e00008, 0xa01021, 0x8f830044,
-0x3c02fff0, 0x3442ffff, 0x42480, 0x621824,
-0x3c020002, 0x822025, 0x641825, 0xaf830044,
-0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x3c030001,
-0x431025, 0xaf820044, 0x8f830054, 0x8f820054,
-0x10000002, 0x24630001, 0x8f820054, 0x621023,
-0x2c420002, 0x1440fffc, 0x0, 0x3e00008,
-0x0, 0x8f820044, 0x2403ff7f, 0x431024,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x34420080,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x3e00008, 0x0,
-0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024,
-0xaf820044, 0x8f820044, 0x3c030001, 0x431025,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
-0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x3e00008, 0x0, 0x27bdffc8, 0xafb30024,
-0x809821, 0xafbe002c, 0xa0f021, 0xafb20020,
-0xc09021, 0x33c2ffff, 0xafbf0030, 0xafb50028,
-0xafb1001c, 0xafb00018, 0x14400034, 0xa7b20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x12000075,
-0x0, 0x1000fff6, 0x0, 0x3275ffff,
-0x27b10010, 0xa7a00010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2b01024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2b01024, 0xc004db9,
-0x34108000, 0xc004db9, 0x0, 0xc004d58,
-0x0, 0x50400005, 0x108042, 0x96220000,
-0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004db9, 0x0, 0x33c5ffff,
-0x24020001, 0x54a20004, 0x24020002, 0x97a20010,
-0x10000006, 0x521025, 0x14a20006, 0x3271ffff,
-0x97a20010, 0x121827, 0x431024, 0xa7a20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8fbf0030,
-0x8fbe002c, 0x8fb50028, 0x8fb30024, 0x8fb20020,
-0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038,
-0x0, 0x0, 0x0, 0x27bdffe8,
-0xafbf0010, 0x8ee304b8, 0x24020008, 0x146201e0,
-0x0, 0x3c020001, 0x8c426f1c, 0x14400005,
-0x0, 0xc003daf, 0x8f840224, 0x100001d8,
-0x0, 0x8f820220, 0x3c030008, 0x431024,
-0x10400026, 0x24020001, 0x8f840224, 0x8f820220,
-0x3c030400, 0x431024, 0x10400006, 0x0,
-0x3c010002, 0xac208fa0, 0x3c010002, 0x1000000b,
-0xac208fc0, 0x3c030002, 0x24638fa0, 0x8c620000,
-0x24420001, 0xac620000, 0x2c420002, 0x14400003,
-0x24020001, 0x3c010002, 0xac228fc0, 0x3c020002,
-0x8c428fc0, 0x10400006, 0x30820040, 0x10400004,
-0x24020001, 0x3c010002, 0x10000003, 0xac228fc4,
-0x3c010002, 0xac208fc4, 0x3c010002, 0xac248f9c,
-0x3c010002, 0x1000000b, 0xac208fd0, 0x3c010002,
-0xac228fd0, 0x3c010002, 0xac208fc0, 0x3c010002,
-0xac208fa0, 0x3c010002, 0xac208fc4, 0x3c010002,
-0xac208f9c, 0x3c030002, 0x8c638f90, 0x3c020002,
-0x8c428f94, 0x50620004, 0x2463ffff, 0x3c010002,
-0xac238f94, 0x2463ffff, 0x2c62000e, 0x10400194,
-0x31080, 0x3c010001, 0x220821, 0x8c226c00,
-0x400008, 0x0, 0x24020002, 0x3c010002,
-0xac208fc0, 0x3c010002, 0xac208fa0, 0x3c010002,
-0xac208f9c, 0x3c010002, 0xac208fc4, 0x3c010002,
-0xac208fb8, 0x3c010002, 0xac208fb0, 0xaf800224,
-0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fd0,
-0x1440004f, 0x3c02fdff, 0x3442ffff, 0xc003daf,
-0x282a024, 0xaf800204, 0x8f820200, 0x2403fffd,
-0x431024, 0xaf820200, 0x3c010002, 0xac208fe0,
-0x8f830054, 0x3c020002, 0x8c428fb8, 0x24040001,
-0x3c010002, 0xac248fcc, 0x24420001, 0x3c010002,
-0xac228fb8, 0x2c420004, 0x3c010002, 0xac238fb4,
-0x14400006, 0x24020003, 0x3c010001, 0xac246d9c,
-0x3c010002, 0x1000015e, 0xac208fb8, 0x3c010002,
-0x1000015b, 0xac228f90, 0x8f830054, 0x3c020002,
-0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400003, 0x24020004, 0x3c010002, 0xac228f90,
-0x3c020002, 0x8c428fd0, 0x14400021, 0x3c02fdff,
-0x3442ffff, 0x1000014a, 0x282a024, 0x3c040001,
-0x8c846f20, 0x3c010002, 0xc005084, 0xac208fa8,
-0x3c020002, 0x8c428fdc, 0xaf820204, 0x3c020002,
-0x8c428fd0, 0x14400012, 0x3c03fdff, 0x8f820204,
-0x3463ffff, 0x30420030, 0x1440012f, 0x283a024,
-0x3c030002, 0x8c638fdc, 0x24020005, 0x3c010002,
-0xac228f90, 0x3c010002, 0x10000131, 0xac238fe0,
-0x3c020002, 0x8c428fd0, 0x10400010, 0x3c02fdff,
-0x3c020001, 0x8c426e3c, 0x24420001, 0x3c010001,
-0xac226e3c, 0x2c420002, 0x14400125, 0x24020001,
-0x3c010001, 0xac226e44, 0x3c010001, 0xac206e3c,
-0x3c010001, 0x1000011e, 0xac226d9c, 0x3c030002,
-0x8c638fc0, 0x3442ffff, 0x10600119, 0x282a024,
-0x3c020002, 0x8c428f9c, 0x10400115, 0x0,
-0x3c010002, 0xac228fc8, 0x24020003, 0x3c010002,
-0xac228fa0, 0x100000b8, 0x24020006, 0x3c010002,
-0xac208fa8, 0x8f820204, 0x34420040, 0xaf820204,
-0x3c020002, 0x8c428fe0, 0x24030007, 0x3c010002,
-0xac238f90, 0x34420040, 0x3c010002, 0xac228fe0,
-0x3c020002, 0x8c428fc0, 0x10400005, 0x0,
-0x3c020002, 0x8c428f9c, 0x104000f0, 0x24020002,
-0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21,
-0x104000ea, 0x24020002, 0x3c020002, 0x8c428fc4,
-0x104000ef, 0x2404ffbf, 0x3c020002, 0x8c428f9c,
-0x3c030002, 0x8c638fc8, 0x441024, 0x641824,
-0x10430004, 0x24020001, 0x3c010002, 0x100000e4,
-0xac228f90, 0x24020003, 0xaca20000, 0x24020008,
-0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fcc,
-0x1040000c, 0x24020001, 0x3c040002, 0xc005091,
-0x8c848f9c, 0x3c020002, 0x8c428fe8, 0x14400005,
-0x24020001, 0x3c020002, 0x8c428fe4, 0x10400006,
-0x24020001, 0x3c010001, 0xac226d9c, 0x3c010002,
-0x100000cb, 0xac208fb8, 0x3c020002, 0x8c428fb0,
-0x3c030002, 0x8c638f9c, 0x2c420001, 0x210c0,
-0x30630008, 0x3c010002, 0xac228fb0, 0x3c010002,
-0xac238fac, 0x8f830054, 0x24020009, 0x3c010002,
-0xac228f90, 0x3c010002, 0x100000b9, 0xac238fb4,
-0x8f830054, 0x3c020002, 0x8c428fb4, 0x2463d8f0,
-0x431023, 0x2c422710, 0x1440009f, 0x0,
-0x3c020002, 0x8c428fc0, 0x10400005, 0x0,
-0x3c020002, 0x8c428f9c, 0x104000a0, 0x24020002,
-0x3c030002, 0x24638fa0, 0x8c620000, 0x2c424e21,
-0x1040009a, 0x24020002, 0x3c020002, 0x8c428fcc,
-0x1040000e, 0x0, 0x3c020002, 0x8c428f9c,
-0x3c010002, 0xac208fcc, 0x30420080, 0x1040002f,
-0x2402000c, 0x8f820204, 0x30420080, 0x1440000c,
-0x24020003, 0x10000029, 0x2402000c, 0x3c020002,
-0x8c428f9c, 0x30420080, 0x14400005, 0x24020003,
-0x8f820204, 0x30420080, 0x1040001f, 0x24020003,
-0xac620000, 0x2402000a, 0x3c010002, 0xac228f90,
-0x3c040002, 0x24848fd8, 0x8c820000, 0x3c030002,
-0x8c638fb0, 0x431025, 0xaf820204, 0x8c830000,
-0x3c040002, 0x8c848fb0, 0x2402000b, 0x3c010002,
-0xac228f90, 0x641825, 0x3c010002, 0xac238fe0,
-0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21,
-0x10400066, 0x24020002, 0x3c020002, 0x8c428fd0,
-0x10400005, 0x0, 0x2402000c, 0x3c010002,
-0x10000067, 0xac228f90, 0x3c020002, 0x8c428fc0,
-0x10400063, 0x0, 0x3c040002, 0x8c848f9c,
-0x10800055, 0x30820008, 0x3c030002, 0x8c638fac,
-0x1062005b, 0x24020003, 0x3c010002, 0xac248fc8,
-0xaca20000, 0x24020006, 0x3c010002, 0x10000054,
-0xac228f90, 0x8f820200, 0x34420002, 0xaf820200,
-0x8f830054, 0x2402000d, 0x3c010002, 0xac228f90,
-0x3c010002, 0xac238fb4, 0x8f830054, 0x3c020002,
-0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400031, 0x0, 0x3c020002, 0x8c428fd0,
-0x10400020, 0x2402000e, 0x3c030002, 0x8c638fe4,
-0x3c010002, 0x14600015, 0xac228f90, 0xc003e6d,
-0x0, 0x3c050001, 0x8ca56d98, 0xc00529b,
-0x2021, 0x3c030001, 0x8c636d98, 0x24020004,
-0x14620005, 0x2403fffb, 0x3c020001, 0x8c426d94,
-0x10000003, 0x2403fff7, 0x3c020001, 0x8c426d94,
-0x431024, 0x3c010001, 0xac226d94, 0x8f830224,
-0x3c020200, 0x3c010002, 0xac238fec, 0x10000020,
-0x282a025, 0x3c020002, 0x8c428fc0, 0x10400005,
-0x0, 0x3c020002, 0x8c428f9c, 0x1040000f,
-0x24020002, 0x3c020002, 0x8c428fa0, 0x2c424e21,
-0x1040000a, 0x24020002, 0x3c020002, 0x8c428fc0,
-0x1040000f, 0x0, 0x3c020002, 0x8c428f9c,
-0x1440000b, 0x0, 0x24020002, 0x3c010002,
-0x10000007, 0xac228f90, 0x3c020002, 0x8c428fc0,
-0x10400003, 0x0, 0xc003daf, 0x0,
-0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0x8fbf0010, 0x3e00008, 0x27bd0018, 0x3c030002,
-0x24638fe8, 0x8c620000, 0x10400005, 0x34422000,
-0x3c010002, 0xac228fdc, 0x10000003, 0xac600000,
-0x3c010002, 0xac248fdc, 0x3e00008, 0x0,
-0x27bdffe0, 0x30820030, 0xafbf0018, 0x3c010002,
-0xac228fe4, 0x14400067, 0x3c02ffff, 0x34421f0e,
-0x821024, 0x14400061, 0x24020030, 0x30822000,
-0x1040005d, 0x30838000, 0x31a02, 0x30820001,
-0x21200, 0x3c040001, 0x8c846f20, 0x621825,
-0x331c2, 0x3c030001, 0x24636e48, 0x30828000,
-0x21202, 0x30840001, 0x42200, 0x441025,
-0x239c2, 0x61080, 0x431021, 0x471021,
-0x90430000, 0x24020001, 0x10620025, 0x0,
-0x10600007, 0x24020002, 0x10620013, 0x24020003,
-0x1062002c, 0x3c05000f, 0x10000037, 0x0,
-0x8f820200, 0x2403feff, 0x431024, 0xaf820200,
-0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024,
-0xaf820220, 0x3c010002, 0xac209004, 0x3c010002,
-0x10000034, 0xac20900c, 0x8f820200, 0x34420100,
-0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff,
-0x431024, 0xaf820220, 0x24020100, 0x3c010002,
-0xac229004, 0x3c010002, 0x10000026, 0xac20900c,
-0x8f820200, 0x2403feff, 0x431024, 0xaf820200,
-0x8f820220, 0x3c030001, 0x431025, 0xaf820220,
-0x3c010002, 0xac209004, 0x3c010002, 0x10000019,
-0xac23900c, 0x8f820200, 0x34420100, 0xaf820200,
-0x8f820220, 0x3c030001, 0x431025, 0xaf820220,
-0x24020100, 0x3c010002, 0xac229004, 0x3c010002,
-0x1000000c, 0xac23900c, 0x34a5ffff, 0x3c040001,
-0x24846c38, 0xafa30010, 0xc002b3b, 0xafa00014,
-0x10000004, 0x0, 0x24020030, 0x3c010002,
-0xac228fe8, 0x8fbf0018, 0x3e00008, 0x27bd0020,
-0x0, 0x0, 0x0, 0x27bdffc8,
-0xafb20028, 0x809021, 0xafb3002c, 0xa09821,
-0xafb00020, 0xc08021, 0x3c040001, 0x24846c50,
-0x3c050009, 0x3c020001, 0x8c426d98, 0x34a59001,
-0x2403021, 0x2603821, 0xafbf0030, 0xafb10024,
-0xa7a0001a, 0xafb00014, 0xc002b3b, 0xafa20010,
-0x24020002, 0x12620083, 0x2e620003, 0x10400005,
-0x24020001, 0x1262000a, 0x0, 0x10000173,
-0x0, 0x24020004, 0x126200f8, 0x24020008,
-0x126200f7, 0x3c02ffec, 0x1000016c, 0x0,
-0x3c020001, 0x8c426d94, 0x30420002, 0x14400004,
-0x128940, 0x3c02fffb, 0x3442ffff, 0x2028024,
-0x3c010002, 0x310821, 0xac308ffc, 0x3c024000,
-0x2021024, 0x1040004e, 0x1023c2, 0x30840030,
-0x101382, 0x3042001c, 0x3c030001, 0x24636dd8,
-0x431021, 0x823821, 0x3c020020, 0x2021024,
-0x10400006, 0x24020100, 0x3c010002, 0x310821,
-0xac229000, 0x10000005, 0x3c020080, 0x3c010002,
-0x310821, 0xac209000, 0x3c020080, 0x2021024,
-0x10400006, 0x121940, 0x3c020001, 0x3c010002,
-0x230821, 0x10000005, 0xac229008, 0x121140,
-0x3c010002, 0x220821, 0xac209008, 0x94e40000,
-0x3c030001, 0x8c636f40, 0x24020005, 0x10620010,
-0xa7a40018, 0x32024000, 0x10400002, 0x34824000,
-0xa7a20018, 0x24040001, 0x94e20002, 0x24050004,
-0x24e60002, 0x34420001, 0xc0045be, 0xa4e20002,
-0x24040001, 0x2821, 0xc0045be, 0x27a60018,
-0x3c020001, 0x8c426d98, 0x24110001, 0x3c010001,
-0xac316da4, 0x14530004, 0x32028000, 0xc003daf,
-0x0, 0x32028000, 0x1040011c, 0x0,
-0xc003daf, 0x0, 0x3c030001, 0x8c636f40,
-0x24020005, 0x10620115, 0x24020002, 0x3c010001,
-0xac316d9c, 0x3c010001, 0x10000110, 0xac226d98,
-0x24040001, 0x24050004, 0x27b0001a, 0xc0045be,
-0x2003021, 0x24040001, 0x2821, 0xc0045be,
-0x2003021, 0x3c020002, 0x511021, 0x8c428ff4,
-0x3c040001, 0x8c846d98, 0x3c03bfff, 0x3463ffff,
-0x3c010001, 0xac336da4, 0x431024, 0x3c010002,
-0x310821, 0x109300f7, 0xac228ff4, 0x100000f7,
-0x0, 0x3c022000, 0x2021024, 0x10400005,
-0x24020001, 0x3c010001, 0xac226f1c, 0x10000004,
-0x128940, 0x3c010001, 0xac206f1c, 0x128940,
-0x3c010002, 0x310821, 0xac308ff8, 0x3c024000,
-0x2021024, 0x14400014, 0x0, 0x3c020001,
-0x8c426f1c, 0x10400006, 0x24040004, 0x24050001,
-0xc004ddb, 0x24062000, 0x24020001, 0xaee204b8,
-0x3c020002, 0x511021, 0x8c428ff0, 0x3c03bfff,
-0x3463ffff, 0x431024, 0x3c010002, 0x310821,
-0x100000d0, 0xac228ff0, 0x3c020001, 0x8c426f1c,
-0x10400028, 0x3c0300a0, 0x2031024, 0x5443000d,
-0x3c020020, 0x3c020001, 0x8c426f20, 0x24030100,
-0x3c010002, 0x310821, 0xac239004, 0x3c030001,
-0x3c010002, 0x310821, 0xac23900c, 0x10000015,
-0x34420400, 0x2021024, 0x10400008, 0x24030100,
-0x3c020001, 0x8c426f20, 0x3c010002, 0x310821,
-0xac239004, 0x1000000b, 0x34420800, 0x3c020080,
-0x2021024, 0x1040002e, 0x3c030001, 0x3c020001,
-0x8c426f20, 0x3c010002, 0x310821, 0xac23900c,
-0x34420c00, 0x3c010001, 0xac226f20, 0x10000025,
-0x24040001, 0x3c020020, 0x2021024, 0x10400006,
-0x24020100, 0x3c010002, 0x310821, 0xac229004,
-0x10000005, 0x3c020080, 0x3c010002, 0x310821,
-0xac209004, 0x3c020080, 0x2021024, 0x10400007,
-0x121940, 0x3c020001, 0x3c010002, 0x230821,
-0xac22900c, 0x10000006, 0x24040001, 0x121140,
-0x3c010002, 0x220821, 0xac20900c, 0x24040001,
-0x2821, 0x27b0001e, 0xc00457c, 0x2003021,
-0x24040001, 0x2821, 0xc00457c, 0x2003021,
-0x24040001, 0x24050001, 0x27b0001c, 0xc00457c,
-0x2003021, 0x24040001, 0x24050001, 0xc00457c,
-0x2003021, 0x10000077, 0x0, 0x3c02ffec,
-0x3442ffff, 0x2028024, 0x3c020008, 0x2028025,
-0x121140, 0x3c010002, 0x220821, 0xac308ff8,
-0x3c022000, 0x2021024, 0x10400009, 0x0,
-0x3c020001, 0x8c426e44, 0x14400005, 0x24020001,
-0x3c010001, 0xac226f1c, 0x10000004, 0x3c024000,
-0x3c010001, 0xac206f1c, 0x3c024000, 0x2021024,
-0x1440001d, 0x24020e01, 0x3c030001, 0x8c636f1c,
-0xaf820238, 0x3c010001, 0xac206db0, 0x10600005,
-0x24022020, 0x3c010001, 0xac226f20, 0x24020001,
-0xaee204b8, 0x3c04bfff, 0x121940, 0x3c020002,
-0x431021, 0x8c428ff0, 0x3c050001, 0x8ca56d98,
-0x3484ffff, 0x441024, 0x3c010002, 0x230821,
-0xac228ff0, 0x24020001, 0x10a20044, 0x0,
-0x10000040, 0x0, 0x3c020001, 0x8c426f1c,
-0x1040001c, 0x24022000, 0x3c010001, 0xac226f20,
-0x3c0300a0, 0x2031024, 0x14430005, 0x121140,
-0x3402a000, 0x3c010001, 0x1000002d, 0xac226f20,
-0x3c030002, 0x621821, 0x8c638ff8, 0x3c020020,
-0x621024, 0x10400004, 0x24022001, 0x3c010001,
-0x10000023, 0xac226f20, 0x3c020080, 0x621024,
-0x1040001f, 0x3402a001, 0x3c010001, 0x1000001c,
-0xac226f20, 0x3c020020, 0x2021024, 0x10400007,
-0x121940, 0x24020100, 0x3c010002, 0x230821,
-0xac229004, 0x10000006, 0x3c020080, 0x121140,
-0x3c010002, 0x220821, 0xac209004, 0x3c020080,
-0x2021024, 0x10400006, 0x121940, 0x3c020001,
-0x3c010002, 0x230821, 0x10000005, 0xac22900c,
-0x121140, 0x3c010002, 0x220821, 0xac20900c,
-0x3c030001, 0x8c636d98, 0x24020001, 0x10620003,
-0x0, 0xc003daf, 0x0, 0x8fbf0030,
-0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
-0x3e00008, 0x27bd0038, 0x27bdffb0, 0xafb3003c,
-0x9821, 0xafb50040, 0xa821, 0xafb10034,
-0x8821, 0x24020002, 0xafbf0048, 0xafbe0044,
-0xafb20038, 0xafb00030, 0xafa4002c, 0xa7a0001a,
-0xa7a00018, 0xa7a00020, 0xa7a0001e, 0xa7a00022,
-0x10a20130, 0xa7a0001c, 0x2ca20003, 0x10400005,
-0x24020001, 0x10a2000a, 0x3c024000, 0x1000025d,
-0x2201021, 0x24020004, 0x10a2020a, 0x24020008,
-0x10a20208, 0x2201021, 0x10000256, 0x0,
-0x8fa8002c, 0x88140, 0x3c030002, 0x701821,
-0x8c638ffc, 0x621024, 0x14400009, 0x24040001,
-0x3c027fff, 0x3442ffff, 0x628824, 0x3c010002,
-0x300821, 0xac318ff4, 0x10000246, 0x2201021,
-0x24050001, 0xc00457c, 0x27a60018, 0x24040001,
-0x24050001, 0xc00457c, 0x27a60018, 0x97a20018,
-0x30420004, 0x104000d9, 0x3c114000, 0x3c020001,
-0x8c426f40, 0x2443ffff, 0x2c620006, 0x104000d9,
-0x31080, 0x3c010001, 0x220821, 0x8c226c68,
-0x400008, 0x0, 0x24040001, 0x24050011,
-0x27b0001a, 0xc00457c, 0x2003021, 0x24040001,
-0x24050011, 0xc00457c, 0x2003021, 0x97a3001a,
-0x30624000, 0x10400002, 0x3c150010, 0x3c150008,
-0x30628000, 0x104000aa, 0x3c130001, 0x100000a8,
-0x3c130002, 0x24040001, 0x24050014, 0x27b0001a,
-0xc00457c, 0x2003021, 0x24040001, 0x24050014,
-0xc00457c, 0x2003021, 0x97a3001a, 0x30621000,
-0x10400002, 0x3c150010, 0x3c150008, 0x30620800,
-0x10400097, 0x3c130001, 0x10000095, 0x3c130002,
-0x24040001, 0x24050019, 0x27b0001c, 0xc00457c,
-0x2003021, 0x24040001, 0x24050019, 0xc00457c,
-0x2003021, 0x97a2001c, 0x30430700, 0x24020400,
-0x10620027, 0x28620401, 0x1040000e, 0x24020200,
-0x1062001f, 0x28620201, 0x10400005, 0x24020100,
-0x5062001e, 0x3c130001, 0x1000001e, 0x24040001,
-0x24020300, 0x50620019, 0x3c130002, 0x10000019,
-0x24040001, 0x24020600, 0x1062000d, 0x28620601,
-0x10400005, 0x24020500, 0x5062000b, 0x3c130002,
-0x10000010, 0x24040001, 0x24020700, 0x1462000d,
-0x24040001, 0x3c130004, 0x1000000a, 0x3c150008,
-0x10000006, 0x3c130004, 0x10000005, 0x3c150008,
-0x3c130001, 0x10000002, 0x3c150008, 0x3c150010,
-0x24040001, 0x24050018, 0x27b0001e, 0xc00457c,
-0x2003021, 0x24040001, 0x24050018, 0xc00457c,
-0x2003021, 0x8fa8002c, 0x97a7001e, 0x81140,
-0x3c060002, 0xc23021, 0x8cc68ff4, 0x97a20022,
-0x3c100001, 0x26106c5c, 0x2002021, 0xafa20010,
-0x97a2001c, 0x3c05000c, 0x34a50303, 0xc002b3b,
-0xafa20014, 0x3c020004, 0x16620010, 0x3c020001,
-0x8f840054, 0x24030001, 0x24020002, 0x3c010001,
-0xac236d9c, 0x3c010001, 0xac226d98, 0x3c010001,
-0xac236da4, 0x3c010001, 0xac236e24, 0x3c010001,
-0xac246f30, 0x1000004f, 0x2b38825, 0x16620039,
-0x3c028000, 0x3c020001, 0x8c426e20, 0x1440001e,
-0x24040018, 0x2021, 0x2821, 0xc004ddb,
-0x34068000, 0x8f830054, 0x8f820054, 0x2b38825,
-0x10000002, 0x24630032, 0x8f820054, 0x621023,
-0x2c420033, 0x1440fffc, 0x0, 0x8f830054,
-0x24020001, 0x3c010001, 0xac226e20, 0x3c010001,
-0xac226d9c, 0x3c010001, 0xac226d98, 0x3c010001,
-0xac226da4, 0x3c010001, 0xac226e24, 0x3c010001,
-0x1000002c, 0xac236f30, 0x2821, 0xc004ddb,
-0x24060404, 0x2021, 0x2405001e, 0x27a60018,
-0x24020002, 0xc0045be, 0xa7a20018, 0x2021,
-0x2821, 0x27a60018, 0xc0045be, 0xa7a00018,
-0x24040018, 0x24050002, 0xc004ddb, 0x24060004,
-0x3c028000, 0x2221025, 0x2b31825, 0x10000015,
-0x438825, 0x2221025, 0x2751825, 0x438825,
-0x2002021, 0x97a6001c, 0x3c070001, 0x8ce76d98,
-0x3c05000c, 0x34a50326, 0xafb30010, 0xc002b3b,
-0xafb10014, 0x10000007, 0x0, 0x3c110002,
-0x2308821, 0x8e318ffc, 0x3c027fff, 0x3442ffff,
-0x2228824, 0x3c020001, 0x8c426da8, 0x1040001e,
-0x0, 0x3c020001, 0x8c426f1c, 0x10400002,
-0x3c022000, 0x2228825, 0x8fa8002c, 0x81140,
-0x3c010002, 0x220821, 0x8c229000, 0x10400003,
-0x3c020020, 0x10000005, 0x2228825, 0x3c02ffdf,
-0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140,
-0x3c010002, 0x220821, 0x8c229008, 0x10400003,
-0x3c020080, 0x10000004, 0x2228825, 0x3c02ff7f,
-0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140,
-0x3c010002, 0x220821, 0xac318ff4, 0x10000135,
-0x2201021, 0x8fa8002c, 0x8f140, 0x3c030002,
-0x7e1821, 0x8c638ff8, 0x3c024000, 0x621024,
-0x14400009, 0x24040001, 0x3c027fff, 0x3442ffff,
-0x628824, 0x3c010002, 0x3e0821, 0xac318ff0,
-0x10000124, 0x2201021, 0x2821, 0xc00457c,
-0x27a60018, 0x24040001, 0x2821, 0xc00457c,
-0x27a60018, 0x24040001, 0x24050001, 0x27b20020,
-0xc00457c, 0x2403021, 0x24040001, 0x24050001,
-0xc00457c, 0x2403021, 0x24040001, 0x24050004,
-0x27b1001e, 0xc00457c, 0x2203021, 0x24040001,
-0x24050004, 0xc00457c, 0x2203021, 0x24040001,
-0x24050005, 0x27b00022, 0xc00457c, 0x2003021,
-0x24040001, 0x24050005, 0xc00457c, 0x2003021,
-0x24040001, 0x24050010, 0xc00457c, 0x27a60018,
-0x24040001, 0x24050010, 0xc00457c, 0x27a60018,
-0x24040001, 0x2405000a, 0xc00457c, 0x2403021,
-0x24040001, 0x2405000a, 0xc00457c, 0x2403021,
-0x24040001, 0x24050018, 0xc00457c, 0x2203021,
-0x24040001, 0x24050018, 0xc00457c, 0x2203021,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x97a20018, 0x30420004, 0x10400066, 0x3c114000,
-0x3c030001, 0x8c636f34, 0x24020005, 0x14620067,
-0x24040001, 0x24050019, 0x27b0001c, 0xc00457c,
-0x2003021, 0x24040001, 0x24050019, 0xc00457c,
-0x2003021, 0x97a2001c, 0x30430700, 0x24020400,
-0x10620027, 0x28620401, 0x1040000e, 0x24020200,
-0x1062001f, 0x28620201, 0x10400005, 0x24020100,
-0x5062001e, 0x3c130001, 0x1000001e, 0x3c020004,
-0x24020300, 0x50620019, 0x3c130002, 0x10000019,
-0x3c020004, 0x24020600, 0x1062000d, 0x28620601,
-0x10400005, 0x24020500, 0x5062000b, 0x3c130002,
-0x10000010, 0x3c020004, 0x24020700, 0x1462000d,
-0x3c020004, 0x3c130004, 0x1000000a, 0x3c150008,
-0x10000006, 0x3c130004, 0x10000005, 0x3c150008,
-0x3c130001, 0x10000002, 0x3c150008, 0x3c150010,
-0x3c020004, 0x12620017, 0x3c028000, 0x8f820054,
-0x24100001, 0x3c010001, 0xac306d9c, 0x3c010001,
-0xac306d98, 0x3c010001, 0xac306da4, 0x3c010001,
-0xac306e24, 0x3c010001, 0xac226f30, 0x3c020001,
-0x16620022, 0x2758825, 0x2021, 0x2821,
-0xc004ddb, 0x34068000, 0x3c010001, 0x1000001b,
-0xac306e20, 0x2221025, 0x2b31825, 0x438825,
-0x97a6001c, 0x3c020001, 0x8c426f1c, 0x3c070001,
-0x8ce76d98, 0x3c040001, 0x24846c5c, 0xafa20010,
-0x97a2001e, 0x3c05000c, 0x34a50323, 0x3c010001,
-0xac206e20, 0xc002b3b, 0xafa20014, 0x10000007,
-0x0, 0x3c110002, 0x23e8821, 0x8e318ff0,
-0x3c027fff, 0x3442ffff, 0x2228824, 0x3c020001,
-0x8c426da8, 0x10400069, 0x0, 0x3c020001,
-0x8c426f1c, 0x10400002, 0x3c022000, 0x2228825,
-0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
-0x8c229004, 0x10400003, 0x3c020020, 0x10000005,
-0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
-0x8c22900c, 0x10400003, 0x3c020080, 0x1000004f,
-0x2228825, 0x3c02ff7f, 0x3442ffff, 0x1000004b,
-0x2228824, 0x8fa8002c, 0x82940, 0x3c030002,
-0x651821, 0x8c638ff8, 0x3c024000, 0x621024,
-0x14400008, 0x3c027fff, 0x3442ffff, 0x628824,
-0x3c010002, 0x250821, 0xac318ff0, 0x10000041,
-0x2201021, 0x3c020001, 0x8c426da8, 0x10400034,
-0x3c11c00c, 0x3c020001, 0x8c426e44, 0x3c04c00c,
-0x34842000, 0x3c030001, 0x8c636f1c, 0x2102b,
-0x21023, 0x441024, 0x10600003, 0x518825,
-0x3c022000, 0x2228825, 0x3c020002, 0x451021,
-0x8c429004, 0x10400003, 0x3c020020, 0x10000004,
-0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
-0x8c22900c, 0x10400003, 0x3c020080, 0x10000004,
-0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824,
-0x3c020001, 0x8c426e30, 0x10400002, 0x3c020800,
-0x2228825, 0x3c020001, 0x8c426e34, 0x10400002,
-0x3c020400, 0x2228825, 0x3c020001, 0x8c426e38,
-0x10400006, 0x3c020100, 0x10000004, 0x2228825,
-0x3c027fff, 0x3442ffff, 0x628824, 0x8fa8002c,
-0x81140, 0x3c010002, 0x220821, 0xac318ff0,
-0x2201021, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
-0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
-0x3e00008, 0x27bd0050, 0x27bdffd0, 0xafb20028,
-0x809021, 0xafbf002c, 0xafb10024, 0xafb00020,
-0x8f840200, 0x3c100001, 0x8e106d98, 0x8f860220,
-0x24020002, 0x1202005c, 0x2e020003, 0x10400005,
-0x24020001, 0x1202000a, 0x121940, 0x1000010c,
-0x0, 0x24020004, 0x120200bf, 0x24020008,
-0x120200be, 0x128940, 0x10000105, 0x0,
-0x3c050002, 0xa32821, 0x8ca58ffc, 0x3c100002,
-0x2038021, 0x8e108ff4, 0x3c024000, 0xa21024,
-0x10400038, 0x3c020008, 0x2021024, 0x10400020,
-0x34840002, 0x3c020002, 0x431021, 0x8c429000,
-0x10400005, 0x34840020, 0x34840100, 0x3c020020,
-0x10000006, 0x2028025, 0x2402feff, 0x822024,
-0x3c02ffdf, 0x3442ffff, 0x2028024, 0x121140,
-0x3c010002, 0x220821, 0x8c229008, 0x10400005,
-0x3c020001, 0xc23025, 0x3c020080, 0x10000016,
-0x2028025, 0x3c02fffe, 0x3442ffff, 0xc23024,
-0x3c02ff7f, 0x3442ffff, 0x1000000f, 0x2028024,
-0x2402fedf, 0x822024, 0x3c02fffe, 0x3442ffff,
-0xc23024, 0x3c02ff5f, 0x3442ffff, 0x2028024,
-0x3c010002, 0x230821, 0xac209000, 0x3c010002,
-0x230821, 0xac209008, 0xaf840200, 0xaf860220,
-0x8f820220, 0x34420002, 0xaf820220, 0x1000000a,
-0x121140, 0x3c02bfff, 0x3442ffff, 0x8f830200,
-0x2028024, 0x2402fffd, 0x621824, 0xc003daf,
-0xaf830200, 0x121140, 0x3c010002, 0x220821,
-0x100000b7, 0xac308ff4, 0x3c020001, 0x8c426f1c,
-0x10400069, 0x24050004, 0x24040001, 0xc00457c,
-0x27a60018, 0x24040001, 0x24050005, 0xc00457c,
-0x27a6001a, 0x97a30018, 0x97a2001a, 0x3c040001,
-0x24846e48, 0x30630c00, 0x31a82, 0x30420c00,
-0x21282, 0xa7a2001a, 0x21080, 0x441021,
-0x431021, 0xa7a30018, 0x90480000, 0x24020001,
-0x3103ffff, 0x10620029, 0x28620002, 0x10400005,
-0x0, 0x10600009, 0x0, 0x1000003d,
-0x0, 0x10700013, 0x24020003, 0x1062002c,
-0x0, 0x10000037, 0x0, 0x8f820200,
-0x2403feff, 0x431024, 0xaf820200, 0x8f820220,
-0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220,
-0x3c010002, 0xac209004, 0x3c010002, 0x10000032,
-0xac20900c, 0x8f820200, 0x34420100, 0xaf820200,
-0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024,
-0xaf820220, 0x24020100, 0x3c010002, 0xac229004,
-0x3c010002, 0x10000024, 0xac20900c, 0x8f820200,
-0x2403feff, 0x431024, 0xaf820200, 0x8f820220,
-0x3c030001, 0x431025, 0xaf820220, 0x3c010002,
-0xac209004, 0x3c010002, 0x10000017, 0xac23900c,
-0x8f820200, 0x34420100, 0xaf820200, 0x8f820220,
-0x3c030001, 0x431025, 0xaf820220, 0x24020100,
-0x3c010002, 0xac229004, 0x3c010002, 0x1000000a,
-0xac23900c, 0x3c040001, 0x24846c80, 0x97a6001a,
-0x97a70018, 0x3c050001, 0x34a5ffff, 0xafa80010,
-0xc002b3b, 0xafa00014, 0x8f820200, 0x34420002,
-0x1000004b, 0xaf820200, 0x128940, 0x3c050002,
-0xb12821, 0x8ca58ff8, 0x3c100002, 0x2118021,
-0x8e108ff0, 0x3c024000, 0xa21024, 0x14400010,
-0x0, 0x3c020001, 0x8c426f1c, 0x14400005,
-0x3c02bfff, 0x8f820200, 0x34420002, 0xaf820200,
-0x3c02bfff, 0x3442ffff, 0xc003daf, 0x2028024,
-0x3c010002, 0x310821, 0x10000031, 0xac308ff0,
-0x3c020001, 0x8c426f1c, 0x10400005, 0x3c020020,
-0x3c020001, 0x8c426e44, 0x10400025, 0x3c020020,
-0xa21024, 0x10400007, 0x34840020, 0x24020100,
-0x3c010002, 0x310821, 0xac229004, 0x10000006,
-0x34840100, 0x3c010002, 0x310821, 0xac209004,
-0x2402feff, 0x822024, 0x3c020080, 0xa21024,
-0x10400007, 0x121940, 0x3c020001, 0x3c010002,
-0x230821, 0xac22900c, 0x10000008, 0xc23025,
-0x121140, 0x3c010002, 0x220821, 0xac20900c,
-0x3c02fffe, 0x3442ffff, 0xc23024, 0xaf840200,
-0xaf860220, 0x8f820220, 0x34420002, 0xaf820220,
-0x121140, 0x3c010002, 0x220821, 0xac308ff0,
-0x8fbf002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
-0x3e00008, 0x27bd0030, 0x0, 0x1821,
-0x308400ff, 0x2405ffdf, 0x2406ffbf, 0x641007,
-0x30420001, 0x10400004, 0x0, 0x8f820044,
-0x10000003, 0x34420040, 0x8f820044, 0x461024,
-0xaf820044, 0x8f820044, 0x34420020, 0xaf820044,
-0x8f820044, 0x451024, 0xaf820044, 0x24630001,
-0x28620008, 0x5440ffee, 0x641007, 0x3e00008,
-0x0, 0x2c820008, 0x1040001b, 0x0,
-0x2405ffdf, 0x2406ffbf, 0x41880, 0x3c020001,
-0x24426e60, 0x621821, 0x24640004, 0x90620000,
-0x10400004, 0x0, 0x8f820044, 0x10000003,
-0x34420040, 0x8f820044, 0x461024, 0xaf820044,
-0x8f820044, 0x34420020, 0xaf820044, 0x8f820044,
-0x451024, 0xaf820044, 0x24630001, 0x64102b,
-0x1440ffee, 0x0, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x8f8400c4,
-0x8f8600e0, 0x8f8700e4, 0x2402fff8, 0xc22824,
-0x10e5001a, 0x27623ff8, 0x14e20002, 0x24e80008,
-0x27683000, 0x55050004, 0x8d0a0000, 0x30c20004,
-0x14400012, 0x805021, 0x8ce90000, 0x8f42013c,
-0x1494823, 0x49182b, 0x94eb0006, 0x10600002,
-0x25630050, 0x494821, 0x123182b, 0x50400003,
-0x8f4201fc, 0x3e00008, 0xe01021, 0xaf8800e8,
-0x24420001, 0xaf4201fc, 0xaf8800e4, 0x3e00008,
-0x1021, 0x3e00008, 0x0, 0x8f8300e4,
-0x27623ff8, 0x10620004, 0x24620008, 0xaf8200e8,
-0x3e00008, 0xaf8200e4, 0x27623000, 0xaf8200e8,
-0x3e00008, 0xaf8200e4, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x8f880120,
-0x27624fe0, 0x8f830128, 0x15020002, 0x25090020,
-0x27694800, 0x11230012, 0x8fa20010, 0xad040000,
-0xad050004, 0xad060008, 0xa507000e, 0x8fa30014,
-0xad020018, 0x8fa20018, 0xad03001c, 0x25030016,
-0xad020010, 0xad030014, 0xaf890120, 0x8f4300fc,
-0x24020001, 0x2463ffff, 0x3e00008, 0xaf4300fc,
-0x8f430324, 0x1021, 0x24630001, 0x3e00008,
-0xaf430324, 0x3e00008, 0x0, 0x8f880100,
-0x276247e0, 0x8f830108, 0x15020002, 0x25090020,
-0x27694000, 0x1123000f, 0x8fa20010, 0xad040000,
-0xad050004, 0xad060008, 0xa507000e, 0x8fa30014,
-0xad020018, 0x8fa20018, 0xad03001c, 0x25030016,
-0xad020010, 0xad030014, 0xaf890100, 0x3e00008,
-0x24020001, 0x8f430328, 0x1021, 0x24630001,
-0x3e00008, 0xaf430328, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x0 };
-static int tigon2FwRodata[/*(MAX_RODATA_LEN/4) + 1*/] = {
-0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6677, 0x6d61696e, 0x2e632c76, 0x20312e31,
-0x2e322e34, 0x35203139, 0x39392f30, 0x312f3234,
-0x2030303a, 0x31303a35, 0x35207368, 0x75616e67,
-0x20457870, 0x20240000, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x6261644d, 0x656d537a,
-0x0, 0x68775665, 0x72000000, 0x62616448,
-0x77566572, 0x0, 0x2a2a4441, 0x574e5f41,
-0x0, 0x74785278, 0x4266537a, 0x0,
-0x62664174, 0x6e4d726b, 0x0, 0x7265645a,
-0x6f6e6531, 0x0, 0x70636943, 0x6f6e6600,
-0x67656e43, 0x6f6e6600, 0x2a646d61, 0x5244666c,
-0x0, 0x2a50414e, 0x49432a00, 0x2e2e2f2e,
-0x2e2f2e2e, 0x2f2e2e2f, 0x2e2e2f73, 0x72632f6e,
-0x69632f66, 0x77322f63, 0x6f6d6d6f, 0x6e2f6677,
-0x6d61696e, 0x2e630000, 0x72636246, 0x6c616773,
-0x0, 0x62616452, 0x78526362, 0x0,
-0x676c6f62, 0x466c6773, 0x0, 0x2b5f6469,
-0x73705f6c, 0x6f6f7000, 0x2b65765f, 0x68616e64,
-0x6c657200, 0x63616e74, 0x31446d61, 0x0,
-0x2b715f64, 0x6d615f74, 0x6f5f6e69, 0x635f636b,
-0x73756d00, 0x2b685f73, 0x656e645f, 0x64617461,
-0x5f726561, 0x64795f63, 0x6b73756d, 0x0,
-0x2b685f64, 0x6d615f72, 0x645f6173, 0x73697374,
-0x5f636b73, 0x756d0000, 0x74436b73, 0x6d4f6e00,
-0x2b715f64, 0x6d615f74, 0x6f5f6e69, 0x63000000,
-0x2b685f73, 0x656e645f, 0x64617461, 0x5f726561,
-0x64790000, 0x2b685f64, 0x6d615f72, 0x645f6173,
-0x73697374, 0x0, 0x74436b73, 0x6d4f6666,
-0x0, 0x2b685f73, 0x656e645f, 0x62645f72,
-0x65616479, 0x0, 0x68737453, 0x52696e67,
-0x0, 0x62616453, 0x52696e67, 0x0,
-0x6e696353, 0x52696e67, 0x0, 0x77446d61,
-0x416c6c41, 0x0, 0x2b715f64, 0x6d615f74,
-0x6f5f686f, 0x73745f63, 0x6b73756d, 0x0,
-0x2b685f6d, 0x61635f72, 0x785f636f, 0x6d705f63,
-0x6b73756d, 0x0, 0x2b685f64, 0x6d615f77,
-0x725f6173, 0x73697374, 0x5f636b73, 0x756d0000,
-0x72436b73, 0x6d4f6e00, 0x2b715f64, 0x6d615f74,
-0x6f5f686f, 0x73740000, 0x2b685f6d, 0x61635f72,
-0x785f636f, 0x6d700000, 0x2b685f64, 0x6d615f77,
-0x725f6173, 0x73697374, 0x0, 0x72436b73,
-0x6d4f6666, 0x0, 0x2b685f72, 0x6563765f,
-0x62645f72, 0x65616479, 0x0, 0x2b685f72,
-0x6563765f, 0x6a756d62, 0x6f5f6264, 0x5f726561,
-0x64790000, 0x2b685f72, 0x6563765f, 0x6d696e69,
-0x5f62645f, 0x72656164, 0x79000000, 0x2b6d685f,
-0x636f6d6d, 0x616e6400, 0x2b685f74, 0x696d6572,
-0x0, 0x2b685f64, 0x6f5f7570, 0x64617465,
-0x5f74785f, 0x636f6e73, 0x0, 0x2b685f64,
-0x6f5f7570, 0x64617465, 0x5f72785f, 0x70726f64,
-0x0, 0x2b636b73, 0x756d3136, 0x0,
-0x2b706565, 0x6b5f6d61, 0x635f7278, 0x5f776100,
-0x2b706565, 0x6b5f6d61, 0x635f7278, 0x0,
-0x2b646571, 0x5f6d6163, 0x5f727800, 0x2b685f6d,
-0x61635f72, 0x785f6174, 0x746e0000, 0x62616452,
-0x6574537a, 0x0, 0x72784264, 0x4266537a,
-0x0, 0x2b6e756c, 0x6c5f6861, 0x6e646c65,
-0x72000000, 0x66774f70, 0x4661696c, 0x0,
-0x2b685f75, 0x70646174, 0x655f6c65, 0x64340000,
-0x2b685f75, 0x70646174, 0x655f6c65, 0x64360000,
-0x2b685f75, 0x70646174, 0x655f6c65, 0x64320000,
-0x696e7453, 0x74617465, 0x0, 0x2a2a696e,
-0x69744370, 0x0, 0x23736372, 0x65616d00,
-0x69537461, 0x636b4572, 0x0, 0x70726f62,
-0x654d656d, 0x0, 0x2a2a4441, 0x574e5f42,
-0x0, 0x2b73775f, 0x646d615f, 0x61737369,
-0x73745f70, 0x6c75735f, 0x74696d65, 0x72000000,
-0x2b267072, 0x656c6f61, 0x645f7772, 0x5f646573,
-0x63720000, 0x2b267072, 0x656c6f61, 0x645f7264,
-0x5f646573, 0x63720000, 0x2b685f68, 0x665f7469,
-0x6d657200, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7469, 0x6d65722e, 0x632c7620, 0x312e312e,
-0x322e3335, 0x20313939, 0x392f3031, 0x2f323720,
-0x31393a30, 0x393a3530, 0x20686179, 0x65732045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x542d446d, 0x61526432,
-0x0, 0x542d446d, 0x61526431, 0x0,
-0x542d446d, 0x61526442, 0x0, 0x542d446d,
-0x61577232, 0x0, 0x542d446d, 0x61577231,
-0x0, 0x542d446d, 0x61577242, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f636f, 0x6d6d616e, 0x642e632c, 0x7620312e,
-0x312e322e, 0x32382031, 0x3939392f, 0x30312f32,
-0x30203139, 0x3a34393a, 0x34392073, 0x6875616e,
-0x67204578, 0x70202400, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x3f48636d, 0x644d6278,
-0x0, 0x3f636d64, 0x48737453, 0x0,
-0x3f636d64, 0x4d634d64, 0x0, 0x3f636d64,
-0x50726f6d, 0x0, 0x3f636d64, 0x4c696e6b,
-0x0, 0x3f636d64, 0x45727200, 0x86ac,
-0x8e5c, 0x8e5c, 0x8de4, 0x8b78,
-0x8e30, 0x8e5c, 0x8790, 0x8800,
-0x8990, 0x8a68, 0x8a34, 0x8e5c,
-0x8870, 0x8b24, 0x8e5c, 0x8b34,
-0x87b4, 0x8824, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6d63, 0x6173742e, 0x632c7620, 0x312e312e,
-0x322e3820, 0x31393938, 0x2f31322f, 0x30382030,
-0x323a3336, 0x3a333620, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x6164644d, 0x63447570,
-0x0, 0x6164644d, 0x6346756c, 0x0,
-0x64656c4d, 0x634e6f45, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f646d, 0x612e632c, 0x7620312e, 0x312e322e,
-0x32342031, 0x3939382f, 0x31322f32, 0x31203030,
-0x3a33333a, 0x30392073, 0x6875616e, 0x67204578,
-0x70202400, 0x65767452, 0x6e674600, 0x51657674,
-0x46000000, 0x51657674, 0x505f4600, 0x4d657674,
-0x526e6746, 0x0, 0x4d516576, 0x74460000,
-0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46,
-0x0, 0x5173436f, 0x6e734600, 0x51725072,
-0x6f644600, 0x7377446d, 0x614f6666, 0x0,
-0x31446d61, 0x4f6e0000, 0x7377446d, 0x614f6e00,
-0x2372446d, 0x6141544e, 0x0, 0x72446d61,
-0x41544e30, 0x0, 0x72446d61, 0x41544e31,
-0x0, 0x72446d61, 0x34476200, 0x2a50414e,
-0x49432a00, 0x2e2e2f2e, 0x2e2f2e2e, 0x2f2e2e2f,
-0x2e2e2f73, 0x72632f6e, 0x69632f66, 0x77322f63,
-0x6f6d6d6f, 0x6e2f646d, 0x612e6300, 0x2377446d,
-0x6141544e, 0x0, 0x77446d61, 0x41544e30,
-0x0, 0x77446d61, 0x41544e31, 0x0,
-0x77446d61, 0x34476200, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7472, 0x6163652e, 0x632c7620, 0x312e312e,
-0x322e3520, 0x31393938, 0x2f30392f, 0x33302031,
-0x383a3530, 0x3a323820, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6461, 0x74612e63, 0x2c762031, 0x2e312e32,
-0x2e313220, 0x31393939, 0x2f30312f, 0x32302031,
-0x393a3439, 0x3a353120, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x46575f56, 0x45525349,
-0x4f4e3a20, 0x23312046, 0x72692041, 0x70722037,
-0x2031373a, 0x35373a35, 0x32205044, 0x54203230,
-0x30300000, 0x46575f43, 0x4f4d5049, 0x4c455f54,
-0x494d453a, 0x2031373a, 0x35373a35, 0x32000000,
-0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064,
-0x65767263, 0x73000000, 0x46575f43, 0x4f4d5049,
-0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465,
-0x0, 0x46575f43, 0x4f4d5049, 0x4c455f44,
-0x4f4d4149, 0x4e3a2065, 0x6e672e61, 0x6374656f,
-0x6e2e636f, 0x6d000000, 0x46575f43, 0x4f4d5049,
-0x4c45523a, 0x20676363, 0x20766572, 0x73696f6e,
-0x20322e37, 0x2e320000, 0x0, 0x12041100,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6d65, 0x6d2e632c, 0x7620312e, 0x312e322e,
-0x35203139, 0x39382f30, 0x392f3330, 0x2031383a,
-0x35303a30, 0x38207368, 0x75616e67, 0x20457870,
-0x20240000, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7365, 0x6e642e63, 0x2c762031, 0x2e312e32,
-0x2e343420, 0x31393938, 0x2f31322f, 0x32312030,
-0x303a3333, 0x3a313820, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x69736e74, 0x54637055,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7265, 0x63762e63, 0x2c762031, 0x2e312e32,
-0x2e353320, 0x31393939, 0x2f30312f, 0x31362030,
-0x323a3535, 0x3a343320, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x724d6163, 0x43686b30,
-0x0, 0x72784672, 0x6d324c67, 0x0,
-0x72784e6f, 0x53744264, 0x0, 0x72784e6f,
-0x4d694264, 0x0, 0x72784e6f, 0x4a6d4264,
-0x0, 0x7278436b, 0x446d6146, 0x0,
-0x72785144, 0x6d457846, 0x0, 0x72785144,
-0x6d614600, 0x72785144, 0x4c426446, 0x0,
-0x72785144, 0x6d426446, 0x0, 0x72784372,
-0x63506164, 0x0, 0x72536d51, 0x446d6146,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6d61, 0x632e632c, 0x7620312e, 0x312e322e,
-0x32322031, 0x3939382f, 0x31322f30, 0x38203032,
-0x3a33363a, 0x33302073, 0x6875616e, 0x67204578,
-0x70202400, 0x65767452, 0x6e674600, 0x51657674,
-0x46000000, 0x51657674, 0x505f4600, 0x4d657674,
-0x526e6746, 0x0, 0x4d516576, 0x74460000,
-0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46,
-0x0, 0x5173436f, 0x6e734600, 0x51725072,
-0x6f644600, 0x6d616354, 0x68726573, 0x0,
-0x23744d61, 0x6341544e, 0x0, 0x23724d61,
-0x6341544e, 0x0, 0x72656d41, 0x73737274,
-0x0, 0x6c696e6b, 0x444f574e, 0x0,
-0x6c696e6b, 0x55500000, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f636b, 0x73756d2e, 0x632c7620, 0x312e312e,
-0x322e3920, 0x31393939, 0x2f30312f, 0x31342030,
-0x303a3033, 0x3a343820, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x0, 0x0,
-0x0, 0x50726f62, 0x65506879, 0x0,
-0x6c6e6b41, 0x53535254, 0x0, 0x109a4,
-0x10a1c, 0x10a50, 0x10a7c, 0x11050,
-0x10aa8, 0x10b10, 0x111fc, 0x10dc0,
-0x10c68, 0x10c80, 0x10cc4, 0x10cec,
-0x10d0c, 0x10d34, 0x111fc, 0x10dc0,
-0x10df8, 0x10e10, 0x10e40, 0x10e68,
-0x10e88, 0x10eb0, 0x0, 0x10fdc,
-0x11008, 0x1102c, 0x111fc, 0x11050,
-0x11078, 0x11108, 0x0, 0x0,
-0x0, 0x1186c, 0x1193c, 0x11a14,
-0x11ae4, 0x11b40, 0x11c1c, 0x11c44,
-0x11d20, 0x11d48, 0x11ef0, 0x11f18,
-0x120c0, 0x122b8, 0x1254c, 0x12460,
-0x1254c, 0x12578, 0x120e8, 0x12290,
-0x7273745f, 0x676d6969, 0x0, 0x12608,
-0x12640, 0x12728, 0x13374, 0x133b4,
-0x133cc, 0x7365746c, 0x6f6f7000, 0x0,
-0x0, 0x13bbc, 0x13bfc, 0x13c8c,
-0x13cd0, 0x13d34, 0x13dc0, 0x13df4,
-0x13e7c, 0x13f14, 0x13fe4, 0x14024,
-0x140a8, 0x140cc, 0x141dc, 0x646f4261,
-0x73655067, 0x0, 0x0, 0x0,
-0x0, 0x73746d61, 0x634c4e4b, 0x0,
-0x6765746d, 0x636c6e6b, 0x0, 0x14ed8,
-0x14ed8, 0x14b8c, 0x14bd8, 0x14c24,
-0x14ed8, 0x7365746d, 0x61636163, 0x74000000,
-0x0, 0x0 };
-static int tigon2FwData[/*(MAX_DATA_LEN/4) + 1*/] = {
-0x1,
-0x1, 0x1, 0xc001fc, 0x3ffc,
-0xc00000, 0x416c7465, 0x6f6e2041, 0x63654e49,
-0x43205600, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x416c7465,
-0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242,
-0x0, 0x0, 0x0, 0x1ffffc,
-0x1fff7c, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x60cf00,
-0x60, 0xcf000000, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x3, 0x0,
-0x1, 0x0, 0x0, 0x0,
-0x1, 0x0, 0x1, 0x0,
-0x0, 0x0, 0x0, 0x1,
-0x1, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x1000000, 0x21000000,
-0x12000140, 0x0, 0x0, 0x20000000,
-0x120000a0, 0x0, 0x12000060, 0x12000180,
-0x120001e0, 0x0, 0x0, 0x0,
-0x1, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x2,
-0x0, 0x0, 0x30001, 0x1,
-0x30201, 0x0, 0x0, 0x1010101,
-0x1010100, 0x10100, 0x1010001, 0x10001,
-0x1000101, 0x101, 0x0, 0x0 };
diff --git a/os/pc/etherif.h b/os/pc/etherif.h
deleted file mode 100644
index d80e06c9..00000000
--- a/os/pc/etherif.h
+++ /dev/null
@@ -1,39 +0,0 @@
-enum {
- MaxEther = 24,
- Ntypes = 8,
-};
-
-typedef struct Ether Ether;
-struct Ether {
- ISAConf; /* hardware info */
-
- int ctlrno;
- int tbdf; /* type+busno+devno+funcno */
- int minmtu;
- int maxmtu;
- uchar ea[Eaddrlen];
-
- void (*attach)(Ether*); /* filled in by reset routine */
- void (*detach)(Ether*);
- void (*transmit)(Ether*);
- void (*interrupt)(Ureg*, void*);
- long (*ifstat)(Ether*, void*, long, ulong);
- long (*ctl)(Ether*, void*, long); /* custom ctl messages */
- void (*power)(Ether*, int); /* power on/off */
- void (*shutdown)(Ether*); /* shutdown hardware before reboot */
- void *ctlr;
-
- Queue* oq;
-
- Netif;
-};
-
-extern Block* etheriq(Ether*, Block*, int);
-extern void addethercard(char*, int(*)(Ether*));
-extern ulong ethercrc(uchar*, int);
-extern int parseether(uchar*, char*);
-
-#define NEXT(x, l) (((x)+1)%(l))
-#define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1)
-#define HOWMANY(x, y) (((x)+((y)-1))/(y))
-#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))
diff --git a/os/pc/etherigbe.c b/os/pc/etherigbe.c
deleted file mode 100644
index 10515097..00000000
--- a/os/pc/etherigbe.c
+++ /dev/null
@@ -1,1989 +0,0 @@
-/*
- * Intel 8254[340]NN Gigabit Ethernet Controller
- * as found on the Intel PRO/1000 series of adapters:
- * 82543GC Intel PRO/1000 T
- * 82544EI Intel PRO/1000 XT
- * 82540EM Intel PRO/1000 MT
- * 82541[GP]I
- * 82547GI
- * 82546GB
- * 82546EB
- * To Do:
- * finish autonegotiation code;
- * integrate fiber stuff back in (this ONLY handles
- * the CAT5 cards at the moment);
- * add checksum-offload;
- * add tuning control via ctl file;
- * this driver is little-endian specific.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-enum {
- i82542 = (0x1000<<16)|0x8086,
- i82543gc = (0x1004<<16)|0x8086,
- i82544ei = (0x1008<<16)|0x8086,
- i82547ei = (0x1019<<16)|0x8086,
- i82540em = (0x100E<<16)|0x8086,
- i82540eplp = (0x101E<<16)|0x8086,
- i82545gmc = (0x1026<<16)|0x8086,
- i82547gi = (0x1075<<16)|0x8086,
- i82541gi = (0x1076<<16)|0x8086,
- i82541gi2 = (0x1077<<16)|0x8086,
- i82546gb = (0x1079<<16)|0x8086,
- i82541pi = (0x107c<<16)|0x8086,
- i82546eb = (0x1010<<16)|0x8086,
-};
-
-enum {
- Ctrl = 0x00000000, /* Device Control */
- Ctrldup = 0x00000004, /* Device Control Duplicate */
- Status = 0x00000008, /* Device Status */
- Eecd = 0x00000010, /* EEPROM/Flash Control/Data */
- Ctrlext = 0x00000018, /* Extended Device Control */
- Mdic = 0x00000020, /* MDI Control */
- Fcal = 0x00000028, /* Flow Control Address Low */
- Fcah = 0x0000002C, /* Flow Control Address High */
- Fct = 0x00000030, /* Flow Control Type */
- Icr = 0x000000C0, /* Interrupt Cause Read */
- Ics = 0x000000C8, /* Interrupt Cause Set */
- Ims = 0x000000D0, /* Interrupt Mask Set/Read */
- Imc = 0x000000D8, /* Interrupt mask Clear */
- Rctl = 0x00000100, /* Receive Control */
- Fcttv = 0x00000170, /* Flow Control Transmit Timer Value */
- Txcw = 0x00000178, /* Transmit Configuration Word */
- Rxcw = 0x00000180, /* Receive Configuration Word */
- Tctl = 0x00000400, /* Transmit Control */
- Tipg = 0x00000410, /* Transmit IPG */
- Tbt = 0x00000448, /* Transmit Burst Timer */
- Ait = 0x00000458, /* Adaptive IFS Throttle */
- Fcrtl = 0x00002160, /* Flow Control RX Threshold Low */
- Fcrth = 0x00002168, /* Flow Control Rx Threshold High */
- Rdfh = 0x00002410, /* Receive data fifo head */
- Rdft = 0x00002418, /* Receive data fifo tail */
- Rdfhs = 0x00002420, /* Receive data fifo head saved */
- Rdfts = 0x00002428, /* Receive data fifo tail saved */
- Rdfpc = 0x00002430, /* Receive data fifo packet count */
- Rdbal = 0x00002800, /* Rd Base Address Low */
- Rdbah = 0x00002804, /* Rd Base Address High */
- Rdlen = 0x00002808, /* Receive Descriptor Length */
- Rdh = 0x00002810, /* Receive Descriptor Head */
- Rdt = 0x00002818, /* Receive Descriptor Tail */
- Rdtr = 0x00002820, /* Receive Descriptor Timer Ring */
- Rxdctl = 0x00002828, /* Receive Descriptor Control */
- Radv = 0x0000282C, /* Receive Interrupt Absolute Delay Timer */
- Txdmac = 0x00003000, /* Transfer DMA Control */
- Ett = 0x00003008, /* Early Transmit Control */
- Tdfh = 0x00003410, /* Transmit data fifo head */
- Tdft = 0x00003418, /* Transmit data fifo tail */
- Tdfhs = 0x00003420, /* Transmit data Fifo Head saved */
- Tdfts = 0x00003428, /* Transmit data fifo tail saved */
- Tdfpc = 0x00003430, /* Trasnmit data Fifo packet count */
- Tdbal = 0x00003800, /* Td Base Address Low */
- Tdbah = 0x00003804, /* Td Base Address High */
- Tdlen = 0x00003808, /* Transmit Descriptor Length */
- Tdh = 0x00003810, /* Transmit Descriptor Head */
- Tdt = 0x00003818, /* Transmit Descriptor Tail */
- Tidv = 0x00003820, /* Transmit Interrupt Delay Value */
- Txdctl = 0x00003828, /* Transmit Descriptor Control */
- Tadv = 0x0000382C, /* Transmit Interrupt Absolute Delay Timer */
-
- Statistics = 0x00004000, /* Start of Statistics Area */
- Gorcl = 0x88/4, /* Good Octets Received Count */
- Gotcl = 0x90/4, /* Good Octets Transmitted Count */
- Torl = 0xC0/4, /* Total Octets Received */
- Totl = 0xC8/4, /* Total Octets Transmitted */
- Nstatistics = 64,
-
- Rxcsum = 0x00005000, /* Receive Checksum Control */
- Mta = 0x00005200, /* Multicast Table Array */
- Ral = 0x00005400, /* Receive Address Low */
- Rah = 0x00005404, /* Receive Address High */
- Manc = 0x00005820, /* Management Control */
-};
-
-enum { /* Ctrl */
- Bem = 0x00000002, /* Big Endian Mode */
- Prior = 0x00000004, /* Priority on the PCI bus */
- Lrst = 0x00000008, /* Link Reset */
- Asde = 0x00000020, /* Auto-Speed Detection Enable */
- Slu = 0x00000040, /* Set Link Up */
- Ilos = 0x00000080, /* Invert Loss of Signal (LOS) */
- SspeedMASK = 0x00000300, /* Speed Selection */
- SspeedSHIFT = 8,
- Sspeed10 = 0x00000000, /* 10Mb/s */
- Sspeed100 = 0x00000100, /* 100Mb/s */
- Sspeed1000 = 0x00000200, /* 1000Mb/s */
- Frcspd = 0x00000800, /* Force Speed */
- Frcdplx = 0x00001000, /* Force Duplex */
- SwdpinsloMASK = 0x003C0000, /* Software Defined Pins - lo nibble */
- SwdpinsloSHIFT = 18,
- SwdpioloMASK = 0x03C00000, /* Software Defined Pins - I or O */
- SwdpioloSHIFT = 22,
- Devrst = 0x04000000, /* Device Reset */
- Rfce = 0x08000000, /* Receive Flow Control Enable */
- Tfce = 0x10000000, /* Transmit Flow Control Enable */
- Vme = 0x40000000, /* VLAN Mode Enable */
-};
-
-enum { /* Status */
- Lu = 0x00000002, /* Link Up */
- Tckok = 0x00000004, /* Transmit clock is running */
- Rbcok = 0x00000008, /* Receive clock is running */
- Txoff = 0x00000010, /* Transmission Paused */
- Tbimode = 0x00000020, /* TBI Mode Indication */
- LspeedMASK = 0x000000C0, /* Link Speed Setting */
- LspeedSHIFT = 6,
- Lspeed10 = 0x00000000, /* 10Mb/s */
- Lspeed100 = 0x00000040, /* 100Mb/s */
- Lspeed1000 = 0x00000080, /* 1000Mb/s */
- Mtxckok = 0x00000400, /* MTX clock is running */
- Pci66 = 0x00000800, /* PCI Bus speed indication */
- Bus64 = 0x00001000, /* PCI Bus width indication */
- Pcixmode = 0x00002000, /* PCI-X mode */
- PcixspeedMASK = 0x0000C000, /* PCI-X bus speed */
- PcixspeedSHIFT = 14,
- Pcix66 = 0x00000000, /* 50-66MHz */
- Pcix100 = 0x00004000, /* 66-100MHz */
- Pcix133 = 0x00008000, /* 100-133MHz */
-};
-
-enum { /* Ctrl and Status */
- Fd = 0x00000001, /* Full-Duplex */
- AsdvMASK = 0x00000300,
- AsdvSHIFT = 8,
- Asdv10 = 0x00000000, /* 10Mb/s */
- Asdv100 = 0x00000100, /* 100Mb/s */
- Asdv1000 = 0x00000200, /* 1000Mb/s */
-};
-
-enum { /* Eecd */
- Sk = 0x00000001, /* Clock input to the EEPROM */
- Cs = 0x00000002, /* Chip Select */
- Di = 0x00000004, /* Data Input to the EEPROM */
- Do = 0x00000008, /* Data Output from the EEPROM */
- Areq = 0x00000040, /* EEPROM Access Request */
- Agnt = 0x00000080, /* EEPROM Access Grant */
- Eepresent = 0x00000100, /* EEPROM Present */
- Eesz256 = 0x00000200, /* EEPROM is 256 words not 64 */
- Eeszaddr = 0x00000400, /* EEPROM size for 8254[17] */
- Spi = 0x00002000, /* EEPROM is SPI not Microwire */
-};
-
-enum { /* Ctrlext */
- Gpien = 0x0000000F, /* General Purpose Interrupt Enables */
- SwdpinshiMASK = 0x000000F0, /* Software Defined Pins - hi nibble */
- SwdpinshiSHIFT = 4,
- SwdpiohiMASK = 0x00000F00, /* Software Defined Pins - I or O */
- SwdpiohiSHIFT = 8,
- Asdchk = 0x00001000, /* ASD Check */
- Eerst = 0x00002000, /* EEPROM Reset */
- Ips = 0x00004000, /* Invert Power State */
- Spdbyps = 0x00008000, /* Speed Select Bypass */
-};
-
-enum { /* EEPROM content offsets */
- Ea = 0x00, /* Ethernet Address */
- Cf = 0x03, /* Compatibility Field */
- Pba = 0x08, /* Printed Board Assembly number */
- Icw1 = 0x0A, /* Initialization Control Word 1 */
- Sid = 0x0B, /* Subsystem ID */
- Svid = 0x0C, /* Subsystem Vendor ID */
- Did = 0x0D, /* Device ID */
- Vid = 0x0E, /* Vendor ID */
- Icw2 = 0x0F, /* Initialization Control Word 2 */
-};
-
-enum { /* Mdic */
- MDIdMASK = 0x0000FFFF, /* Data */
- MDIdSHIFT = 0,
- MDIrMASK = 0x001F0000, /* PHY Register Address */
- MDIrSHIFT = 16,
- MDIpMASK = 0x03E00000, /* PHY Address */
- MDIpSHIFT = 21,
- MDIwop = 0x04000000, /* Write Operation */
- MDIrop = 0x08000000, /* Read Operation */
- MDIready = 0x10000000, /* End of Transaction */
- MDIie = 0x20000000, /* Interrupt Enable */
- MDIe = 0x40000000, /* Error */
-};
-
-enum { /* Icr, Ics, Ims, Imc */
- Txdw = 0x00000001, /* Transmit Descriptor Written Back */
- Txqe = 0x00000002, /* Transmit Queue Empty */
- Lsc = 0x00000004, /* Link Status Change */
- Rxseq = 0x00000008, /* Receive Sequence Error */
- Rxdmt0 = 0x00000010, /* Rd Minimum Threshold Reached */
- Rxo = 0x00000040, /* Receiver Overrun */
- Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
- Mdac = 0x00000200, /* MDIO Access Completed */
- Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
- Gpi0 = 0x00000800, /* General Purpose Interrupts */
- Gpi1 = 0x00001000,
- Gpi2 = 0x00002000,
- Gpi3 = 0x00004000,
-};
-
-/*
- * The Mdic register isn't implemented on the 82543GC,
- * the software defined pins are used instead.
- * These definitions work for the Intel PRO/1000 T Server Adapter.
- * The direction pin bits are read from the EEPROM.
- */
-enum {
- Mdd = ((1<<2)<<SwdpinsloSHIFT), /* data */
- Mddo = ((1<<2)<<SwdpioloSHIFT), /* pin direction */
- Mdc = ((1<<3)<<SwdpinsloSHIFT), /* clock */
- Mdco = ((1<<3)<<SwdpioloSHIFT), /* pin direction */
- Mdr = ((1<<0)<<SwdpinshiSHIFT), /* reset */
- Mdro = ((1<<0)<<SwdpiohiSHIFT), /* pin direction */
-};
-
-enum { /* Txcw */
- TxcwFd = 0x00000020, /* Full Duplex */
- TxcwHd = 0x00000040, /* Half Duplex */
- TxcwPauseMASK = 0x00000180, /* Pause */
- TxcwPauseSHIFT = 7,
- TxcwPs = (1<<TxcwPauseSHIFT), /* Pause Supported */
- TxcwAs = (2<<TxcwPauseSHIFT), /* Asymmetric FC desired */
- TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
- TxcwRfiSHIFT = 12,
- TxcwNpr = 0x00008000, /* Next Page Request */
- TxcwConfig = 0x40000000, /* Transmit COnfig Control */
- TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
-};
-
-enum { /* Rxcw */
- Rxword = 0x0000FFFF, /* Data from auto-negotiation process */
- Rxnocarrier = 0x04000000, /* Carrier Sense indication */
- Rxinvalid = 0x08000000, /* Invalid Symbol during configuration */
- Rxchange = 0x10000000, /* Change to the Rxword indication */
- Rxconfig = 0x20000000, /* /C/ order set reception indication */
- Rxsync = 0x40000000, /* Lost bit synchronization indication */
- Anc = 0x80000000, /* Auto Negotiation Complete */
-};
-
-enum { /* Rctl */
- Rrst = 0x00000001, /* Receiver Software Reset */
- Ren = 0x00000002, /* Receiver Enable */
- Sbp = 0x00000004, /* Store Bad Packets */
- Upe = 0x00000008, /* Unicast Promiscuous Enable */
- Mpe = 0x00000010, /* Multicast Promiscuous Enable */
- Lpe = 0x00000020, /* Long Packet Reception Enable */
- LbmMASK = 0x000000C0, /* Loopback Mode */
- LbmOFF = 0x00000000, /* No Loopback */
- LbmTBI = 0x00000040, /* TBI Loopback */
- LbmMII = 0x00000080, /* GMII/MII Loopback */
- LbmXCVR = 0x000000C0, /* Transceiver Loopback */
- RdtmsMASK = 0x00000300, /* Rd Minimum Threshold Size */
- RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
- RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
- RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
- MoMASK = 0x00003000, /* Multicast Offset */
- Mo47b36 = 0x00000000, /* bits [47:36] of received address */
- Mo46b35 = 0x00001000, /* bits [46:35] of received address */
- Mo45b34 = 0x00002000, /* bits [45:34] of received address */
- Mo43b32 = 0x00003000, /* bits [43:32] of received address */
- Bam = 0x00008000, /* Broadcast Accept Mode */
- BsizeMASK = 0x00030000, /* Receive Buffer Size */
- Bsize2048 = 0x00000000, /* Bsex = 0 */
- Bsize1024 = 0x00010000, /* Bsex = 0 */
- Bsize512 = 0x00020000, /* Bsex = 0 */
- Bsize256 = 0x00030000, /* Bsex = 0 */
- Bsize16384 = 0x00010000, /* Bsex = 1 */
- Vfe = 0x00040000, /* VLAN Filter Enable */
- Cfien = 0x00080000, /* Canonical Form Indicator Enable */
- Cfi = 0x00100000, /* Canonical Form Indicator value */
- Dpf = 0x00400000, /* Discard Pause Frames */
- Pmcf = 0x00800000, /* Pass MAC Control Frames */
- Bsex = 0x02000000, /* Buffer Size Extension */
- Secrc = 0x04000000, /* Strip CRC from incoming packet */
-};
-
-enum { /* Tctl */
- Trst = 0x00000001, /* Transmitter Software Reset */
- Ten = 0x00000002, /* Transmit Enable */
- Psp = 0x00000008, /* Pad Short Packets */
- CtMASK = 0x00000FF0, /* Collision Threshold */
- CtSHIFT = 4,
- ColdMASK = 0x003FF000, /* Collision Distance */
- ColdSHIFT = 12,
- Swxoff = 0x00400000, /* Sofware XOFF Transmission */
- Pbe = 0x00800000, /* Packet Burst Enable */
- Rtlc = 0x01000000, /* Re-transmit on Late Collision */
- Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
-};
-
-enum { /* [RT]xdctl */
- PthreshMASK = 0x0000003F, /* Prefetch Threshold */
- PthreshSHIFT = 0,
- HthreshMASK = 0x00003F00, /* Host Threshold */
- HthreshSHIFT = 8,
- WthreshMASK = 0x003F0000, /* Writeback Threshold */
- WthreshSHIFT = 16,
- Gran = 0x01000000, /* Granularity */
- LthreshMASK = 0xFE000000, /* Low Threshold */
- LthreshSHIFT = 25,
-};
-
-enum { /* Rxcsum */
- PcssMASK = 0x000000FF, /* Packet Checksum Start */
- PcssSHIFT = 0,
- Ipofl = 0x00000100, /* IP Checksum Off-load Enable */
- Tuofl = 0x00000200, /* TCP/UDP Checksum Off-load Enable */
-};
-
-enum { /* Manc */
- Arpen = 0x00002000, /* Enable ARP Request Filtering */
-};
-
-enum { /* Receive Delay Timer Ring */
- DelayMASK = 0x0000FFFF, /* delay timer in 1.024nS increments */
- DelaySHIFT = 0,
- Fpd = 0x80000000, /* Flush partial Descriptor Block */
-};
-
-typedef struct Rd { /* Receive Descriptor */
- uint addr[2];
- ushort length;
- ushort checksum;
- uchar status;
- uchar errors;
- ushort special;
-} Rd;
-
-enum { /* Rd status */
- Rdd = 0x01, /* Descriptor Done */
- Reop = 0x02, /* End of Packet */
- Ixsm = 0x04, /* Ignore Checksum Indication */
- Vp = 0x08, /* Packet is 802.1Q (matched VET) */
- Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
- Ipcs = 0x40, /* IP Checksum Calculated on Packet */
- Pif = 0x80, /* Passed in-exact filter */
-};
-
-enum { /* Rd errors */
- Ce = 0x01, /* CRC Error or Alignment Error */
- Se = 0x02, /* Symbol Error */
- Seq = 0x04, /* Sequence Error */
- Cxe = 0x10, /* Carrier Extension Error */
- Tcpe = 0x20, /* TCP/UDP Checksum Error */
- Ipe = 0x40, /* IP Checksum Error */
- Rxe = 0x80, /* RX Data Error */
-};
-
-typedef struct Td Td;
-struct Td { /* Transmit Descriptor */
- union {
- uint addr[2]; /* Data */
- struct { /* Context */
- uchar ipcss;
- uchar ipcso;
- ushort ipcse;
- uchar tucss;
- uchar tucso;
- ushort tucse;
- };
- };
- uint control;
- uint status;
-};
-
-enum { /* Td control */
- LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
- LenSHIFT = 0,
- DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
- DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
- PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
- Teop = 0x01000000, /* End of Packet (DD) */
- PtypeIP = 0x02000000, /* IP Packet Type (CD) */
- Ifcs = 0x02000000, /* Insert FCS (DD) */
- Tse = 0x04000000, /* TCP Segmentation Enable */
- Rs = 0x08000000, /* Report Status */
- Rps = 0x10000000, /* Report Status Sent */
- Dext = 0x20000000, /* Descriptor Extension */
- Vle = 0x40000000, /* VLAN Packet Enable */
- Ide = 0x80000000, /* Interrupt Delay Enable */
-};
-
-enum { /* Td status */
- Tdd = 0x00000001, /* Descriptor Done */
- Ec = 0x00000002, /* Excess Collisions */
- Lc = 0x00000004, /* Late Collision */
- Tu = 0x00000008, /* Transmit Underrun */
- Iixsm = 0x00000100, /* Insert IP Checksum */
- Itxsm = 0x00000200, /* Insert TCP/UDP Checksum */
- HdrlenMASK = 0x0000FF00, /* Header Length (Tse) */
- HdrlenSHIFT = 8,
- VlanMASK = 0x0FFF0000, /* VLAN Identifier */
- VlanSHIFT = 16,
- Tcfi = 0x10000000, /* Canonical Form Indicator */
- PriMASK = 0xE0000000, /* User Priority */
- PriSHIFT = 29,
- MssMASK = 0xFFFF0000, /* Maximum Segment Size (Tse) */
- MssSHIFT = 16,
-};
-
-enum {
- Nrd = 256, /* multiple of 8 */
- Ntd = 64, /* multiple of 8 */
- Nrb = 1024, /* private receive buffers per Ctlr */
- Rbsz = 2048,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- Ether* edev;
- int active;
- int started;
- int id;
- int cls;
- ushort eeprom[0x40];
-
- QLock alock; /* attach */
- void* alloc; /* receive/transmit descriptors */
- int nrd;
- int ntd;
- int nrb; /* how many this Ctlr has in the pool */
-
- int* nic;
- Lock imlock;
- int im; /* interrupt mask */
-
- Mii* mii;
- Rendez lrendez;
- int lim;
-
- int link;
-
- QLock slock;
- uint statistics[Nstatistics];
- uint lsleep;
- uint lintr;
- uint rsleep;
- uint rintr;
- uint txdw;
- uint tintr;
- uint ixsm;
- uint ipcs;
- uint tcpcs;
-
- uchar ra[Eaddrlen]; /* receive address */
- ulong mta[128]; /* multicast table array */
-
- Rendez rrendez;
- int rim;
- int rdfree;
- Rd* rdba; /* receive descriptor base address */
- Block** rb; /* receive buffers */
- int rdh; /* receive descriptor head */
- int rdt; /* receive descriptor tail */
- int rdtr; /* receive delay timer ring value */
-
- Lock tlock;
- int tbusy;
- int tdfree;
- Td* tdba; /* transmit descriptor base address */
- Block** tb; /* transmit buffers */
- int tdh; /* transmit descriptor head */
- int tdt; /* transmit descriptor tail */
-
- int txcw;
- int fcrtl;
- int fcrth;
-} Ctlr;
-
-#define csr32r(c, r) (*((c)->nic+((r)/4)))
-#define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
-
-static Ctlr* igbectlrhead;
-static Ctlr* igbectlrtail;
-
-static Lock igberblock; /* free receive Blocks */
-static Block* igberbpool; /* receive Blocks for all igbe controllers */
-
-static char* statistics[Nstatistics] = {
- "CRC Error",
- "Alignment Error",
- "Symbol Error",
- "RX Error",
- "Missed Packets",
- "Single Collision",
- "Excessive Collisions",
- "Multiple Collision",
- "Late Collisions",
- nil,
- "Collision",
- "Transmit Underrun",
- "Defer",
- "Transmit - No CRS",
- "Sequence Error",
- "Carrier Extension Error",
- "Receive Error Length",
- nil,
- "XON Received",
- "XON Transmitted",
- "XOFF Received",
- "XOFF Transmitted",
- "FC Received Unsupported",
- "Packets Received (64 Bytes)",
- "Packets Received (65-127 Bytes)",
- "Packets Received (128-255 Bytes)",
- "Packets Received (256-511 Bytes)",
- "Packets Received (512-1023 Bytes)",
- "Packets Received (1024-1522 Bytes)",
- "Good Packets Received",
- "Broadcast Packets Received",
- "Multicast Packets Received",
- "Good Packets Transmitted",
- nil,
- "Good Octets Received",
- nil,
- "Good Octets Transmitted",
- nil,
- nil,
- nil,
- "Receive No Buffers",
- "Receive Undersize",
- "Receive Fragment",
- "Receive Oversize",
- "Receive Jabber",
- nil,
- nil,
- nil,
- "Total Octets Received",
- nil,
- "Total Octets Transmitted",
- nil,
- "Total Packets Received",
- "Total Packets Transmitted",
- "Packets Transmitted (64 Bytes)",
- "Packets Transmitted (65-127 Bytes)",
- "Packets Transmitted (128-255 Bytes)",
- "Packets Transmitted (256-511 Bytes)",
- "Packets Transmitted (512-1023 Bytes)",
- "Packets Transmitted (1024-1522 Bytes)",
- "Multicast Packets Transmitted",
- "Broadcast Packets Transmitted",
- "TCP Segmentation Context Transmitted",
- "TCP Segmentation Context Fail",
-};
-
-static long
-igbeifstat(Ether* edev, void* a, long n, ulong offset)
-{
- Ctlr *ctlr;
- char *p, *s;
- int i, l, r;
- uvlong tuvl, ruvl;
-
- ctlr = edev->ctlr;
- qlock(&ctlr->slock);
- p = malloc(2*READSTR);
- l = 0;
- for(i = 0; i < Nstatistics; i++){
- r = csr32r(ctlr, Statistics+i*4);
- if((s = statistics[i]) == nil)
- continue;
- switch(i){
- case Gorcl:
- case Gotcl:
- case Torl:
- case Totl:
- ruvl = r;
- ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
- tuvl = ruvl;
- tuvl += ctlr->statistics[i];
- tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
- if(tuvl == 0)
- continue;
- ctlr->statistics[i] = tuvl;
- ctlr->statistics[i+1] = tuvl>>32;
- l += snprint(p+l, 2*READSTR-l, "%s: %llud %llud\n",
- s, tuvl, ruvl);
- i++;
- break;
-
- default:
- ctlr->statistics[i] += r;
- if(ctlr->statistics[i] == 0)
- continue;
- l += snprint(p+l, 2*READSTR-l, "%s: %ud %ud\n",
- s, ctlr->statistics[i], r);
- break;
- }
- }
-
- l += snprint(p+l, 2*READSTR-l, "lintr: %ud %ud\n",
- ctlr->lintr, ctlr->lsleep);
- l += snprint(p+l, 2*READSTR-l, "rintr: %ud %ud\n",
- ctlr->rintr, ctlr->rsleep);
- l += snprint(p+l, 2*READSTR-l, "tintr: %ud %ud\n",
- ctlr->tintr, ctlr->txdw);
- l += snprint(p+l, 2*READSTR-l, "ixcs: %ud %ud %ud\n",
- ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
- l += snprint(p+l, 2*READSTR-l, "rdtr: %ud\n", ctlr->rdtr);
- l += snprint(p+l, 2*READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));
-
- l += snprint(p+l, 2*READSTR-l, "eeprom:");
- for(i = 0; i < 0x40; i++){
- if(i && ((i & 0x07) == 0))
- l += snprint(p+l, 2*READSTR-l, "\n ");
- l += snprint(p+l, 2*READSTR-l, " %4.4uX", ctlr->eeprom[i]);
- }
- l += snprint(p+l, 2*READSTR-l, "\n");
-
- if(ctlr->mii != nil && ctlr->mii->curphy != nil){
- l += snprint(p+l, 2*READSTR, "phy: ");
- for(i = 0; i < NMiiPhyr; i++){
- if(i && ((i & 0x07) == 0))
- l += snprint(p+l, 2*READSTR-l, "\n ");
- r = miimir(ctlr->mii, i);
- l += snprint(p+l, 2*READSTR-l, " %4.4uX", r);
- }
- snprint(p+l, 2*READSTR-l, "\n");
- }
- n = readstr(offset, a, n, p);
- free(p);
- qunlock(&ctlr->slock);
-
- return n;
-}
-
-enum {
- CMrdtr,
-};
-
-static Cmdtab igbectlmsg[] = {
- CMrdtr, "rdtr", 2,
-};
-
-static long
-igbectl(Ether* edev, void* buf, long n)
-{
- int v;
- char *p;
- Ctlr *ctlr;
- Cmdbuf *cb;
- Cmdtab *ct;
-
- if((ctlr = edev->ctlr) == nil)
- error(Enonexist);
-
- cb = parsecmd(buf, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
-
- ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));
- switch(ct->index){
- case CMrdtr:
- v = strtol(cb->f[1], &p, 0);
- if(v < 0 || p == cb->f[1] || v > 0xFFFF)
- error(Ebadarg);
- ctlr->rdtr = v;;
- csr32w(ctlr, Rdtr, Fpd|v);
- break;
- }
- free(cb);
- poperror();
-
- return n;
-}
-
-static void
-igbepromiscuous(void* arg, int on)
-{
- int rctl;
- Ctlr *ctlr;
- Ether *edev;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- rctl = csr32r(ctlr, Rctl);
- rctl &= ~MoMASK;
- rctl |= Mo47b36;
- if(on)
- rctl |= Upe|Mpe;
- else
- rctl &= ~(Upe|Mpe);
- csr32w(ctlr, Rctl, rctl);
-}
-
-static void
-igbemulticast(void* arg, uchar* addr, int on)
-{
- int bit, x;
- Ctlr *ctlr;
- Ether *edev;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- x = addr[5]>>1;
- bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
- if(on)
- ctlr->mta[x] |= 1<<bit;
- else
- ctlr->mta[x] &= ~(1<<bit);
-
- csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
-}
-
-static Block*
-igberballoc(void)
-{
- Block *bp;
-
- ilock(&igberblock);
- if((bp = igberbpool) != nil){
- igberbpool = bp->next;
- bp->next = nil;
- }
- iunlock(&igberblock);
-
- return bp;
-}
-
-static void
-igberbfree(Block* bp)
-{
- bp->rp = bp->lim - Rbsz;
- bp->wp = bp->rp;
-
- ilock(&igberblock);
- bp->next = igberbpool;
- igberbpool = bp;
- iunlock(&igberblock);
-}
-
-static void
-igbeim(Ctlr* ctlr, int im)
-{
- ilock(&ctlr->imlock);
- ctlr->im |= im;
- csr32w(ctlr, Ims, ctlr->im);
- iunlock(&ctlr->imlock);
-}
-
-static int
-igbelim(void* ctlr)
-{
- return ((Ctlr*)ctlr)->lim != 0;
-}
-
-static void
-igbelproc(void* arg)
-{
- Ctlr *ctlr;
- Ether *edev;
- MiiPhy *phy;
- int ctrl, r;
-
- edev = arg;
- ctlr = edev->ctlr;
- for(;;){
- if(ctlr->mii == nil || ctlr->mii->curphy == nil)
- continue;
-
- /*
- * To do:
- * logic to manage status change,
- * this is incomplete but should work
- * one time to set up the hardware.
- *
- * MiiPhy.speed, etc. should be in Mii.
- */
- if(miistatus(ctlr->mii) < 0)
- //continue;
- goto enable;
-
- phy = ctlr->mii->curphy;
- ctrl = csr32r(ctlr, Ctrl);
-
- switch(ctlr->id){
- case i82543gc:
- case i82544ei:
- default:
- if(!(ctrl & Asde)){
- ctrl &= ~(SspeedMASK|Ilos|Fd);
- ctrl |= Frcdplx|Frcspd;
- if(phy->speed == 1000)
- ctrl |= Sspeed1000;
- else if(phy->speed == 100)
- ctrl |= Sspeed100;
- if(phy->fd)
- ctrl |= Fd;
- }
- break;
-
- case i82540em:
- case i82540eplp:
- case i82547gi:
- case i82541gi:
- case i82541gi2:
- case i82541pi:
- break;
- }
-
- /*
- * Collision Distance.
- */
- r = csr32r(ctlr, Tctl);
- r &= ~ColdMASK;
- if(phy->fd)
- r |= 64<<ColdSHIFT;
- else
- r |= 512<<ColdSHIFT;
- csr32w(ctlr, Tctl, r);
-
- /*
- * Flow control.
- */
- if(phy->rfc)
- ctrl |= Rfce;
- if(phy->tfc)
- ctrl |= Tfce;
- csr32w(ctlr, Ctrl, ctrl);
-
-enable:
- ctlr->lim = 0;
- igbeim(ctlr, Lsc);
-
- ctlr->lsleep++;
- sleep(&ctlr->lrendez, igbelim, ctlr);
- }
-}
-
-static void
-igbetxinit(Ctlr* ctlr)
-{
- int i, r;
- Block *bp;
-
- csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
- switch(ctlr->id){
- default:
- r = 6;
- break;
- case i82543gc:
- case i82544ei:
- case i82547ei:
- case i82540em:
- case i82540eplp:
- case i82541gi:
- case i82541gi2:
- case i82541pi:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- case i82547gi:
- r = 8;
- break;
- }
- csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
- csr32w(ctlr, Ait, 0);
- csr32w(ctlr, Txdmac, 0);
-
- csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
- csr32w(ctlr, Tdbah, 0);
- csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
- ctlr->tdh = PREV(0, ctlr->ntd);
- csr32w(ctlr, Tdh, 0);
- ctlr->tdt = 0;
- csr32w(ctlr, Tdt, 0);
-
- for(i = 0; i < ctlr->ntd; i++){
- if((bp = ctlr->tb[i]) != nil){
- ctlr->tb[i] = nil;
- freeb(bp);
- }
- memset(&ctlr->tdba[i], 0, sizeof(Td));
- }
- ctlr->tdfree = ctlr->ntd;
-
- csr32w(ctlr, Tidv, 128);
- r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
-
- switch(ctlr->id){
- default:
- break;
- case i82540em:
- case i82540eplp:
- case i82547gi:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- case i82541gi:
- case i82541gi2:
- case i82541pi:
- r = csr32r(ctlr, Txdctl);
- r &= ~WthreshMASK;
- r |= Gran|(4<<WthreshSHIFT);
-
- csr32w(ctlr, Tadv, 64);
- break;
- }
-
- csr32w(ctlr, Txdctl, r);
-
- r = csr32r(ctlr, Tctl);
- r |= Ten;
- csr32w(ctlr, Tctl, r);
-}
-
-static void
-igbetransmit(Ether* edev)
-{
- Td *td;
- Block *bp;
- Ctlr *ctlr;
- int tdh, tdt;
-
- ctlr = edev->ctlr;
-
- ilock(&ctlr->tlock);
-
- /*
- * Free any completed packets
- */
- tdh = ctlr->tdh;
- while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
- if((bp = ctlr->tb[tdh]) != nil){
- ctlr->tb[tdh] = nil;
- freeb(bp);
- }
- memset(&ctlr->tdba[tdh], 0, sizeof(Td));
- tdh = NEXT(tdh, ctlr->ntd);
- }
- ctlr->tdh = tdh;
-
- /*
- * Try to fill the ring back up.
- */
- tdt = ctlr->tdt;
- while(NEXT(tdt, ctlr->ntd) != tdh){
- if((bp = qget(edev->oq)) == nil)
- break;
- td = &ctlr->tdba[tdt];
- td->addr[0] = PCIWADDR(bp->rp);
- td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
- td->control |= Dext|Ifcs|Teop|DtypeDD;
- ctlr->tb[tdt] = bp;
- tdt = NEXT(tdt, ctlr->ntd);
- if(NEXT(tdt, ctlr->ntd) == tdh){
- td->control |= Rs;
- ctlr->txdw++;
- ctlr->tdt = tdt;
- csr32w(ctlr, Tdt, tdt);
- igbeim(ctlr, Txdw);
- break;
- }
- ctlr->tdt = tdt;
- csr32w(ctlr, Tdt, tdt);
- }
-
- iunlock(&ctlr->tlock);
-}
-
-static void
-igbereplenish(Ctlr* ctlr)
-{
- Rd *rd;
- int rdt;
- Block *bp;
-
- rdt = ctlr->rdt;
- while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
- rd = &ctlr->rdba[rdt];
- if(ctlr->rb[rdt] == nil){
- bp = igberballoc();
- if(bp == nil){
- iprint("#l%d: igbereplenish: no available buffers\n",
- ctlr->edev->ctlrno);
- break;
- }
- ctlr->rb[rdt] = bp;
- rd->addr[0] = PCIWADDR(bp->rp);
- rd->addr[1] = 0;
- }
- coherence();
- rd->status = 0;
- rdt = NEXT(rdt, ctlr->nrd);
- ctlr->rdfree++;
- }
- ctlr->rdt = rdt;
- csr32w(ctlr, Rdt, rdt);
-}
-
-static void
-igberxinit(Ctlr* ctlr)
-{
- int i;
- Block *bp;
-
- csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
-
- csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
- csr32w(ctlr, Rdbah, 0);
- csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
- ctlr->rdh = 0;
- csr32w(ctlr, Rdh, 0);
- ctlr->rdt = 0;
- csr32w(ctlr, Rdt, 0);
- ctlr->rdtr = 0;
- csr32w(ctlr, Rdtr, Fpd|0);
-
- for(i = 0; i < ctlr->nrd; i++){
- if((bp = ctlr->rb[i]) != nil){
- ctlr->rb[i] = nil;
- freeb(bp);
- }
- }
- igbereplenish(ctlr);
-
- switch(ctlr->id){
- case i82540em:
- case i82540eplp:
- case i82541gi:
- case i82541gi2:
- case i82541pi:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- case i82547gi:
- csr32w(ctlr, Radv, 64);
- break;
- }
- csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
-
- /*
- * Enable checksum offload.
- */
- csr32w(ctlr, Rxcsum, Tuofl|Ipofl|(ETHERHDRSIZE<<PcssSHIFT));
-}
-
-static int
-igberim(void* ctlr)
-{
- return ((Ctlr*)ctlr)->rim != 0;
-}
-
-static void
-igberproc(void* arg)
-{
- Rd *rd;
- Block *bp;
- Ctlr *ctlr;
- int r, rdh;
- Ether *edev;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- igberxinit(ctlr);
- r = csr32r(ctlr, Rctl);
- r |= Ren;
- csr32w(ctlr, Rctl, r);
-
- for(;;){
- ctlr->rim = 0;
- igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
- ctlr->rsleep++;
- sleep(&ctlr->rrendez, igberim, ctlr);
-
- rdh = ctlr->rdh;
- for(;;){
- rd = &ctlr->rdba[rdh];
-
- if(!(rd->status & Rdd))
- break;
-
- /*
- * Accept eop packets with no errors.
- * With no errors and the Ixsm bit set,
- * the descriptor status Tpcs and Ipcs bits give
- * an indication of whether the checksums were
- * calculated and valid.
- */
- if((rd->status & Reop) && rd->errors == 0){
- bp = ctlr->rb[rdh];
- ctlr->rb[rdh] = nil;
- bp->wp += rd->length;
- bp->next = nil;
- if(!(rd->status & Ixsm)){
- ctlr->ixsm++;
- if(rd->status & Ipcs){
- /*
- * IP checksum calculated
- * (and valid as errors == 0).
- */
- ctlr->ipcs++;
- bp->flag |= Bipck;
- }
- if(rd->status & Tcpcs){
- /*
- * TCP/UDP checksum calculated
- * (and valid as errors == 0).
- */
- ctlr->tcpcs++;
- bp->flag |= Btcpck|Budpck;
- }
- bp->checksum = rd->checksum;
- bp->flag |= Bpktck;
- }
- etheriq(edev, bp, 1);
- }
- else if(ctlr->rb[rdh] != nil){
- freeb(ctlr->rb[rdh]);
- ctlr->rb[rdh] = nil;
- }
-
- memset(rd, 0, sizeof(Rd));
- coherence();
- ctlr->rdfree--;
- rdh = NEXT(rdh, ctlr->nrd);
- }
- ctlr->rdh = rdh;
-
- if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
- igbereplenish(ctlr);
- }
-}
-
-static void
-igbeattach(Ether* edev)
-{
- Block *bp;
- Ctlr *ctlr;
- char name[KNAMELEN];
-
- ctlr = edev->ctlr;
- ctlr->edev = edev; /* point back to Ether* */
- qlock(&ctlr->alock);
- if(ctlr->alloc != nil){
- qunlock(&ctlr->alock);
- return;
- }
-
- ctlr->nrd = ROUND(Nrd, 8);
- ctlr->ntd = ROUND(Ntd, 8);
- ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 127);
- if(ctlr->alloc == nil){
- qunlock(&ctlr->alock);
- return;
- }
- ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 128);
- ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
-
- ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
- ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
-
- if(waserror()){
- while(ctlr->nrb > 0){
- bp = igberballoc();
- bp->free = nil;
- freeb(bp);
- ctlr->nrb--;
- }
- free(ctlr->tb);
- ctlr->tb = nil;
- free(ctlr->rb);
- ctlr->rb = nil;
- free(ctlr->alloc);
- ctlr->alloc = nil;
- qunlock(&ctlr->alock);
- nexterror();
- }
-
- for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
- if((bp = allocb(Rbsz)) == nil)
- break;
- bp->free = igberbfree;
- freeb(bp);
- }
-
- snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
- kproc(name, igbelproc, edev, 0);
-
- snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
- kproc(name, igberproc, edev, 0);
-
- igbetxinit(ctlr);
-
- qunlock(&ctlr->alock);
- poperror();
-}
-
-static void
-igbeinterrupt(Ureg*, void* arg)
-{
- Ctlr *ctlr;
- Ether *edev;
- int icr, im, txdw;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- ilock(&ctlr->imlock);
- csr32w(ctlr, Imc, ~0);
- im = ctlr->im;
- txdw = 0;
-
- while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
- if(icr & Lsc){
- im &= ~Lsc;
- ctlr->lim = icr & Lsc;
- wakeup(&ctlr->lrendez);
- ctlr->lintr++;
- }
- if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq)){
- im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq);
- ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq);
- wakeup(&ctlr->rrendez);
- ctlr->rintr++;
- }
- if(icr & Txdw){
- im &= ~Txdw;
- txdw++;
- ctlr->tintr++;
- }
- }
-
- ctlr->im = im;
- csr32w(ctlr, Ims, im);
- iunlock(&ctlr->imlock);
-
- if(txdw)
- igbetransmit(edev);
-}
-
-static int
-i82543mdior(Ctlr* ctlr, int n)
-{
- int ctrl, data, i, r;
-
- /*
- * Read n bits from the Management Data I/O Interface.
- */
- ctrl = csr32r(ctlr, Ctrl);
- r = (ctrl & ~Mddo)|Mdco;
- data = 0;
- for(i = n-1; i >= 0; i--){
- if(csr32r(ctlr, Ctrl) & Mdd)
- data |= (1<<i);
- csr32w(ctlr, Ctrl, Mdc|r);
- csr32w(ctlr, Ctrl, r);
- }
- csr32w(ctlr, Ctrl, ctrl);
-
- return data;
-}
-
-static int
-i82543mdiow(Ctlr* ctlr, int bits, int n)
-{
- int ctrl, i, r;
-
- /*
- * Write n bits to the Management Data I/O Interface.
- */
- ctrl = csr32r(ctlr, Ctrl);
- r = Mdco|Mddo|ctrl;
- for(i = n-1; i >= 0; i--){
- if(bits & (1<<i))
- r |= Mdd;
- else
- r &= ~Mdd;
- csr32w(ctlr, Ctrl, Mdc|r);
- csr32w(ctlr, Ctrl, r);
- }
- csr32w(ctlr, Ctrl, ctrl);
-
- return 0;
-}
-
-static int
-i82543miimir(Mii* mii, int pa, int ra)
-{
- int data;
- Ctlr *ctlr;
-
- ctlr = mii->ctlr;
-
- /*
- * MII Management Interface Read.
- *
- * Preamble;
- * ST+OP+PHYAD+REGAD;
- * TA + 16 data bits.
- */
- i82543mdiow(ctlr, 0xFFFFFFFF, 32);
- i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
- data = i82543mdior(ctlr, 18);
-
- if(data & 0x10000)
- return -1;
-
- return data & 0xFFFF;
-}
-
-static int
-i82543miimiw(Mii* mii, int pa, int ra, int data)
-{
- Ctlr *ctlr;
-
- ctlr = mii->ctlr;
-
- /*
- * MII Management Interface Write.
- *
- * Preamble;
- * ST+OP+PHYAD+REGAD+TA + 16 data bits;
- * Z.
- */
- i82543mdiow(ctlr, 0xFFFFFFFF, 32);
- data &= 0xFFFF;
- data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
- i82543mdiow(ctlr, data, 32);
-
- return 0;
-}
-
-static int
-igbemiimir(Mii* mii, int pa, int ra)
-{
- Ctlr *ctlr;
- int mdic, timo;
-
- ctlr = mii->ctlr;
-
- csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
- mdic = 0;
- for(timo = 64; timo; timo--){
- mdic = csr32r(ctlr, Mdic);
- if(mdic & (MDIe|MDIready))
- break;
- microdelay(1);
- }
-
- if((mdic & (MDIe|MDIready)) == MDIready)
- return mdic & 0xFFFF;
- return -1;
-}
-
-static int
-igbemiimiw(Mii* mii, int pa, int ra, int data)
-{
- Ctlr *ctlr;
- int mdic, timo;
-
- ctlr = mii->ctlr;
-
- data &= MDIdMASK;
- csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
- mdic = 0;
- for(timo = 64; timo; timo--){
- mdic = csr32r(ctlr, Mdic);
- if(mdic & (MDIe|MDIready))
- break;
- microdelay(1);
- }
- if((mdic & (MDIe|MDIready)) == MDIready)
- return 0;
- return -1;
-}
-
-static int
-igbemii(Ctlr* ctlr)
-{
- MiiPhy *phy;
- int ctrl, p, r;
-
- r = csr32r(ctlr, Status);
- if(r & Tbimode)
- return -1;
- if((ctlr->mii = malloc(sizeof(Mii))) == nil)
- return -1;
- ctlr->mii->ctlr = ctlr;
-
- ctrl = csr32r(ctlr, Ctrl);
- ctrl |= Slu;
-
- switch(ctlr->id){
- case i82543gc:
- ctrl |= Frcdplx|Frcspd;
- csr32w(ctlr, Ctrl, ctrl);
-
- /*
- * The reset pin direction (Mdro) should already
- * be set from the EEPROM load.
- * If it's not set this configuration is unexpected
- * so bail.
- */
- r = csr32r(ctlr, Ctrlext);
- if(!(r & Mdro))
- return -1;
- csr32w(ctlr, Ctrlext, r);
- delay(20);
- r = csr32r(ctlr, Ctrlext);
- r &= ~Mdr;
- csr32w(ctlr, Ctrlext, r);
- delay(20);
- r = csr32r(ctlr, Ctrlext);
- r |= Mdr;
- csr32w(ctlr, Ctrlext, r);
- delay(20);
-
- ctlr->mii->mir = i82543miimir;
- ctlr->mii->miw = i82543miimiw;
- break;
- case i82544ei:
- case i82547ei:
- case i82540em:
- case i82540eplp:
- case i82547gi:
- case i82541gi:
- case i82541gi2:
- case i82541pi:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- ctrl &= ~(Frcdplx|Frcspd);
- csr32w(ctlr, Ctrl, ctrl);
- ctlr->mii->mir = igbemiimir;
- ctlr->mii->miw = igbemiimiw;
- break;
- default:
- free(ctlr->mii);
- ctlr->mii = nil;
- return -1;
- }
-
- if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
- free(ctlr->mii);
- ctlr->mii = nil;
- return -1;
- }
- USED(phy);
- // print("oui %X phyno %d\n", phy->oui, phy->phyno);
-
- /*
- * 8254X-specific PHY registers not in 802.3:
- * 0x10 PHY specific control
- * 0x14 extended PHY specific control
- * Set appropriate values then reset the PHY to have
- * changes noted.
- */
- switch(ctlr->id){
- case i82547gi:
- case i82541gi:
- case i82541gi2:
- case i82541pi:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- break;
- default:
- r = miimir(ctlr->mii, 16);
- r |= 0x0800; /* assert CRS on Tx */
- r |= 0x0060; /* auto-crossover all speeds */
- r |= 0x0002; /* polarity reversal enabled */
- miimiw(ctlr->mii, 16, r);
-
- r = miimir(ctlr->mii, 20);
- r |= 0x0070; /* +25MHz clock */
- r &= ~0x0F00;
- r |= 0x0100; /* 1x downshift */
- miimiw(ctlr->mii, 20, r);
-
- miireset(ctlr->mii);
- p = 0;
- if(ctlr->txcw & TxcwPs)
- p |= AnaP;
- if(ctlr->txcw & TxcwAs)
- p |= AnaAP;
- miiane(ctlr->mii, ~0, p, ~0);
- break;
- }
- return 0;
-}
-
-static int
-at93c46io(Ctlr* ctlr, char* op, int data)
-{
- char *lp, *p;
- int i, loop, eecd, r;
-
- eecd = csr32r(ctlr, Eecd);
-
- r = 0;
- loop = -1;
- lp = nil;
- for(p = op; *p != '\0'; p++){
- switch(*p){
- default:
- return -1;
- case ' ':
- continue;
- case ':': /* start of loop */
- loop = strtol(p+1, &lp, 0)-1;
- lp--;
- if(p == lp)
- loop = 7;
- p = lp;
- continue;
- case ';': /* end of loop */
- if(lp == nil)
- return -1;
- loop--;
- if(loop >= 0)
- p = lp;
- else
- lp = nil;
- continue;
- case 'C': /* assert clock */
- eecd |= Sk;
- break;
- case 'c': /* deassert clock */
- eecd &= ~Sk;
- break;
- case 'D': /* next bit in 'data' byte */
- if(loop < 0)
- return -1;
- if(data & (1<<loop))
- eecd |= Di;
- else
- eecd &= ~Di;
- break;
- case 'O': /* collect data output */
- i = (csr32r(ctlr, Eecd) & Do) != 0;
- if(loop >= 0)
- r |= (i<<loop);
- else
- r = i;
- continue;
- case 'I': /* assert data input */
- eecd |= Di;
- break;
- case 'i': /* deassert data input */
- eecd &= ~Di;
- break;
- case 'S': /* enable chip select */
- eecd |= Cs;
- break;
- case 's': /* disable chip select */
- eecd &= ~Cs;
- break;
- }
- csr32w(ctlr, Eecd, eecd);
- microdelay(50);
- }
- if(loop >= 0)
- return -1;
- return r;
-}
-
-static int
-at93c46r(Ctlr* ctlr)
-{
- ushort sum;
- char rop[20];
- int addr, areq, bits, data, eecd, i;
-
- eecd = csr32r(ctlr, Eecd);
- if(eecd & Spi){
- print("igbe: SPI EEPROM access not implemented\n");
- return 0;
- }
- if(eecd & (Eeszaddr|Eesz256))
- bits = 8;
- else
- bits = 6;
-
- sum = 0;
-
- switch(ctlr->id){
- default:
- areq = 0;
- break;
- case i82541gi:
- case i82547gi:
- case i82540em:
- case i82540eplp:
- case i82541pi:
- case i82541gi2:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- areq = 1;
- csr32w(ctlr, Eecd, eecd|Areq);
- for(i = 0; i < 1000; i++){
- if((eecd = csr32r(ctlr, Eecd)) & Agnt)
- break;
- microdelay(5);
- }
- if(!(eecd & Agnt)){
- print("igbe: not granted EEPROM access\n");
- goto release;
- }
- break;
- }
- snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
-
- for(addr = 0; addr < 0x40; addr++){
- /*
- * Read a word at address 'addr' from the Atmel AT93C46
- * 3-Wire Serial EEPROM or compatible. The EEPROM access is
- * controlled by 4 bits in Eecd. See the AT93C46 datasheet
- * for protocol details.
- */
- if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
- print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
- goto release;
- }
- data = at93c46io(ctlr, ":16COc;", 0);
- at93c46io(ctlr, "sic", 0);
- ctlr->eeprom[addr] = data;
- sum += data;
- }
-
-release:
- if(areq)
- csr32w(ctlr, Eecd, eecd & ~Areq);
- return sum;
-}
-
-static int
-igbedetach(Ctlr* ctlr)
-{
- int r, timeo;
-
- /*
- * Perform a device reset to get the chip back to the
- * power-on state, followed by an EEPROM reset to read
- * the defaults for some internal registers.
- */
- csr32w(ctlr, Imc, ~0);
- csr32w(ctlr, Rctl, 0);
- csr32w(ctlr, Tctl, 0);
-
- delay(10);
-
- csr32w(ctlr, Ctrl, Devrst);
- delay(1);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr32r(ctlr, Ctrl) & Devrst))
- break;
- delay(1);
- }
- if(csr32r(ctlr, Ctrl) & Devrst)
- return -1;
- r = csr32r(ctlr, Ctrlext);
- csr32w(ctlr, Ctrlext, r|Eerst);
- delay(1);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr32r(ctlr, Ctrlext) & Eerst))
- break;
- delay(1);
- }
- if(csr32r(ctlr, Ctrlext) & Eerst)
- return -1;
-
- switch(ctlr->id){
- default:
- break;
- case i82540em:
- case i82540eplp:
- case i82541gi:
- case i82541pi:
- case i82547gi:
- case i82541gi2:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- r = csr32r(ctlr, Manc);
- r &= ~Arpen;
- csr32w(ctlr, Manc, r);
- break;
- }
-
- csr32w(ctlr, Imc, ~0);
- delay(1);
- for(timeo = 0; timeo < 1000; timeo++){
- if(!csr32r(ctlr, Icr))
- break;
- delay(1);
- }
- if(csr32r(ctlr, Icr))
- return -1;
-
- return 0;
-}
-
-static void
-igbeshutdown(Ether* ether)
-{
- igbedetach(ether->ctlr);
-}
-
-static int
-igbereset(Ctlr* ctlr)
-{
- int ctrl, i, pause, r, swdpio, txcw;
-
- if(igbedetach(ctlr))
- return -1;
-
- /*
- * Read the EEPROM, validate the checksum
- * then get the device back to a power-on state.
- */
- if((r = at93c46r(ctlr)) != 0xBABA){
- print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
- return -1;
- }
-
- /*
- * Snarf and set up the receive addresses.
- * There are 16 addresses. The first should be the MAC address.
- * The others are cleared and not marked valid (MS bit of Rah).
- */
- if ((ctlr->id == i82546gb || ctlr->id == i82546eb) && BUSFNO(ctlr->pcidev->tbdf) == 1)
- ctlr->eeprom[Ea+2] += 0x100; // second interface
- for(i = Ea; i < Eaddrlen/2; i++){
-if(i == Ea && ctlr->id == i82541gi && ctlr->eeprom[i] == 0xFFFF)
- ctlr->eeprom[i] = 0xD000;
- ctlr->ra[2*i] = ctlr->eeprom[i];
- ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
- }
- r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
- csr32w(ctlr, Ral, r);
- r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
- csr32w(ctlr, Rah, r);
- for(i = 1; i < 16; i++){
- csr32w(ctlr, Ral+i*8, 0);
- csr32w(ctlr, Rah+i*8, 0);
- }
-
- /*
- * Clear the Multicast Table Array.
- * It's a 4096 bit vector accessed as 128 32-bit registers.
- */
- memset(ctlr->mta, 0, sizeof(ctlr->mta));
- for(i = 0; i < 128; i++)
- csr32w(ctlr, Mta+i*4, 0);
-
- /*
- * Just in case the Eerst didn't load the defaults
- * (doesn't appear to fully on the 82543GC), do it manually.
- */
- if (ctlr->id == i82543gc) {
- txcw = csr32r(ctlr, Txcw);
- txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
- ctrl = csr32r(ctlr, Ctrl);
- ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
-
- if(ctlr->eeprom[Icw1] & 0x0400){
- ctrl |= Fd;
- txcw |= TxcwFd;
- }
- if(ctlr->eeprom[Icw1] & 0x0200)
- ctrl |= Lrst;
- if(ctlr->eeprom[Icw1] & 0x0010)
- ctrl |= Ilos;
- if(ctlr->eeprom[Icw1] & 0x0800)
- ctrl |= Frcspd;
- swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
- ctrl |= swdpio<<SwdpioloSHIFT;
- csr32w(ctlr, Ctrl, ctrl);
-
- ctrl = csr32r(ctlr, Ctrlext);
- ctrl &= ~(Ips|SwdpiohiMASK);
- swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
- if(ctlr->eeprom[Icw1] & 0x1000)
- ctrl |= Ips;
- ctrl |= swdpio<<SwdpiohiSHIFT;
- csr32w(ctlr, Ctrlext, ctrl);
-
- if(ctlr->eeprom[Icw2] & 0x0800)
- txcw |= TxcwAne;
- pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
- txcw |= pause<<TxcwPauseSHIFT;
- switch(pause){
- default:
- ctlr->fcrtl = 0x00002000;
- ctlr->fcrth = 0x00004000;
- txcw |= TxcwAs|TxcwPs;
- break;
- case 0:
- ctlr->fcrtl = 0x00002000;
- ctlr->fcrth = 0x00004000;
- break;
- case 2:
- ctlr->fcrtl = 0;
- ctlr->fcrth = 0;
- txcw |= TxcwAs;
- break;
- }
- ctlr->txcw = txcw;
- csr32w(ctlr, Txcw, txcw);
- }
-
-
- /*
- * Flow control - values from the datasheet.
- */
- csr32w(ctlr, Fcal, 0x00C28001);
- csr32w(ctlr, Fcah, 0x00000100);
- csr32w(ctlr, Fct, 0x00008808);
- csr32w(ctlr, Fcttv, 0x00000100);
-
- csr32w(ctlr, Fcrtl, ctlr->fcrtl);
- csr32w(ctlr, Fcrth, ctlr->fcrth);
-
- if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0)
- return -1;
-
- return 0;
-}
-
-static void
-igbepci(void)
-{
- int cls;
- Pcidev *p;
- Ctlr *ctlr;
- void *mem;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != 0x02 || p->ccru != 0)
- continue;
-
- switch((p->did<<16)|p->vid){
- default:
- continue;
- case i82543gc:
- case i82544ei:
- case i82547ei:
- case i82540em:
- case i82540eplp:
- case i82541gi:
- case i82547gi:
- case i82541gi2:
- case i82541pi:
- case i82545gmc:
- case i82546gb:
- case i82546eb:
- break;
- }
-
- mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
- if(mem == nil){
- print("igbe: can't map %8.8luX\n", p->mem[0].bar);
- continue;
- }
- cls = pcicfgr8(p, PciCLS);
- switch(cls){
- default:
- print("igbe: unexpected CLS - %d\n", cls*4);
- break;
- case 0x00:
- case 0xFF:
- print("igbe: unusable CLS\n");
- continue;
- case 0x08:
- case 0x10:
- break;
- }
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = p->mem[0].bar & ~0x0F;
- ctlr->pcidev = p;
- ctlr->id = (p->did<<16)|p->vid;
- ctlr->cls = cls*4;
- ctlr->nic = mem;
-
- if(igbereset(ctlr)){
- free(ctlr);
- vunmap(mem, p->mem[0].size);
- continue;
- }
- pcisetbme(p);
-
- if(igbectlrhead != nil)
- igbectlrtail->next = ctlr;
- else
- igbectlrhead = ctlr;
- igbectlrtail = ctlr;
- }
-}
-
-static int
-igbepnp(Ether* edev)
-{
- Ctlr *ctlr;
-
- if(igbectlrhead == nil)
- igbepci();
-
- /*
- * Any adapter matches if no edev->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = igbectlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(edev->port == 0 || edev->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- edev->ctlr = ctlr;
- edev->port = ctlr->port;
- edev->irq = ctlr->pcidev->intl;
- edev->tbdf = ctlr->pcidev->tbdf;
- edev->mbps = 1000;
- memmove(edev->ea, ctlr->ra, Eaddrlen);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- edev->attach = igbeattach;
- edev->transmit = igbetransmit;
- edev->interrupt = igbeinterrupt;
- edev->ifstat = igbeifstat;
- edev->ctl = igbectl;
-
- edev->arg = edev;
- edev->promiscuous = igbepromiscuous;
- edev->shutdown = igbeshutdown;
- edev->multicast = igbemulticast;
-
- return 0;
-}
-
-void
-etherigbelink(void)
-{
- addethercard("i82543", igbepnp);
- addethercard("igbe", igbepnp);
-}
-
diff --git a/os/pc/etherrhine.c b/os/pc/etherrhine.c
deleted file mode 100644
index 5d25a6f0..00000000
--- a/os/pc/etherrhine.c
+++ /dev/null
@@ -1,734 +0,0 @@
- /*
- Via Rhine driver, written for VT6102.
- Uses the ethermii to control PHY.
-
- Currently always copies on both, tx and rx.
- rx side could be copy-free, and tx-side might be made
- (almost) copy-free by using (possibly) two descriptors (if it allows
- arbitrary tx lengths, which it should..): first for alignment and
- second for rest of the frame. Rx-part should be worth doing.
-*/
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-#include "etherif.h"
-
-#include "ethermii.h"
-
-typedef struct Desc Desc;
-typedef struct Ctlr Ctlr;
-
-enum {
- Ntxd = 16,
- Nrxd = 64,
- Nwait = 50,
- Ntxstats = 9,
- Nrxstats = 8,
- BIGSTR = 8192,
-};
-
-struct Desc {
- ulong stat;
- ulong size;
- ulong addr;
- ulong next;
- char *buf;
- ulong pad[3];
-};
-
-struct Ctlr {
- Pcidev *pci;
- int attached;
- int txused;
- int txhead;
- int txtail;
- int rxtail;
- ulong port;
-
- Mii mii;
-
- ulong txstats[Ntxstats];
- ulong rxstats[Nrxstats];
-
- Desc *txd; /* wants to be aligned on 16-byte boundary */
- Desc *rxd;
-
- QLock attachlck;
- Lock lock;
-};
-
-#define ior8(c, r) (inb((c)->port+(r)))
-#define ior16(c, r) (ins((c)->port+(r)))
-#define ior32(c, r) (inl((c)->port+(r)))
-#define iow8(c, r, b) (outb((c)->port+(r), (int)(b)))
-#define iow16(c, r, w) (outs((c)->port+(r), (ushort)(w)))
-#define iow32(c, r, l) (outl((c)->port+(r), (ulong)(l)))
-
-enum Regs {
- Eaddr = 0x0,
- Rcr = 0x6,
- Tcr = 0x7,
- Cr = 0x8,
- Isr = 0xc,
- Imr = 0xe,
- McastAddr = 0x10,
- RxdAddr = 0x18,
- TxdAddr = 0x1C,
- Bcr = 0x6e,
- RhineMiiPhy = 0x6C,
- RhineMiiSr = 0x6D,
- RhineMiiCr = 0x70,
- RhineMiiAddr = 0x71,
- RhineMiiData = 0x72,
- Eecsr = 0x74,
- ConfigB = 0x79,
- ConfigD = 0x7B,
- MiscCr = 0x80,
- HwSticky = 0x83,
- MiscIsr = 0x84,
- MiscImr = 0x86,
- WolCrSet = 0xA0,
- WolCfgSet = 0xA1,
- WolCgSet = 0xA3,
- WolCrClr = 0xA4,
- PwrCfgClr = 0xA5,
- WolCgClr = 0xA7,
-};
-
-enum Rcrbits {
- RxErrX = 1<<0,
- RxSmall = 1<<1,
- RxMcast = 1<<2,
- RxBcast = 1<<3,
- RxProm = 1<<4,
- RxFifo64 = 0<<5, RxFifo32 = 1<<5, RxFifo128 = 2<<5, RxFifo256 = 3<<5,
- RxFifo512 = 4<<5, RxFifo768 = 5<<5, RxFifo1024 = 6<<5,
- RxFifoStoreForward = 7<<5,
-};
-
-enum Tcrbits {
- TxLoopback0 = 1<<1,
- TxLoopback1 = 1<<2,
- TxBackoff = 1<<3,
- TxFifo128 = 0<<5, TxFifo256 = 1<<5, TxFifo512 = 2<<5, TxFifo1024 = 3<<5,
- TxFifoStoreForward = 7<<5,
-};
-
-enum Crbits {
- Init = 1<<0,
- Start = 1<<1,
- Stop = 1<<2,
- RxOn = 1<<3,
- TxOn = 1<<4,
- Tdmd = 1<<5,
- Rdmd = 1<<6,
- EarlyRx = 1<<8,
- Reserved0 = 1<<9,
- FullDuplex = 1<<10,
- NoAutoPoll = 1<<11,
- Reserved1 = 1<<12,
- Tdmd1 = 1<<13,
- Rdmd1 = 1<<14,
- Reset = 1<<15,
-};
-
-enum Isrbits {
- RxOk = 1<<0,
- TxOk = 1<<1,
- RxErr = 1<<2,
- TxErr = 1<<3,
- TxBufUdf = 1<<4,
- RxBufLinkErr = 1<<5,
- BusErr = 1<<6,
- CrcOvf = 1<<7,
- EarlyRxInt = 1<<8,
- TxFifoUdf = 1<<9,
- RxFifoOvf = 1<<10,
- TxPktRace = 1<<11,
- NoRxbuf = 1<<12,
- TxCollision = 1<<13,
- PortCh = 1<<14,
- GPInt = 1<<15
-};
-
-enum Bcrbits {
- Dma32 = 0<<0, Dma64 = 1<<0, Dma128 = 2<<0,
- Dma256 = 3<<0, Dma512 = 4<<0, Dma1024 = 5<<0,
- DmaStoreForward = 7<<0,
- DupRxFifo0 = 1<<3, DupRxFifo1 = 1<<4, DupRxFifo2 = 1<<5,
- ExtraLed = 1<<6,
- MediumSelect = 1<<7,
- PollTimer0 = 1<<8, PollTimer1 = 1<<9, PollTimer2 = 1<<10,
- DupTxFifo0 = 1<<11, DupTxFifo1 = 1<<12, DupTxFifo2 = 1<<13,
-};
-
-enum Eecsrbits {
- EeAutoLoad = 1<<5,
-};
-
-enum MiscCrbits {
- Timer0Enable= 1<<0,
- Timer0Suspend = 1<<1,
- HalfDuplexFlowControl = 1<<2,
- FullDuplexFlowControl = 1<<3,
- Timer1Enable = 1<<8,
- ForceSoftReset = 1<<14,
-};
-
-enum HwStickybits {
- StickyDS0 = 1<<0,
- StickyDS1 = 1<<1,
- WOLEna = 1<<2,
- WOLStat = 1<<3,
-};
-
-enum WolCgbits {
- PmeOvr = 1<<7,
-};
-
-enum Descbits {
- OwnNic = 1<<31, /* stat */
- TxAbort = 1<<8, /* stat */
- TxError = 1<<15, /* stat */
- RxChainbuf = 1<<10, /* stat */
- RxChainStart = 1<<9, /* stat */
- RxChainEnd = 1<<8, /* stat */
- Chainbuf = 1<<15, /* size rx & tx*/
- TxDisableCrc = 1<<16, /* size */
- TxChainStart = 1<<21, /* size */
- TxChainEnd = 1<<22, /* size */
- TxInt = 1<<23, /* size */
-};
-
-enum ConfigDbits {
- BackoffOptional = 1<<0,
- BackoffAMD = 1<<1,
- BackoffDEC = 1<<2,
- BackoffRandom = 1<<3,
- PmccTestMode = 1<<4,
- PciReadlineCap = 1<<5,
- DiagMode = 1<<6,
- MmioEnable = 1<<7,
-};
-
-enum ConfigBbits {
- LatencyTimer = 1<<0,
- WriteWaitState = 1<<1,
- ReadWaitState = 1<<2,
- RxArbit = 1<<3,
- TxArbit = 1<<4,
- NoMemReadline = 1<<5,
- NoParity = 1<<6,
- NoTxQueuing = 1<<7,
-};
-
-enum RhineMiiCrbits {
- Mdc = 1<<0,
- Mdi = 1<<1,
- Mdo = 1<<2,
- Mdout = 1<<3,
- Mdpm = 1<<4,
- Wcmd = 1<<5,
- Rcmd = 1<<6,
- Mauto = 1<<7,
-};
-
-enum RhineMiiSrbits {
- Speed10M = 1<<0,
- LinkFail = 1<<1,
- PhyError = 1<<3,
- DefaultPhy = 1<<4,
- ResetPhy = 1<<7,
-};
-
-enum RhineMiiAddrbits {
- Mdone = 1<<5,
- Msrcen = 1<<6,
- Midle = 1<<7,
-};
-
-static char *
-txstatnames[Ntxstats] = {
- "aborts (excess collisions)",
- "out of window collisions",
- "carrier sense losses",
- "fifo underflows",
- "invalid descriptor format or underflows",
- "system errors",
- "reserved",
- "transmit errors",
- "collisions",
-};
-
-static char *
-rxstatnames[Nrxstats] = {
- "receiver errors",
- "crc errors",
- "frame alignment errors",
- "fifo overflows",
- "long packets",
- "run packets",
- "system errors",
- "buffer underflows",
-};
-
-static void
-attach(Ether *edev)
-{
- Ctlr *ctlr;
- Desc *txd, *rxd, *td, *rd;
- Mii *mi;
- MiiPhy *phy;
- int i, s;
-
- ctlr = edev->ctlr;
- qlock(&ctlr->attachlck);
- if (ctlr->attached == 0) {
- txd = ctlr->txd;
- rxd = ctlr->rxd;
- for (i = 0; i < Ntxd; ++i) {
- td = &txd[i];
- td->next = PCIWADDR(&txd[(i+1) % Ntxd]);
- td->buf = xspanalloc(sizeof(Etherpkt)+4, 4, 0);
- td->addr = PCIWADDR(td->buf);
- td->size = 0;
- coherence();
- td->stat = 0;
- }
- for (i = 0; i < Nrxd; ++i) {
- rd = &rxd[i];
- rd->next = PCIWADDR(&rxd[(i+1) % Nrxd]);
- rd->buf = xspanalloc(sizeof(Etherpkt)+4, 4, 0);
- rd->addr = PCIWADDR(rd->buf);
- rd->size = sizeof(Etherpkt)+4;
- coherence();
- rd->stat = OwnNic;
- }
-
- ctlr->txhead = ctlr->txtail = ctlr->rxtail = 0;
- mi = &ctlr->mii;
- miistatus(mi);
- phy = mi->curphy;
- s = splhi();
- iow32(ctlr, TxdAddr, PCIWADDR(&txd[0]));
- iow32(ctlr, RxdAddr, PCIWADDR(&rxd[0]));
- iow16(ctlr, Cr, (phy->fd ? FullDuplex : 0) | NoAutoPoll | TxOn | RxOn | Start | Rdmd);
- iow16(ctlr, Isr, 0xFFFF);
- iow16(ctlr, Imr, 0xFFFF);
- iow8(ctlr, MiscIsr, 0xFF);
- iow8(ctlr, MiscImr, ~(3<<5));
- splx(s);
- }
- ctlr->attached++;
- qunlock(&ctlr->attachlck);
-}
-
-static void
-txstart(Ether *edev)
-{
- Ctlr *ctlr;
- Desc *txd, *td;
- Block *b;
- int i, txused, n;
- ulong size;
-
- ctlr = edev->ctlr;
-
- txd = ctlr->txd;
- i = ctlr->txhead;
- txused = ctlr->txused;
- n = 0;
- while (txused < Ntxd) {
- if ((b = qget(edev->oq)) == nil)
- break;
-
- td = &txd[i];
-
- size = BLEN(b);
- memmove(td->buf, b->rp, size);
- freeb(b);
- td->size = size | TxChainStart | TxChainEnd | TxInt; /* could reduce number of ints here */
- coherence();
- td->stat = OwnNic;
- i = (i + 1) % Ntxd;
- txused++;
- n++;
- }
- if (n)
- iow16(ctlr, Cr, ior16(ctlr, Cr) | Tdmd);
-
- ctlr->txhead = i;
- ctlr->txused = txused;
-}
-
-static void
-transmit(Ether *edev)
-{
- Ctlr *ctlr;
- ctlr = edev->ctlr;
- ilock(&ctlr->lock);
- txstart(edev);
- iunlock(&ctlr->lock);
-}
-
-static void
-txcomplete(Ether *edev)
-{
- Ctlr *ctlr;
- Desc *txd, *td;
- int i, txused, j;
- ulong stat;
-
- ctlr = edev->ctlr;
- txd = ctlr->txd;
- txused = ctlr->txused;
- i = ctlr->txtail;
- while (txused > 0) {
- td = &txd[i];
- stat = td->stat;
-
- if (stat & OwnNic)
- break;
-
- ctlr->txstats[Ntxstats-1] += stat & 0xF;
- for (j = 0; j < Ntxstats-1; ++j)
- if (stat & (1<<(j+8)))
- ctlr->txstats[j]++;
-
- i = (i + 1) % Ntxd;
- txused--;
- }
- ctlr->txused = txused;
- ctlr->txtail = i;
-
- if (txused <= Ntxd/2)
- txstart(edev);
-}
-
-static void
-interrupt(Ureg *, void *arg)
-{
- Ether *edev;
- Ctlr *ctlr;
- ushort isr, misr;
- ulong stat;
- Desc *rxd, *rd;
- int i, n, j;
-
- edev = (Ether*)arg;
- ctlr = edev->ctlr;
- iow16(ctlr, Imr, 0);
- isr = ior16(ctlr, Isr);
- iow16(ctlr, Isr, 0xFFFF);
- misr = ior16(ctlr, MiscIsr) & ~(3<<5); /* don't care about used defined ints */
-
- if (isr & RxOk) {
- Block *b;
- int size;
- rxd = ctlr->rxd;
- i = ctlr->rxtail;
-
- n = 0;
- while ((rxd[i].stat & OwnNic) == 0) {
- rd = &rxd[i];
- stat = rd->stat;
- for (j = 0; j < Nrxstats; ++j)
- if (stat & (1<<j))
- ctlr->rxstats[j]++;
-
- if (stat & 0xFF)
- iprint("rx: %lux\n", stat & 0xFF);
-
- size = ((rd->stat>>16) & 2047) - 4;
- b = iallocb(sizeof(Etherpkt));
- memmove(b->wp, rd->buf, size);
- b->wp += size;
- etheriq(edev, b, 1);
- rd->size = sizeof(Etherpkt)+4;
- coherence();
- rd->stat = OwnNic;
- i = (i + 1) % Nrxd;
- n++;
- }
- if (n)
- iow16(ctlr, Cr, ior16(ctlr, Cr) | Rdmd);
- ctlr->rxtail = i;
- isr &= ~RxOk;
- }
- if (isr & TxOk) {
- txcomplete(edev);
- isr &= ~TxOk;
- }
- if (isr | misr)
- iprint("etherrhine: unhandled irq(s). isr:%x misr:%x\n", isr, misr);
-
- iow16(ctlr, Imr, 0xFFFF);
-}
-
-static void
-promiscuous(void *arg, int enable)
-{
- Ether *edev;
- Ctlr *ctlr;
-
- edev = arg;
- ctlr = edev->ctlr;
- ilock(&ctlr->lock);
- iow8(ctlr, Rcr, (ior8(ctlr, Rcr) & ~(RxProm|RxBcast)) |
- (enable ? RxProm : RxBcast));
- iunlock(&ctlr->lock);
-}
-
-static int
-miiread(Mii *mii, int phy, int reg)
-{
- Ctlr *ctlr;
- int n;
-
- ctlr = mii->ctlr;
-
- n = Nwait;
- while (n-- && ior8(ctlr, RhineMiiCr) & (Rcmd | Wcmd))
- microdelay(1);
- if (n == Nwait)
- iprint("etherrhine: miiread: timeout\n");
-
- iow8(ctlr, RhineMiiCr, 0);
- iow8(ctlr, RhineMiiPhy, phy);
- iow8(ctlr, RhineMiiAddr, reg);
- iow8(ctlr, RhineMiiCr, Rcmd);
-
- n = Nwait;
- while (n-- && ior8(ctlr, RhineMiiCr) & Rcmd)
- microdelay(1);
- if (n == Nwait)
- iprint("etherrhine: miiread: timeout\n");
-
- n = ior16(ctlr, RhineMiiData);
-
- return n;
-}
-
-static int
-miiwrite(Mii *mii, int phy, int reg, int data)
-{
- int n;
- Ctlr *ctlr;
-
- ctlr = mii->ctlr;
-
- n = Nwait;
- while (n-- && ior8(ctlr, RhineMiiCr) & (Rcmd | Wcmd))
- microdelay(1);
- if (n == Nwait)
- iprint("etherrhine: miiwrite: timeout\n");
-
- iow8(ctlr, RhineMiiCr, 0);
- iow8(ctlr, RhineMiiPhy, phy);
- iow8(ctlr, RhineMiiAddr, reg);
- iow16(ctlr, RhineMiiData, data);
- iow8(ctlr, RhineMiiCr, Wcmd);
-
- n = Nwait;
- while (n-- && ior8(ctlr, RhineMiiCr) & Wcmd)
- microdelay(1);
- if (n == Nwait)
- iprint("etherrhine: miiwrite: timeout\n");
-
- return 0;
-}
-
-/* multicast already on, don't need to do anything */
-static void
-multicast(void*, uchar*, int)
-{
-}
-
-static void
-shutdown(Ether *edev)
-{
- int i;
- Ctlr *ctlr = edev->ctlr;
-
- ilock(&ctlr->lock);
- pcisetbme(ctlr->pci);
-
- iow16(ctlr, Cr, ior16(ctlr, Cr) | Stop);
- iow16(ctlr, Cr, ior16(ctlr, Cr) | Reset);
-
- for (i = 0; i < Nwait; ++i) {
- if ((ior16(ctlr, Cr) & Reset) == 0)
- break;
- delay(5);
- }
- if (i == Nwait)
- iprint("etherrhine: reset timeout\n");
- iunlock(&ctlr->lock);
-}
-
-static void
-init(Ether *edev)
-{
- Ctlr *ctlr;
- MiiPhy *phy;
- int i;
-
- shutdown(edev);
-
- ctlr = edev->ctlr;
- ilock(&ctlr->lock);
- iow8(ctlr, Eecsr, ior8(ctlr, Eecsr) | EeAutoLoad);
- for (i = 0; i < Nwait; ++i) {
- if ((ior8(ctlr, Eecsr) & EeAutoLoad) == 0)
- break;
- delay(5);
- }
- if (i == Nwait)
- iprint("etherrhine: eeprom autoload timeout\n");
-
- for (i = 0; i < Eaddrlen; ++i)
- edev->ea[i] = ior8(ctlr, Eaddr + i);
-
- ctlr->mii.mir = miiread;
- ctlr->mii.miw = miiwrite;
- ctlr->mii.ctlr = ctlr;
-
- if(mii(&ctlr->mii, ~0) == 0 || ctlr->mii.curphy == nil){
- iprint("etherrhine: init mii failure\n");
- return;
- }
- for (i = 0; i < NMiiPhy; ++i)
- if (ctlr->mii.phy[i])
- if (ctlr->mii.phy[i]->oui != 0xFFFFF)
- ctlr->mii.curphy = ctlr->mii.phy[i];
-
- miistatus(&ctlr->mii);
- phy = ctlr->mii.curphy;
- edev->mbps = phy->speed;
-
- iow16(ctlr, Imr, 0);
- iow16(ctlr, Cr, ior16(ctlr, Cr) | Stop);
- iow8(ctlr, Rcr, ior8(ctlr, Rcr) | RxMcast);
-
- iunlock(&ctlr->lock);
-}
-
-static Pcidev *
-rhinematch(ulong)
-{
- static int nrhines = 0;
- int nfound = 0;
- Pcidev *p = nil;
-
- while (p = pcimatch(p, 0x1106, 0))
- if (p->did == 0x3065)
- if (++nfound > nrhines) {
- nrhines++;
- break;
- }
- return p;
-}
-static long
-ifstat(Ether* edev, void* a, long n, ulong offset)
-{
- int l = 0, i;
- char *p;
- Ctlr *ctlr;
- ctlr = edev->ctlr;
- p = malloc(BIGSTR);
-
- for (i = 0; i < Ntxstats; ++i)
- if (txstatnames[i])
- l += snprint(p+l, BIGSTR - l, "tx: %s: %lud\n", txstatnames[i], ctlr->txstats[i]);
-
- for (i = 0; i < Nrxstats; ++i)
- if (rxstatnames[i])
- l += snprint(p+l, BIGSTR - l, "rx: %s: %lud\n", rxstatnames[i], ctlr->rxstats[i]);
-
-/*
- for (i = 0; i < NMiiPhyr; ++i) {
- if ((i % 8) == 0)
- l += snprint(p + l, BIGSTR - l, "\nmii 0x%02x:", i);
- reg=miimir(&ctlr->mii, i);
- reg=miimir(&ctlr->mii, i);
- l += snprint(p + l, BIGSTR - l, " %4ux", reg);
- }
-
- for (i = 0; i < 0x100; i+=1) {
- if ((i % 16) == 0)
- l += snprint(p + l, BIGSTR - l, "\nreg 0x%02x:", i);
- else if ((i % 2) == 0)
- l += snprint(p + l, BIGSTR - l, " ");
- reg=ior8(ctlr, i);
- l += snprint(p + l, BIGSTR - l, "%02x", reg);
- }
- l += snprint(p + l, BIGSTR - l, " \n");
-*/
-
-
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static int
-pnp(Ether *edev)
-{
- Pcidev *p;
- Ctlr *ctlr;
- ulong port;
- ulong size;
-
- p = rhinematch(edev->port);
- if (p == nil)
- return -1;
-
- port = p->mem[0].bar & ~1;
- size = p->mem[0].size;
- if (ioalloc(port, size, 0, "rhine") < 0) {
- print("etherrhine: couldn't allocate port %lud\n", port);
- return -1;
- }
-
- if ((ctlr = malloc(sizeof(Ctlr))) == nil) {
- print("etherrhine: couldn't allocate memory for ctlr\n");
- return -1;
- }
- memset(ctlr, 0, sizeof(Ctlr));
- ctlr->txd = xspanalloc(sizeof(Desc) * Ntxd, 16, 0);
- ctlr->rxd = xspanalloc(sizeof(Desc) * Nrxd, 16, 0);
-
- ctlr->pci = p;
- ctlr->port = port;
-
- edev->ctlr = ctlr;
- edev->port = ctlr->port;
- edev->irq = p->intl;
- edev->tbdf = p->tbdf;
-
- init(edev);
-
- edev->interrupt = interrupt;
- edev->arg = edev;
-
- edev->attach = attach;
- edev->transmit = transmit;
- edev->ifstat = ifstat;
- edev->promiscuous = promiscuous;
- edev->multicast = multicast;
- edev->shutdown = shutdown;
- return 0;
-}
-
-void
-etherrhinelink(void)
-{
- addethercard("rhine", pnp);
-}
diff --git a/os/pc/ethersmc.c b/os/pc/ethersmc.c
deleted file mode 100644
index 65ebffca..00000000
--- a/os/pc/ethersmc.c
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- * SMC EtherEZ (SMC91cXX chip) PCMCIA card support.
- */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-#include "etherif.h"
-
-enum {
- IoSize = 0x10, /* port pool size */
- TxTimeout = 150,
-};
-
-enum { /* PCMCIA related */
- TupleFunce = 0x22,
- TfNodeId = 0x04,
-};
-
-enum { /* bank 0 registers */
- Tcr = 0x0000, /* transmit control */
- Eph = 0x0002, /* ethernet protocol handler */
- Rcr = 0x0004, /* receiver control */
- Counter = 0x0006, /* statistics counter */
- MemInfo = 0x0008,
- MemCfg = 0x000A,
-};
-
-enum { /* bank 1 registers */
- Config = 0x0000,
- BaseAddr = 0x0002,
- Addr0 = 0x0004, /* ethernet address */
- Addr1 = 0x0006,
- Addr2 = 0x0008,
- General = 0x000A,
- Control = 0x000C,
-};
-
-enum { /* bank 2 registers */
- MmuCmd = 0x0000,
- PktNo = 0x0002,
- AllocRes = 0x0003,
- FifoPorts = 0x0004,
- Pointer = 0x0006,
- Data1 = 0x0008,
- Interrupt = 0x000C,
- IntrMask = 0x000D,
-};
-
-enum { /* bank 3 registers */
- Mcast0 = 0x0000,
- Mcast2 = 0x0002,
- Mcast4 = 0x0004,
- Mcast6 = 0x0006,
- Revision = 0x000A,
-};
-
-enum {
- BankSelect = 0x000E /* bank select register */
-};
-
-enum {
- BsrMask = 0xFF00, /* mask for chip identification */
- BsrId = 0x3300,
-};
-
-
-enum { /* Tcr values */
- TcrClear = 0x0000,
- TcrEnable = 0x0001, /* enable transmit */
- TcrLoop = 0x0002, /* enable internal analogue loopback */
- TcrForceCol = 0x0004, /* force collision on next tx */
- TcrPadEn = 0x0080, /* pad short packets to 64 bytes */
- TcrNoCrc = 0x0100, /* do not append CRC */
- TcrMonCns = 0x0400, /* monitor carrier status */
- TcrFduplx = 0x0800,
- TcrStpSqet = 0x1000,
- TcrEphLoop = 0x2000,
- TcrNormal = TcrEnable,
-};
-
-enum { /* Eph values */
- EphTxOk = 0x0001,
- Eph1Col = 0x0002, /* single collision */
- EphMCol = 0x0004, /* multiple collisions */
- EphTxMcast = 0x0008, /* multicast transmit */
- Eph16Col = 0x0010, /* 16 collisions, tx disabled */
- EphSqet = 0x0020, /* SQE test failed, tx disabled */
- EphTxBcast = 0x0040, /* broadcast tx */
- EphDefr = 0x0080, /* deffered tx */
- EphLatCol = 0x0200, /* late collision, tx disabled */
- EphLostCarr = 0x0400, /* lost carrier, tx disabled */
- EphExcDefr = 0x0800, /* excessive defferals */
- EphCntRol = 0x1000, /* ECR counter(s) rolled over */
- EphRxOvrn = 0x2000, /* receiver overrun, packets dropped */
- EphLinkOk = 0x4000,
- EphTxUnrn = 0x8000, /* tx underrun */
-};
-
-enum { /* Rcr values */
- RcrClear = 0x0000,
- RcrPromisc = 0x0002,
- RcrAllMcast = 0x0004,
- RcrEnable = 0x0100,
- RcrStripCrc = 0x0200,
- RcrSoftReset = 0x8000,
- RcrNormal = RcrStripCrc | RcrEnable,
-};
-
-enum { /* Counter value masks */
- CntColMask = 0x000F, /* collisions */
- CntMColMask = 0x00F0, /* multiple collisions */
- CntDtxMask = 0x0F00, /* deferred transmits */
- CntExDtxMask = 0xF000, /* excessively deferred transmits */
-
- CntColShr = 1,
- CntMColShr = 4,
- CntDtxShr = 8,
-};
-
-enum { /* MemInfo value masks */
- MirTotalMask = 0x00FF,
- MirFreeMask = 0xFF00,
-};
-
-enum { /* Config values */
- CfgIrqSel0 = 0x0002,
- CfgIrqSel1 = 0x0004,
- CfgDisLink = 0x0040, /* disable 10BaseT link test */
- Cfg16Bit = 0x0080,
- CfgAuiSelect = 0x0100,
- CfgSetSqlch = 0x0200,
- CfgFullStep = 0x0400,
- CfgNoWait = 0x1000,
- CfgMiiSelect = 0x8000,
-};
-
-enum { /* Control values */
- CtlStore = 0x0001, /* store to EEPROM */
- CtlReload = 0x0002, /* reload EEPROM into registers */
- CtlEeSelect = 0x0004, /* select registers for reload/store */
- CtlTeEnable = 0x0020, /* tx error detection via eph irq */
- CtlCrEnable = 0x0040, /* counter rollover via eph irq */
- CtlLeEnable = 0x0080, /* link error detection via eph irq*/
- CtlAutoRls = 0x0800, /* auto release mode */
- CtlPowerDn = 0x2000,
-};
-
-enum { /* MmuCmd values */
- McBusy = 0x0001,
- McAlloc = 0x0020, /* | with number of 256 byte packets - 1 */
- McReset = 0x0040,
- McRelease = 0x0080, /* dequeue (but not free) current rx packet */
- McFreePkt = 0x00A0, /* dequeue and free current rx packet */
- McEnqueue = 0x00C0, /* enqueue the packet for tx */
- McTxReset = 0x00E0, /* reset transmit queues */
-};
-
-enum { /* AllocRes values */
- ArFailed = 0x80,
-};
-
-enum { /* FifoPorts values */
- FpTxEmpty = 0x0080,
- FpRxEmpty = 0x8000,
- FpTxMask = 0x007F,
- FpRxMask = 0x7F00,
-};
-
-enum { /* Pointer values */
- PtrRead = 0x2000,
- PtrAutoInc = 0x4000,
- PtrRcv = 0x8000,
-};
-
-enum { /* Interrupt values */
- IntRcv = 0x0001,
- IntTxError = 0x0002,
- IntTxEmpty = 0x0004,
- IntAlloc = 0x0008,
- IntRxOvrn = 0x0010,
- IntEph = 0x0020,
-};
-
-enum { /* transmit status bits */
- TsSuccess = 0x0001,
- Ts16Col = 0x00A0,
- TsLatCol = 0x0200,
- TsLostCar = 0x0400,
-};
-
-enum { /* receive status bits */
- RsMcast = 0x0001,
- RsTooShort = 0x0400,
- RsTooLong = 0x0800,
- RsOddFrame = 0x1000,
- RsBadCrc = 0x2000,
- RsAlgnErr = 0x8000,
- RsError = RsAlgnErr | RsBadCrc | RsTooLong | RsTooShort,
-};
-
-enum {
- RxLenMask = 0x07FF, /* significant rx len bits */
- HdrSize = 6, /* packet header length */
- PageSize = 256, /* page length */
-};
-
-typedef struct Smc91xx Smc91xx;
-struct Smc91xx {
- Lock;
- ushort rev;
- int attached;
- Block *txbp;
- ulong txtime;
-
- ulong rovrn;
- ulong lcar;
- ulong col;
- ulong scol;
- ulong mcol;
- ulong lcol;
- ulong dfr;
-};
-
-#define SELECT_BANK(x) outs(port + BankSelect, x)
-
-static int
-readnodeid(int slot, Ether* ether)
-{
- uchar data[Eaddrlen + 1];
- int len;
-
- len = sizeof(data);
- if (pcmcistuple(slot, TupleFunce, TfNodeId, data, len) != len)
- return -1;
-
- if (data[0] != Eaddrlen)
- return -1;
-
- memmove(ether->ea, &data[1], Eaddrlen);
- return 0;
-}
-
-static void
-chipreset(Ether* ether)
-{
- int port;
- int i;
-
- port = ether->port;
-
- /* reset the chip */
- SELECT_BANK(0);
- outs(port + Rcr, RcrSoftReset);
- delay(1);
- outs(port + Rcr, RcrClear);
- outs(port + Tcr, TcrClear);
- SELECT_BANK(1);
- outs(port + Control, CtlAutoRls | CtlTeEnable |
- CtlCrEnable);
-
- for(i = 0; i < 6; i++) {
- outb(port + Addr0 + i, ether->ea[i]);
- }
-
- SELECT_BANK(2);
- outs(port + MmuCmd, McReset);
-}
-
-static void
-chipenable(Ether* ether)
-{
- int port;
-
- port = ether->port;
- SELECT_BANK(0);
- outs(port + Tcr, TcrNormal);
- outs(port + Rcr, RcrNormal);
- SELECT_BANK(2);
- outb(port + IntrMask, IntEph | IntRxOvrn | IntRcv);
-}
-
-static void
-attach(Ether *ether)
-{
- Smc91xx* ctlr;
-
- ctlr = ether->ctlr;
- ilock(ctlr);
-
- if (ctlr->attached) {
- iunlock(ctlr);
- return;
- }
-
- chipenable(ether);
- ctlr->attached = 1;
- iunlock(ctlr);
-}
-
-static void
-txstart(Ether* ether)
-{
- int port;
- Smc91xx* ctlr;
- Block* bp;
- int len, npages;
- int pno;
-
- /* assumes ctlr is locked and bank 2 is selected */
- /* leaves bank 2 selected on return */
- port = ether->port;
- ctlr = ether->ctlr;
-
- if (ctlr->txbp) {
- bp = ctlr->txbp;
- ctlr->txbp = 0;
- } else {
- bp = qget(ether->oq);
- if (bp == 0)
- return;
-
- len = BLEN(bp);
- npages = (len + HdrSize) / PageSize;
- outs(port + MmuCmd, McAlloc | npages);
- }
-
- pno = inb(port + AllocRes);
- if (pno & ArFailed) {
- outb(port + IntrMask, inb(port + IntrMask) | IntAlloc);
- ctlr->txbp = bp;
- ctlr->txtime = MACHP(0)->ticks;
- return;
- }
-
- outb(port + PktNo, pno);
- outs(port + Pointer, PtrAutoInc);
-
- len = BLEN(bp);
- outs(port + Data1, 0);
- outb(port + Data1, (len + HdrSize) & 0xFF);
- outb(port + Data1, (len + HdrSize) >> 8);
- outss(port + Data1, bp->rp, len / 2);
- if ((len & 1) == 0) {
- outs(port + Data1, 0);
- } else {
- outb(port + Data1, bp->rp[len - 1]);
- outb(port + Data1, 0x20); /* no info what 0x20 means */
- }
-
- outb(port + IntrMask, inb(port + IntrMask) |
- IntTxError | IntTxEmpty);
-
- outs(port + MmuCmd, McEnqueue);
- freeb(bp);
-}
-
-static void
-receive(Ether* ether)
-{
- int port;
- Block* bp;
- int pktno, status, len;
-
- /* assumes ctlr is locked and bank 2 is selected */
- /* leaves bank 2 selected on return */
- port = ether->port;
-
- pktno = ins(port + FifoPorts);
- if (pktno & FpRxEmpty) {
- return;
- }
-
- outs(port + Pointer, PtrRead | PtrRcv | PtrAutoInc);
- status = ins(port + Data1);
- len = ins(port + Data1) & RxLenMask - HdrSize;
-
- if (status & RsOddFrame)
- len++;
-
- if ((status & RsError) || (bp = iallocb(len)) == 0) {
-
- if (status & RsAlgnErr)
- ether->frames++;
- if (status & (RsTooShort | RsTooLong))
- ether->buffs++;
- if (status & RsBadCrc)
- ether->crcs++;
-
- outs(port + MmuCmd, McRelease);
- return;
- }
-
- /* packet length is padded to word */
- inss(port + Data1, bp->rp, len / 2);
- bp->wp = bp->rp + (len & ~1);
-
- if (len & 1) {
- *bp->wp = inb(port + Data1);
- bp->wp++;
- }
-
- etheriq(ether, bp, 1);
- ether->inpackets++;
- outs(port + MmuCmd, McRelease);
-}
-
-static void
-txerror(Ether* ether)
-{
- int port;
- Smc91xx* ctlr;
- int save_pkt;
- int pktno, status;
-
- /* assumes ctlr is locked and bank 2 is selected */
- /* leaves bank 2 selected on return */
- port = ether->port;
- ctlr = ether->ctlr;
-
- save_pkt = inb(port + PktNo);
-
- pktno = ins(port + FifoPorts) & FpTxMask;
- outb(port + PktNo, pktno);
- outs(port + Pointer, PtrAutoInc | PtrRead);
- status = ins(port + Data1);
-
- if (status & TsLostCar)
- ctlr->lcar++;
-
- if (status & TsLatCol)
- ctlr->lcol++;
-
- if (status & Ts16Col)
- ctlr->scol++;
-
- ether->oerrs++;
-
- SELECT_BANK(0);
- outs(port + Tcr, ins(port + Tcr) | TcrEnable);
-
- SELECT_BANK(2);
- outs(port + MmuCmd, McFreePkt);
-
- outb(port + PktNo, save_pkt);
-}
-
-static void
-eph_irq(Ether* ether)
-{
- int port;
- Smc91xx* ctlr;
- ushort status;
- int n;
-
- /* assumes ctlr is locked and bank 2 is selected */
- /* leaves bank 2 selected on return */
- port = ether->port;
- ctlr = ether->ctlr;
-
- SELECT_BANK(0);
- status = ins(port + Eph);
-
- if (status & EphCntRol) {
- /* read the counter register even if we don't need it */
- /* otherwise we will keep getting this interrupt */
- n = ins(port + Counter);
- ctlr->col += (n & CntColMask) >> CntColShr;
- ctlr->mcol += (n & CntMColMask) >> CntMColShr;
- ctlr->dfr += (n & CntDtxMask) >> CntDtxShr;
- }
-
- /* if there was a transmit error, Tcr is disabled */
- outs(port + Tcr, ins(port + Tcr) | TcrEnable);
-
- /* clear a link error interrupt */
- SELECT_BANK(1);
- outs(port + Control, CtlAutoRls);
- outs(port + Control, CtlAutoRls | CtlTeEnable | CtlCrEnable);
-
- SELECT_BANK(2);
-}
-
-static void
-transmit(Ether* ether)
-{
- Smc91xx* ctlr;
- int port, n;
-
- ctlr = ether->ctlr;
- port = ether->port;
- ilock(ctlr);
-
- if (ctlr->txbp) {
- n = TK2MS(MACHP(0)->ticks - ctlr->txtime);
- if (n > TxTimeout) {
- chipreset(ether);
- chipenable(ether);
- freeb(ctlr->txbp);
- ctlr->txbp = 0;
- }
- iunlock(ctlr);
- return;
- }
-
- SELECT_BANK(2);
- txstart(ether);
- iunlock(ctlr);
-}
-
-static void
-interrupt(Ureg*, void *arg)
-{
- int port;
- Smc91xx* ctlr;
- Ether* ether;
- int save_bank;
- int save_pointer;
- int mask, status;
-
- ether = arg;
- port = ether->port;
- ctlr = ether->ctlr;
-
- ilock(ctlr);
- save_bank = ins(port + BankSelect);
- SELECT_BANK(2);
- save_pointer = ins(port + Pointer);
-
- mask = inb(port + IntrMask);
- outb(port + IntrMask, 0);
-
- while ((status = inb(port + Interrupt) & mask) != 0) {
- if (status & IntRcv) {
- receive(ether);
- }
-
- if (status & IntTxError) {
- txerror(ether);
- }
-
- if (status & IntTxEmpty) {
- outb(port + Interrupt, IntTxEmpty);
- outb(port + IntrMask, mask & ~IntTxEmpty);
- txstart(ether);
- mask = inb(port + IntrMask);
- }
-
- if (status & IntAlloc) {
- outb(port + IntrMask, mask & ~IntAlloc);
- txstart(ether);;
- mask = inb(port + IntrMask);
- }
-
- if (status & IntRxOvrn) {
- ctlr->rovrn++;
- ether->misses++;
- outb(port + Interrupt,IntRxOvrn);
- }
-
- if (status & IntEph)
- eph_irq(ether);
- }
-
- outb(port + IntrMask, mask);
- outs(port + Pointer, save_pointer);
- outs(port + BankSelect, save_bank);
- iunlock(ctlr);
-}
-
-static void
-promiscuous(void* arg, int on)
-{
- int port;
- Smc91xx *ctlr;
- Ether* ether;
- ushort x;
-
- ether = arg;
- port = ether->port;
- ctlr = ether->ctlr;
-
- ilock(ctlr);
- SELECT_BANK(0);
- x = ins(port + Rcr);
- if (on)
- x |= RcrPromisc;
- else
- x &= ~RcrPromisc;
-
- outs(port + Rcr, x);
- iunlock(ctlr);
-}
-
-static void
-multicast(void* arg, uchar *addr, int on)
-{
- int port;
- Smc91xx*ctlr;
- Ether *ether;
- ushort x;
-
- USED(addr, on);
-
- ether = arg;
- port = ether->port;
- ctlr = ether->ctlr;
- ilock(ctlr);
-
- SELECT_BANK(0);
- x = ins(port + Rcr);
-
- if (ether->nmaddr)
- x |= RcrAllMcast;
- else
- x &= ~RcrAllMcast;
-
- outs(port + Rcr, x);
- iunlock(ctlr);
-}
-
-static long
-ifstat(Ether* ether, void* a, long n, ulong offset)
-{
- static char *chiprev[] = {
- [3] "92",
- [5] "95",
- [7] "100",
- [8] "100-FD",
- [9] "110",
- };
-
- Smc91xx* ctlr;
- char* p;
- int r, len;
- char* s;
-
- if (n == 0)
- return 0;
-
- ctlr = ether->ctlr;
- p = malloc(READSTR);
-
- s = 0;
- if (ctlr->rev > 0) {
- r = ctlr->rev >> 4;
- if (r < nelem(chiprev))
- s = chiprev[r];
-
- if (r == 4) {
- if ((ctlr->rev & 0x0F) >= 6)
- s = "96";
- else
- s = "94";
- }
- }
-
- len = snprint(p, READSTR, "rev: 91c%s\n", (s) ? s : "???");
- len += snprint(p + len, READSTR - len, "rxovrn: %uld\n", ctlr->rovrn);
- len += snprint(p + len, READSTR - len, "lcar: %uld\n", ctlr->lcar);
- len += snprint(p + len, READSTR - len, "col: %uld\n", ctlr->col);
- len += snprint(p + len, READSTR - len, "16col: %uld\n", ctlr->scol);
- len += snprint(p + len, READSTR - len, "mcol: %uld\n", ctlr->mcol);
- len += snprint(p + len, READSTR - len, "lcol: %uld\n", ctlr->lcol);
- len += snprint(p + len, READSTR - len, "dfr: %uld\n", ctlr->dfr);
- USED(len);
-
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static int
-reset(Ether* ether)
-{
- int port;
- int i, x;
- char* type;
- Smc91xx* ctlr;
- int slot;
- uchar ea[Eaddrlen];
-
- if (ether->irq == 0)
- ether->irq = 9;
-
- if (ether->port == 0)
- ether->port = 0x100;
-
- type = "8020";
- for(i = 0; i < ether->nopt; i++) {
- if (cistrncmp(ether->opt[i], "id=", 3))
- continue;
- type = &ether->opt[i][3];
- break;
- }
-
- if ((slot = pcmspecial(type, ether)) < 0)
- return -1;
-
- if (ioalloc(ether->port, IoSize, 0, "smc91cXX") < 0) {
- pcmspecialclose(slot);
- return -1;
- }
-
- ether->ctlr = malloc(sizeof(Smc91xx));
- ctlr = ether->ctlr;
- if (ctlr == 0) {
- iofree(ether->port);
- pcmspecialclose(slot);
- return -1;
- }
-
- ilock(ctlr);
- ctlr->rev = 0;
- ctlr->txbp = nil;
- ctlr->attached = 0;
- ctlr->rovrn = 0;
- ctlr->lcar = 0;
- ctlr->col = 0;
- ctlr->scol = 0;
- ctlr->mcol = 0;
- ctlr->lcol = 0;
- ctlr->dfr = 0;
-
- port = ether->port;
-
- SELECT_BANK(1);
- if ((ins(port + BankSelect) & BsrMask) != BsrId) {
- outs(port + Control, 0); /* try powering up the chip */
- delay(55);
- }
-
- outs(port + Config, ins(port + Config) | Cfg16Bit);
- x = ins(port + BaseAddr);
-
- if (((ins(port + BankSelect) & BsrMask) != BsrId) ||
- ((x >> 8) == (x & 0xFF))) {
- iunlock(ctlr);
- iofree(port);
- pcmspecialclose(slot);
- return -1;
- }
-
- SELECT_BANK(3);
- ctlr->rev = ins(port + Revision) & 0xFF;
-
- memset(ea, 0, Eaddrlen);
- if (memcmp(ea, ether->ea, Eaddrlen) == 0) {
- if (readnodeid(slot, ether) < 0) {
- print("Smc91cXX: cannot find ethernet address\n");
- iunlock(ctlr);
- iofree(port);
- pcmspecialclose(slot);
- return -1;
- }
- }
-
- chipreset(ether);
-
- ether->attach = attach;
- ether->transmit = transmit;
- ether->interrupt = interrupt;
- ether->ifstat = ifstat;
- ether->promiscuous = promiscuous;
- ether->multicast = multicast;
- ether->arg = ether;
- iunlock(ctlr);
- return 0;
-}
-
-void
-ethersmclink(void)
-{
- addethercard("smc91cXX", reset);
-}
diff --git a/os/pc/ethervt6102.c b/os/pc/ethervt6102.c
deleted file mode 100644
index 20d43a4e..00000000
--- a/os/pc/ethervt6102.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * VIA VT6102 Fast Ethernet Controller (Rhine II).
- * To do:
- * cache-line size alignments - done
- * reduce tx interrupts
- * use 2 descriptors on tx for alignment - done
- * reorganise initialisation/shutdown/reset
- * adjust Tx FIFO threshold on underflow - untested
- * why does the link status never cause an interrupt?
- * use the lproc as a periodic timer for stalls, etc.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-enum {
- Par0 = 0x00, /* Ethernet Address */
- Rcr = 0x06, /* Receive Configuration */
- Tcr = 0x07, /* Transmit Configuration */
- Cr = 0x08, /* Control */
- Isr = 0x0C, /* Interrupt Status */
- Imr = 0x0E, /* Interrupt Mask */
- Rxdaddr = 0x18, /* Current Rx Descriptor Address */
- Txdaddr = 0x1C, /* Current Tx Descriptor Address */
- Phyadr = 0x6C, /* Phy Address */
- Miisr = 0x6D, /* MII Status */
- Bcr0 = 0x6E, /* Bus Control */
- Bcr1 = 0x6F,
- Miicr = 0x70, /* MII Control */
- Miiadr = 0x71, /* MII Address */
- Miidata = 0x72, /* MII Data */
- Eecsr = 0x74, /* EEPROM Control and Status */
-};
-
-enum { /* Rcr */
- Sep = 0x01, /* Accept Error Packets */
- Ar = 0x02, /* Accept Small Packets */
- Am = 0x04, /* Accept Multicast */
- Ab = 0x08, /* Accept Broadcast */
- Prom = 0x10, /* Accept Physical Address Packets */
- RrftMASK = 0xE0, /* Receive FIFO Threshold */
- RrftSHIFT = 5,
- Rrft64 = 0<<RrftSHIFT,
- Rrft32 = 1<<RrftSHIFT,
- Rrft128 = 2<<RrftSHIFT,
- Rrft256 = 3<<RrftSHIFT,
- Rrft512 = 4<<RrftSHIFT,
- Rrft768 = 5<<RrftSHIFT,
- Rrft1024 = 6<<RrftSHIFT,
- RrftSAF = 7<<RrftSHIFT,
-};
-
-enum { /* Tcr */
- Lb0 = 0x02, /* Loopback Mode */
- Lb1 = 0x04,
- Ofset = 0x08, /* Back-off Priority Selection */
- RtsfMASK = 0xE0, /* Transmit FIFO Threshold */
- RtsfSHIFT = 5,
- Rtsf128 = 0<<RtsfSHIFT,
- Rtsf256 = 1<<RtsfSHIFT,
- Rtsf512 = 2<<RtsfSHIFT,
- Rtsf1024 = 3<<RtsfSHIFT,
- RtsfSAF = 7<<RtsfSHIFT,
-};
-
-enum { /* Cr */
- Init = 0x0001, /* INIT Process Begin */
- Strt = 0x0002, /* Start NIC */
- Stop = 0x0004, /* Stop NIC */
- Rxon = 0x0008, /* Turn on Receive Process */
- Txon = 0x0010, /* Turn on Transmit Process */
- Tdmd = 0x0020, /* Transmit Poll Demand */
- Rdmd = 0x0040, /* Receive Poll Demand */
- Eren = 0x0100, /* Early Receive Enable */
- Fdx = 0x0400, /* Set MAC to Full Duplex Mode */
- Dpoll = 0x0800, /* Disable Td/Rd Auto Polling */
- Tdmd1 = 0x2000, /* Transmit Poll Demand 1 */
- Rdmd1 = 0x4000, /* Receive Poll Demand 1 */
- Sfrst = 0x8000, /* Software Reset */
-};
-
-enum { /* Isr/Imr */
- Prx = 0x0001, /* Received Packet Successfully */
- Ptx = 0x0002, /* Transmitted Packet Successfully */
- Rxe = 0x0004, /* Receive Error */
- Txe = 0x0008, /* Transmit Error */
- Tu = 0x0010, /* Transmit Buffer Underflow */
- Ru = 0x0020, /* Receive Buffer Link Error */
- Be = 0x0040, /* PCI Bus Error */
- Cnt = 0x0080, /* Counter Overflow */
- Eri = 0x0100, /* Early Receive Interrupt */
- Udfi = 0x0200, /* Tx FIFO Underflow */
- Ovfi = 0x0400, /* Receive FIFO Overflow */
- Pktrace = 0x0800, /* Hmmm... */
- Norbf = 0x1000, /* No Receive Buffers */
- Abti = 0x2000, /* Transmission Abort */
- Srci = 0x4000, /* Port State Change */
- Geni = 0x8000, /* General Purpose Interrupt */
-};
-
-enum { /* Phyadr */
- PhyadMASK = 0x1F, /* PHY Address */
- PhyadSHIFT = 0,
- Mfdc = 0x20, /* Accelerate MDC Speed */
- Mpo0 = 0x40, /* MII Polling Timer Interval */
- Mpo1 = 0x80,
-};
-
-enum { /* Bcr0 */
- DmaMASK = 0x07, /* DMA Length */
- DmaSHIFT = 0,
- Dma32 = 0<<DmaSHIFT,
- Dma64 = 1<<DmaSHIFT,
- Dma128 = 2<<DmaSHIFT,
- Dma256 = 3<<DmaSHIFT,
- Dma512 = 4<<DmaSHIFT,
- Dma1024 = 5<<DmaSHIFT,
- DmaSAF = 7<<DmaSHIFT,
- CrftMASK = 0x38, /* Rx FIFO Threshold */
- CrftSHIFT = 3,
- Crft64 = 1<<CrftSHIFT,
- Crft128 = 2<<CrftSHIFT,
- Crft256 = 3<<CrftSHIFT,
- Crft512 = 4<<CrftSHIFT,
- Crft1024 = 5<<CrftSHIFT,
- CrftSAF = 7<<CrftSHIFT,
- Extled = 0x40, /* Extra LED Support Control */
- Med2 = 0x80, /* Medium Select Control */
-};
-
-enum { /* Bcr1 */
- PotMASK = 0x07, /* Polling Timer Interval */
- PotSHIFT = 0,
- CtftMASK = 0x38, /* Tx FIFO Threshold */
- CtftSHIFT = 3,
- Ctft64 = 1<<CtftSHIFT,
- Ctft128 = 2<<CtftSHIFT,
- Ctft256 = 3<<CtftSHIFT,
- Ctft512 = 4<<CtftSHIFT,
- Ctft1024 = 5<<CtftSHIFT,
- CtftSAF = 7<<CtftSHIFT,
-};
-
-enum { /* Miicr */
- Mdc = 0x01, /* Clock */
- Mdi = 0x02, /* Data In */
- Mdo = 0x04, /* Data Out */
- Mout = 0x08, /* Output Enable */
- Mdpm = 0x10, /* Direct Program Mode Enable */
- Wcmd = 0x20, /* Write Enable */
- Rcmd = 0x40, /* Read Enable */
- Mauto = 0x80, /* Auto Polling Enable */
-};
-
-enum { /* Miiadr */
- MadMASK = 0x1F, /* MII Port Address */
- MadSHIFT = 0,
- Mdone = 0x20, /* Accelerate MDC Speed */
- Msrcen = 0x40, /* MII Polling Timer Interval */
- Midle = 0x80,
-};
-
-enum { /* Eecsr */
- Edo = 0x01, /* Data Out */
- Edi = 0x02, /* Data In */
- Eck = 0x04, /* Clock */
- Ecs = 0x08, /* Chip Select */
- Dpm = 0x10, /* Direct Program Mode Enable */
- Autold = 0x20, /* Dynamic Reload */
- Embp = 0x40, /* Embedded Program Enable */
- Eepr = 0x80, /* Programmed */
-};
-
-/*
- * Ring descriptor. The space allocated for each
- * of these will be rounded up to a cache-line boundary.
- * The first 4 elements are known to the hardware.
- */
-typedef struct Ds Ds;
-typedef struct Ds {
- uint status;
- uint control;
- uint addr;
- uint branch;
-
- Block* bp;
- void* bounce;
- Ds* next;
- Ds* prev;
-} Ds;
-
-enum { /* Rx Ds status */
- Rerr = 0x00000001, /* Receiver Error */
- Crc = 0x00000002, /* CRC Error */
- Fae = 0x00000004, /* Frame Alignment Error */
- Fov = 0x00000008, /* FIFO Overflow */
- Long = 0x00000010, /* A Long Packet */
- Runt = 0x00000020, /* A Runt Packet */
- Rxserr = 0x00000040, /* System Error */
- Buff = 0x00000080, /* Buffer Underflow Error */
- Rxedp = 0x00000100, /* End of Packet Buffer */
- Rxstp = 0x00000200, /* Packet Start */
- Chn = 0x00000400, /* Chain Buffer */
- Phy = 0x00000800, /* Physical Address Packet */
- Bar = 0x00001000, /* Broadcast Packet */
- Mar = 0x00002000, /* Multicast Packet */
- Rxok = 0x00008000, /* Packet Received Successfully */
- LengthMASK = 0x07FF0000, /* Received Packet Length */
- LengthSHIFT = 16,
-
- Own = 0x80000000, /* Descriptor Owned by NIC */
-};
-
-enum { /* Tx Ds status */
- NcrMASK = 0x0000000F, /* Collision Retry Count */
- NcrSHIFT = 0,
- Cols = 0x00000010, /* Experienced Collisions */
- Cdh = 0x00000080, /* CD Heartbeat */
- Abt = 0x00000100, /* Aborted after Excessive Collisions */
- Owc = 0x00000200, /* Out of Window Collision Seen */
- Crs = 0x00000400, /* Carrier Sense Lost */
- Udf = 0x00000800, /* FIFO Underflow */
- Tbuff = 0x00001000, /* Invalid Td */
- Txserr = 0x00002000, /* System Error */
- Terr = 0x00008000, /* Excessive Collisions */
-};
-
-enum { /* Tx Ds control */
- TbsMASK = 0x000007FF, /* Tx Buffer Size */
- TbsSHIFT = 0,
- Chain = 0x00008000, /* Chain Buffer */
- Crcdisable = 0x00010000, /* Disable CRC generation */
- Stp = 0x00200000, /* Start of Packet */
- Edp = 0x00400000, /* End of Packet */
- Ic = 0x00800000, /* Assert Interrupt Immediately */
-};
-
-enum {
- Nrd = 64,
- Ntd = 64,
- Rdbsz = ROUNDUP(ETHERMAXTU+4, 4),
-
- Nrxstats = 8,
- Ntxstats = 9,
-
- Txcopy = 128,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
- int port;
- Pcidev* pcidev;
- Ctlr* next;
- int active;
- int id;
- uchar par[Eaddrlen];
-
- QLock alock; /* attach */
- void* alloc; /* receive/transmit descriptors */
- int cls; /* alignment */
- int nrd;
- int ntd;
-
- Ds* rd;
- Ds* rdh;
-
- Lock tlock;
- Ds* td;
- Ds* tdh;
- Ds* tdt;
- int tdused;
-
- Lock clock; /* */
- int cr;
- int imr;
- int tft; /* Tx threshold */
-
- Mii* mii;
- Rendez lrendez;
- int lwakeup;
-
- uint rxstats[Nrxstats]; /* statistics */
- uint txstats[Ntxstats];
- uint intr;
- uint lintr;
- uint lsleep;
- uint rintr;
- uint tintr;
- uint taligned;
- uint tsplit;
- uint tcopied;
- uint txdw;
-} Ctlr;
-
-static Ctlr* vt6102ctlrhead;
-static Ctlr* vt6102ctlrtail;
-
-#define csr8r(c, r) (inb((c)->port+(r)))
-#define csr16r(c, r) (ins((c)->port+(r)))
-#define csr32r(c, r) (inl((c)->port+(r)))
-#define csr8w(c, r, b) (outb((c)->port+(r), (int)(b)))
-#define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
-#define csr32w(c, r, w) (outl((c)->port+(r), (ulong)(w)))
-
-static char* rxstats[Nrxstats] = {
- "Receiver Error",
- "CRC Error",
- "Frame Alignment Error",
- "FIFO Overflow",
- "Long Packet",
- "Runt Packet",
- "System Error",
- "Buffer Underflow Error",
-};
-static char* txstats[Ntxstats] = {
- "Aborted after Excessive Collisions",
- "Out of Window Collision Seen",
- "Carrier Sense Lost",
- "FIFO Underflow",
- "Invalid Td",
- "System Error",
- nil,
- "Excessive Collisions",
-};
-
-static long
-vt6102ifstat(Ether* edev, void* a, long n, ulong offset)
-{
- char *p;
- Ctlr *ctlr;
- int i, l, r;
-
- ctlr = edev->ctlr;
-
- p = malloc(2*READSTR);
- l = 0;
- for(i = 0; i < Nrxstats; i++){
- l += snprint(p+l, 2*READSTR-l, "%s: %ud\n",
- rxstats[i], ctlr->rxstats[i]);
- }
- for(i = 0; i < Ntxstats; i++){
- if(txstats[i] == nil)
- continue;
- l += snprint(p+l, 2*READSTR-l, "%s: %ud\n",
- txstats[i], ctlr->txstats[i]);
- }
- l += snprint(p+l, 2*READSTR-l, "cls: %ud\n", ctlr->cls);
- l += snprint(p+l, 2*READSTR-l, "intr: %ud\n", ctlr->intr);
- l += snprint(p+l, 2*READSTR-l, "lintr: %ud\n", ctlr->lintr);
- l += snprint(p+l, 2*READSTR-l, "lsleep: %ud\n", ctlr->lsleep);
- l += snprint(p+l, 2*READSTR-l, "rintr: %ud\n", ctlr->rintr);
- l += snprint(p+l, 2*READSTR-l, "tintr: %ud\n", ctlr->tintr);
- l += snprint(p+l, 2*READSTR-l, "taligned: %ud\n", ctlr->taligned);
- l += snprint(p+l, 2*READSTR-l, "tsplit: %ud\n", ctlr->tsplit);
- l += snprint(p+l, 2*READSTR-l, "tcopied: %ud\n", ctlr->tcopied);
- l += snprint(p+l, 2*READSTR-l, "txdw: %ud\n", ctlr->txdw);
- l += snprint(p+l, 2*READSTR-l, "tft: %ud\n", ctlr->tft);
-
- if(ctlr->mii != nil && ctlr->mii->curphy != nil){
- l += snprint(p+l, 2*READSTR, "phy: ");
- for(i = 0; i < NMiiPhyr; i++){
- if(i && ((i & 0x07) == 0))
- l += snprint(p+l, 2*READSTR-l, "\n ");
- r = miimir(ctlr->mii, i);
- l += snprint(p+l, 2*READSTR-l, " %4.4uX", r);
- }
- snprint(p+l, 2*READSTR-l, "\n");
- }
- snprint(p+l, 2*READSTR-l, "\n");
-
- n = readstr(offset, a, n, p);
- free(p);
-
- return n;
-}
-
-static void
-vt6102promiscuous(void* arg, int on)
-{
- int rcr;
- Ctlr *ctlr;
- Ether *edev;
-
- edev = arg;
- ctlr = edev->ctlr;
- rcr = csr8r(ctlr, Rcr);
- if(on)
- rcr |= Prom;
- else
- rcr &= ~Prom;
- csr8w(ctlr, Rcr, rcr);
-}
-
-static void
-vt6102multicast(void* arg, uchar* addr, int on)
-{
- /*
- * For now Am is set in Rcr.
- * Will need to interlock with promiscuous
- * when this gets filled in.
- */
- USED(arg, addr, on);
-}
-
-static int
-vt6102wakeup(void* v)
-{
- return *((int*)v) != 0;
-}
-
-static void
-vt6102imr(Ctlr* ctlr, int imr)
-{
- ilock(&ctlr->clock);
- ctlr->imr |= imr;
- csr16w(ctlr, Imr, ctlr->imr);
- iunlock(&ctlr->clock);
-}
-
-static void
-vt6102lproc(void* arg)
-{
- Ctlr *ctlr;
- Ether *edev;
- MiiPhy *phy;
-
- edev = arg;
- ctlr = edev->ctlr;
- for(;;){
- if(ctlr->mii == nil || ctlr->mii->curphy == nil)
- break;
- if(miistatus(ctlr->mii) < 0)
- goto enable;
-
- phy = ctlr->mii->curphy;
- ilock(&ctlr->clock);
- if(phy->fd)
- ctlr->cr |= Fdx;
- else
- ctlr->cr &= ~Fdx;
- csr16w(ctlr, Cr, ctlr->cr);
- iunlock(&ctlr->clock);
-enable:
- ctlr->lwakeup = 0;
- vt6102imr(ctlr, Srci);
-
- ctlr->lsleep++;
- sleep(&ctlr->lrendez, vt6102wakeup, &ctlr->lwakeup);
-
- }
- pexit("vt6102lproc: done", 1);
-}
-
-static void
-vt6102attach(Ether* edev)
-{
- int i;
- Ctlr *ctlr;
- Ds *ds, *prev;
- uchar *alloc, *bounce;
- char name[KNAMELEN];
-
- ctlr = edev->ctlr;
- qlock(&ctlr->alock);
- if(ctlr->alloc != nil){
- qunlock(&ctlr->alock);
- return;
- }
-
- /*
- * Descriptor and bounce-buffer space.
- * Must all be aligned on a 4-byte boundary,
- * but try to align on cache-lines.
- */
- ctlr->nrd = Nrd;
- ctlr->ntd = Ntd;
- alloc = malloc((ctlr->nrd+ctlr->ntd)*ctlr->cls + ctlr->ntd*Txcopy + ctlr->cls-1);
- if(alloc == nil){
- qunlock(&ctlr->alock);
- return;
- }
- ctlr->alloc = alloc;
- alloc = (uchar*)ROUNDUP((ulong)alloc, ctlr->cls);
-
- ctlr->rd = (Ds*)alloc;
-
- if(waserror()){
- ds = ctlr->rd;
- for(i = 0; i < ctlr->nrd; i++){
- if(ds->bp != nil){
- freeb(ds->bp);
- ds->bp = nil;
- }
- if((ds = ds->next) == nil)
- break;
- }
- free(ctlr->alloc);
- ctlr->alloc = nil;
- qunlock(&ctlr->alock);
- nexterror();
- }
-
- prev = ctlr->rd + ctlr->nrd-1;
- for(i = 0; i < ctlr->nrd; i++){
- ds = (Ds*)alloc;
- alloc += ctlr->cls;
-
- ds->control = Rdbsz;
- ds->branch = PCIWADDR(alloc);
-
- ds->bp = iallocb(Rdbsz+3);
- if(ds->bp == nil)
- error("vt6102: can't allocate receive ring\n");
- ds->bp->rp = (uchar*)ROUNDUP((ulong)ds->bp->rp, 4);
- ds->addr = PCIWADDR(ds->bp->rp);
-
- ds->next = (Ds*)alloc;
- ds->prev = prev;
- prev = ds;
-
- ds->status = Own;
- }
- prev->branch = 0;
- prev->next = ctlr->rd;
- prev->status = 0;
- ctlr->rdh = ctlr->rd;
-
- ctlr->td = (Ds*)alloc;
- prev = ctlr->td + ctlr->ntd-1;
- bounce = alloc + ctlr->ntd*ctlr->cls;
- for(i = 0; i < ctlr->ntd; i++){
- ds = (Ds*)alloc;
- alloc += ctlr->cls;
-
- ds->bounce = bounce;
- bounce += Txcopy;
- ds->next = (Ds*)alloc;
- ds->prev = prev;
- prev = ds;
- }
- prev->next = ctlr->td;
- ctlr->tdh = ctlr->tdt = ctlr->td;
- ctlr->tdused = 0;
-
- ctlr->cr = Dpoll|Rdmd|Txon|Rxon|Strt;
- /*Srci|Abti|Norbf|Pktrace|Ovfi|Udfi|Be|Ru|Tu|Txe|Rxe|Ptx|Prx*/
- ctlr->imr = Abti|Norbf|Pktrace|Ovfi|Udfi|Be|Ru|Tu|Txe|Rxe|Ptx|Prx;
-
- ilock(&ctlr->clock);
- csr32w(ctlr, Rxdaddr, PCIWADDR(ctlr->rd));
- csr32w(ctlr, Txdaddr, PCIWADDR(ctlr->td));
- csr16w(ctlr, Isr, ~0);
- csr16w(ctlr, Imr, ctlr->imr);
- csr16w(ctlr, Cr, ctlr->cr);
- iunlock(&ctlr->clock);
-
- snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
- kproc(name, vt6102lproc, edev, 0);
-
- qunlock(&ctlr->alock);
- poperror();
-}
-
-static void
-vt6102transmit(Ether* edev)
-{
- Block *bp;
- Ctlr *ctlr;
- Ds *ds, *next;
- int control, i, o, prefix, size, tdused, timeo;
-
- ctlr = edev->ctlr;
-
- ilock(&ctlr->tlock);
-
- /*
- * Free any completed packets
- */
- ds = ctlr->tdh;
- for(tdused = ctlr->tdused; tdused > 0; tdused--){
- /*
- * For some errors the chip will turn the Tx engine
- * off. Wait for that to happen.
- * Could reset and re-init the chip here if it doesn't
- * play fair.
- * To do: adjust Tx FIFO threshold on underflow.
- */
- if(ds->status & (Abt|Tbuff|Udf)){
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr16r(ctlr, Cr) & Txon))
- break;
- microdelay(1);
- }
- ds->status = Own;
- csr32w(ctlr, Txdaddr, PCIWADDR(ds));
- }
-
- if(ds->status & Own)
- break;
- ds->addr = 0;
- ds->branch = 0;
-
- if(ds->bp != nil){
- freeb(ds->bp);
- ds->bp = nil;
- }
- for(i = 0; i < Ntxstats-1; i++){
- if(ds->status & (1<<i))
- ctlr->txstats[i]++;
- }
- ctlr->txstats[i] += (ds->status & NcrMASK)>>NcrSHIFT;
-
- ds = ds->next;
- }
- ctlr->tdh = ds;
-
- /*
- * Try to fill the ring back up.
- */
- ds = ctlr->tdt;
- while(tdused < ctlr->ntd-2){
- if((bp = qget(edev->oq)) == nil)
- break;
- tdused++;
-
- size = BLEN(bp);
- prefix = 0;
-
- if(o = (((int)bp->rp) & 0x03)){
- prefix = Txcopy-o;
- if(prefix > size)
- prefix = size;
- memmove(ds->bounce, bp->rp, prefix);
- ds->addr = PCIWADDR(ds->bounce);
- bp->rp += prefix;
- size -= prefix;
- }
-
- next = ds->next;
- ds->branch = PCIWADDR(ds->next);
-
- if(size){
- if(prefix){
- next->bp = bp;
- next->addr = PCIWADDR(bp->rp);
- next->branch = PCIWADDR(next->next);
- next->control = Edp|Chain|((size<<TbsSHIFT) & TbsMASK);
-
- control = Stp|Chain|((prefix<<TbsSHIFT) & TbsMASK);
-
- next = next->next;
- tdused++;
- ctlr->tsplit++;
- }
- else{
- ds->bp = bp;
- ds->addr = PCIWADDR(bp->rp);
- control = Edp|Stp|((size<<TbsSHIFT) & TbsMASK);
- ctlr->taligned++;
- }
- }
- else{
- freeb(bp);
- control = Edp|Stp|((prefix<<TbsSHIFT) & TbsMASK);
- ctlr->tcopied++;
- }
-
- ds->control = control;
- if(tdused >= ctlr->ntd-2){
- ds->control |= Ic;
- ctlr->txdw++;
- }
- coherence();
- ds->status = Own;
-
- ds = next;
- }
- ctlr->tdt = ds;
- ctlr->tdused = tdused;
- if(ctlr->tdused)
- csr16w(ctlr, Cr, Tdmd|ctlr->cr);
-
- iunlock(&ctlr->tlock);
-}
-
-static void
-vt6102receive(Ether* edev)
-{
- Ds *ds;
- Block *bp;
- Ctlr *ctlr;
- int i, len;
-
- ctlr = edev->ctlr;
-
- ds = ctlr->rdh;
- while(!(ds->status & Own) && ds->status != 0){
- if(ds->status & Rerr){
- for(i = 0; i < Nrxstats; i++){
- if(ds->status & (1<<i))
- ctlr->rxstats[i]++;
- }
- }
- else if(bp = iallocb(Rdbsz+3)){
- len = ((ds->status & LengthMASK)>>LengthSHIFT)-4;
- ds->bp->wp = ds->bp->rp+len;
- etheriq(edev, ds->bp, 1);
- bp->rp = (uchar*)ROUNDUP((ulong)bp->rp, 4);
- ds->addr = PCIWADDR(bp->rp);
- ds->bp = bp;
- }
- ds->control = Rdbsz;
- ds->branch = 0;
- ds->status = 0;
-
- ds->prev->branch = PCIWADDR(ds);
- coherence();
- ds->prev->status = Own;
-
- ds = ds->next;
- }
- ctlr->rdh = ds;
-
- csr16w(ctlr, Cr, ctlr->cr);
-}
-
-static void
-vt6102interrupt(Ureg*, void* arg)
-{
- Ctlr *ctlr;
- Ether *edev;
- int imr, isr, r, timeo;
-
- edev = arg;
- ctlr = edev->ctlr;
-
- ilock(&ctlr->clock);
- csr16w(ctlr, Imr, 0);
- imr = ctlr->imr;
- ctlr->intr++;
- for(;;){
- if((isr = csr16r(ctlr, Isr)) != 0)
- csr16w(ctlr, Isr, isr);
- if((isr & ctlr->imr) == 0)
- break;
-
- if(isr & Srci){
- imr &= ~Srci;
- ctlr->lwakeup = isr & Srci;
- wakeup(&ctlr->lrendez);
- isr &= ~Srci;
- ctlr->lintr++;
- }
- if(isr & (Norbf|Pktrace|Ovfi|Ru|Rxe|Prx)){
- vt6102receive(edev);
- isr &= ~(Norbf|Pktrace|Ovfi|Ru|Rxe|Prx);
- ctlr->rintr++;
- }
- if(isr & (Abti|Udfi|Tu|Txe|Ptx)){
- if(isr & (Abti|Udfi|Tu)){
- for(timeo = 0; timeo < 1000; timeo++){
- if(!(csr16r(ctlr, Cr) & Txon))
- break;
- microdelay(1);
- }
-
- if((isr & Udfi) && ctlr->tft < CtftSAF){
- ctlr->tft += 1<<CtftSHIFT;
- r = csr8r(ctlr, Bcr1) & ~CtftMASK;
- csr8w(ctlr, Bcr1, r|ctlr->tft);
- }
- }
- vt6102transmit(edev);
- isr &= ~(Abti|Udfi|Tu|Txe|Ptx);
- ctlr->tintr++;
- }
- if(isr)
- panic("vt6102: isr %4.4uX\n", isr);
- }
- ctlr->imr = imr;
- csr16w(ctlr, Imr, ctlr->imr);
- iunlock(&ctlr->clock);
-}
-
-static int
-vt6102miimicmd(Mii* mii, int pa, int ra, int cmd, int data)
-{
- Ctlr *ctlr;
- int r, timeo;
-
- ctlr = mii->ctlr;
-
- csr8w(ctlr, Miicr, 0);
- r = csr8r(ctlr, Phyadr);
- csr8w(ctlr, Phyadr, (r & ~PhyadMASK)|pa);
- csr8w(ctlr, Phyadr, pa);
- csr8w(ctlr, Miiadr, ra);
- if(cmd == Wcmd)
- csr16w(ctlr, Miidata, data);
- csr8w(ctlr, Miicr, cmd);
-
- for(timeo = 0; timeo < 10000; timeo++){
- if(!(csr8r(ctlr, Miicr) & cmd))
- break;
- microdelay(1);
- }
- if(timeo >= 10000)
- return -1;
-
- if(cmd == Wcmd)
- return 0;
- return csr16r(ctlr, Miidata);
-}
-
-static int
-vt6102miimir(Mii* mii, int pa, int ra)
-{
- return vt6102miimicmd(mii, pa, ra, Rcmd, 0);
-}
-
-static int
-vt6102miimiw(Mii* mii, int pa, int ra, int data)
-{
- return vt6102miimicmd(mii, pa, ra, Wcmd, data);
-}
-
-static int
-vt6102detach(Ctlr* ctlr)
-{
- int timeo;
-
- /*
- * Soft reset the controller.
- */
- csr16w(ctlr, Cr, Sfrst);
- for(timeo = 0; timeo < 10000; timeo++){
- if(!(csr16r(ctlr, Cr) & Sfrst))
- break;
- microdelay(1);
- }
- if(timeo >= 1000)
- return -1;
-
- return 0;
-}
-
-static int
-vt6102reset(Ctlr* ctlr)
-{
- MiiPhy *phy;
- int i, r, timeo;
-
- if(vt6102detach(ctlr) < 0)
- return -1;
-
- /*
- * Load the MAC address into the PAR[01]
- * registers.
- */
- r = csr8r(ctlr, Eecsr);
- csr8w(ctlr, Eecsr, Autold|r);
- for(timeo = 0; timeo < 100; timeo++){
- if(!(csr8r(ctlr, Cr) & Autold))
- break;
- microdelay(1);
- }
- if(timeo >= 100)
- return -1;
-
- for(i = 0; i < Eaddrlen; i++)
- ctlr->par[i] = csr8r(ctlr, Par0+i);
-
- /*
- * Configure DMA and Rx/Tx thresholds.
- * If the Rx/Tx threshold bits in Bcr[01] are 0 then
- * the thresholds are determined by Rcr/Tcr.
- */
- r = csr8r(ctlr, Bcr0) & ~(CrftMASK|DmaMASK);
- csr8w(ctlr, Bcr0, r|Crft64|Dma64);
- r = csr8r(ctlr, Bcr1) & ~CtftMASK;
- csr8w(ctlr, Bcr1, r|ctlr->tft);
-
- r = csr8r(ctlr, Rcr) & ~(RrftMASK|Prom|Ar|Sep);
- csr8w(ctlr, Rcr, r|Ab|Am);
-
- r = csr8r(ctlr, Tcr) & ~(RtsfMASK|Ofset|Lb1|Lb0);
- csr8w(ctlr, Tcr, r);
-
- /*
- * Link management.
- */
- if((ctlr->mii = malloc(sizeof(Mii))) == nil)
- return -1;
- ctlr->mii->mir = vt6102miimir;
- ctlr->mii->miw = vt6102miimiw;
- ctlr->mii->ctlr = ctlr;
-
- if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
- free(ctlr->mii);
- ctlr->mii = nil;
- return -1;
- }
- // print("oui %X phyno %d\n", phy->oui, phy->phyno);
- USED(phy);
-
- //miiane(ctlr->mii, ~0, ~0, ~0);
-
- return 0;
-}
-
-static void
-vt6102pci(void)
-{
- Pcidev *p;
- Ctlr *ctlr;
- int cls, port;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- if(p->ccrb != Pcibcnet || p->ccru != Pciscether)
- continue;
-
- switch((p->did<<16)|p->vid){
- default:
- continue;
- case (0x3065<<16)|0x1106: /* Rhine II */
- case (0x3106<<16)|0x1106: /* Rhine III */
- break;
- }
-
- port = p->mem[0].bar & ~0x01;
- if(ioalloc(port, p->mem[0].size, 0, "vt6102") < 0){
- print("vt6102: port 0x%uX in use\n", port);
- continue;
- }
- ctlr = malloc(sizeof(Ctlr));
- ctlr->port = port;
- ctlr->pcidev = p;
- ctlr->id = (p->did<<16)|p->vid;
- if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
- cls = 0x10;
- ctlr->cls = cls*4;
- if(ctlr->cls < sizeof(Ds)){
- print("vt6102: cls %d < sizeof(Ds)\n", ctlr->cls);
- iofree(port);
- free(ctlr);
- continue;
- }
- ctlr->tft = Ctft64;
-
- if(vt6102reset(ctlr)){
- iofree(port);
- free(ctlr);
- continue;
- }
- pcisetbme(p);
-
- if(vt6102ctlrhead != nil)
- vt6102ctlrtail->next = ctlr;
- else
- vt6102ctlrhead = ctlr;
- vt6102ctlrtail = ctlr;
- }
-}
-
-static int
-vt6102pnp(Ether* edev)
-{
- Ctlr *ctlr;
-
- if(vt6102ctlrhead == nil)
- vt6102pci();
-
- /*
- * Any adapter matches if no edev->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = vt6102ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(edev->port == 0 || edev->port == ctlr->port){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- edev->ctlr = ctlr;
- edev->port = ctlr->port;
- edev->irq = ctlr->pcidev->intl;
- edev->tbdf = ctlr->pcidev->tbdf;
- edev->mbps = 100;
- memmove(edev->ea, ctlr->par, Eaddrlen);
-
- /*
- * Linkage to the generic ethernet driver.
- */
- edev->attach = vt6102attach;
- edev->transmit = vt6102transmit;
- edev->interrupt = vt6102interrupt;
- edev->ifstat = vt6102ifstat;
- edev->ctl = nil;
-
- edev->arg = edev;
- edev->promiscuous = vt6102promiscuous;
- edev->multicast = vt6102multicast;
-
- return 0;
-}
-
-void
-ethervt6102link(void)
-{
- addethercard("vt6102", vt6102pnp);
- addethercard("rhine", vt6102pnp);
-}
diff --git a/os/pc/etherwavelan.c b/os/pc/etherwavelan.c
deleted file mode 100644
index e76905b5..00000000
--- a/os/pc/etherwavelan.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/* Pci/pcmcia code for wavelan.c */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-#include "etherif.h"
-
-#include "wavelan.h"
-
-static int
-wavelanpcmciareset(Ether *ether)
-{
- int i;
- char *p;
- Ctlr *ctlr;
-
- if((ctlr = malloc(sizeof(Ctlr))) == nil)
- return -1;
-
- ilock(ctlr);
- ctlr->ctlrno = ether->ctlrno;
-
- if (ether->port==0)
- ether->port=WDfltIOB;
- ctlr->iob = ether->port;
-
- if (ether->irq==0)
- ether->irq=WDfltIRQ;
-
- if (ioalloc(ether->port,WIOLen,0,"wavelan")<0){
- // print("#l%d: port 0x%lx in use\n",
- // ether->ctlrno, ether->port);
- goto abort1;
- }
-
- /*
- * If id= is specified, card must match. Otherwise try generic.
- */
- ctlr->slot = -1;
- for(i=0; i<ether->nopt; i++){
- if(cistrncmp(ether->opt[i], "id=", 3) == 0){
- if((ctlr->slot = pcmspecial(&ether->opt[i][3], ether)) < 0)
- goto abort;
- break;
- }
- }
- if(ctlr->slot == -1){
- for (i=0; wavenames[i]; i++)
- if((ctlr->slot = pcmspecial(wavenames[i], ether))>=0)
- break;
- if(!wavenames[i]){
- DEBUG("no wavelan found\n");
- goto abort;
- }
- }
-
- // DEBUG("#l%d: port=0x%lx irq=%ld\n",
- // ether->ctlrno, ether->port, ether->irq);
-
- if(wavelanreset(ether, ctlr) < 0){
- abort:
- iofree(ether->port);
- abort1:
- iunlock(ctlr);
- free(ctlr);
- ether->ctlr = nil;
- return -1;
- }
-
- for(i = 0; i < ether->nopt; i++){
- if(p = strchr(ether->opt[i], '='))
- *p = ' ';
- w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));
- }
-
- iunlock(ctlr);
- return 0;
-}
-
-static struct {
- int vid;
- int did;
-} wavelanpci[] = {
- 0x1260, 0x3873, /* Intersil Prism2.5 */
- 0x1737, 0x0019, /* Linksys WPC-11 untested */
-};
-
-static Ctlr *ctlrhead, *ctlrtail;
-
-static void
-wavelanpciscan(void)
-{
- int i;
- void *mem;
- Pcidev *p;
- Ctlr *ctlr;
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- for(i=0; i<nelem(wavelanpci); i++)
- if(p->vid == wavelanpci[i].vid && p->did == wavelanpci[i].did)
- break;
- if(i==nelem(wavelanpci))
- continue;
-
- /*
- * On the Prism, bar[0] is the memory-mapped register address (4KB),
- */
- if(p->mem[0].size != 4096){
- print("wavelanpci: %.4ux %.4ux: unlikely mmio size\n", p->vid, p->did);
- continue;
- }
-
- ctlr = malloc(sizeof(Ctlr));
- ctlr->pcidev = p;
- mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);
- if(mem == nil){
- print("wavelanpci: %.4ux %.4ux: vmap 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
- free(ctlr);
- continue;
- }
- ctlr->mmb = mem;
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- pcisetbme(p);
- }
-}
-
-static int
-wavelanpcireset(Ether *ether)
-{
- int i;
- char *p;
- Ctlr *ctlr;
-
- if(ctlrhead == nil)
- wavelanpciscan();
-
- /*
- * Allow plan9.ini to set vid, did?
- */
- for(ctlr=ctlrhead; ctlr!=nil; ctlr=ctlr->next)
- if(ctlr->active == 0)
- break;
- if(ctlr == nil)
- return -1;
-
- ctlr->active = 1;
- ilock(ctlr);
- ether->irq = ctlr->pcidev->intl;
- ether->tbdf = ctlr->pcidev->tbdf;
-
- /*
- * Really hard reset.
- */
- csr_outs(ctlr, WR_PciCor, 0x0080);
- delay(250);
- csr_outs(ctlr, WR_PciCor, 0x0000);
- delay(500);
- for(i=0; i<2*10; i++){
- if(!(csr_ins(ctlr, WR_Cmd)&WCmdBusy))
- break;
- delay(100);
- }
- if(i >= 2*10)
- print("wavelan pci %.4ux %.4ux: reset timeout %.4ux\n",
- ctlr->pcidev->vid, ctlr->pcidev->did, csr_ins(ctlr, WR_Cmd));
-
- if(wavelanreset(ether, ctlr) < 0){
- iunlock(ctlr);
- ether->ctlr = nil;
- return -1;
- }
-
- for(i = 0; i < ether->nopt; i++){
- if(p = strchr(ether->opt[i], '='))
- *p = ' ';
- w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));
- }
- iunlock(ctlr);
- return 0;
-}
-
-void
-etherwavelanlink(void)
-{
- addethercard("wavelan", wavelanpcmciareset);
- addethercard("wavelanpci", wavelanpcireset);
-}
diff --git a/os/pc/flashif.h b/os/pc/flashif.h
deleted file mode 100644
index b5391798..00000000
--- a/os/pc/flashif.h
+++ /dev/null
@@ -1,82 +0,0 @@
-typedef struct Flash Flash;
-typedef struct Flashpart Flashpart;
-typedef struct Flashregion Flashregion;
-
-/*
- * logical partitions
- */
-enum {
- Maxflashpart = 8
-};
-
-struct Flashpart {
- char* name;
- ulong start;
- ulong end;
-};
-
-enum {
- Maxflashregion = 8
-};
-
-/*
- * physical erase block regions
- */
-struct Flashregion {
- int n; /* number of blocks in region */
- ulong start; /* physical base address (allowing for banks) */
- ulong end;
- ulong erasesize;
-};
-
-/*
- * structure defining a flash memory card
- */
-struct Flash {
- QLock; /* interlock on flash operations */
- Flash* next;
-
- /* the following are filled in by devflash before Flash.reset called */
- char* name;
- void* addr;
- ulong size;
- int (*reset)(Flash*);
-
- /* the following are filled in by the reset routine */
- int (*eraseall)(Flash*);
- int (*erasezone)(Flash*, int);
- int (*write)(Flash*, ulong, void*, long); /* writes of correct width and alignment */
- int (*suspend)(Flash*);
- int (*resume)(Flash*);
-
- /* the following might be filled in by either archflashreset or the reset routine */
- int nr;
- Flashregion regions[Maxflashregion];
-
- uchar id; /* flash manufacturer ID */
- uchar devid; /* flash device ID */
- int width; /* bytes per flash line */
- int erasesize; /* size of erasable unit (accounting for width) */
- void* data; /* flash type routines' private storage, or nil */
- ulong unusable; /* bit mask of unusable sections */
- Flashpart part[Maxflashpart]; /* logical partitions */
- int protect; /* software protection */
-};
-
-/*
- * called by link routine of driver for specific flash type: arguments are
- * conventional name for card type/model, and card driver's reset routine.
- */
-void addflashcard(char*, int (*)(Flash*));
-
-/*
- * called by devflash.c:/^flashreset; if flash exists,
- * sets type, address, and size in bytes of flash
- * and returns 0; returns -1 if flash doesn't exist
- */
-int archflashreset(char*, void**, long*);
-
-/*
- * enable/disable write protect
- */
-void archflashwp(int);
diff --git a/os/pc/flashzpc.c b/os/pc/flashzpc.c
deleted file mode 100644
index c360f7bf..00000000
--- a/os/pc/flashzpc.c
+++ /dev/null
@@ -1,371 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#include "flashif.h"
-
-#define FLASHMEM 0xfff80000
-#define FLASHPGSZ 0x40000
-#define FLASHBKSZ (FLASHPGSZ>>2)
-#define LOG2FPGSZ 18
-#define FLASHEND (FLASHMEM+FLASHPGSZ)
-#define SYSREG0 0x78
-#define SYSREG1 0x878
-
-/* Intel28F016SA flash memory family (8SA and (DD)32SA as well) in byte mode */
-
-/*
- * word mode does not work - a 2 byte write to a location results in the lower address
- * byte being unchanged (4 byte writes are even stranger) and no indication of error.
- * Perhaps the bridge is interfering with the address lines.
- * Looks like the BIOS code doesn't use it either but that's not certain.
- */
-
-/*
- * When port 0x78 bit 2 is set to 1 (flash device 1)
- * 0xfff80000-0xfffbffff seems to be free but has dos block headers
- * 0xfffc0000-0xfffdffff seems to be the DOS P: drive
- * 0xfffe0000-0xffffffff is the BIOS
- * When port 0x78 bit 2 is set to 0 (flash device 0)
- * 0xfff80000-0xffffffff is a mixture of used and unused DOS blocks and apparently
- * many copies of the BIOS
- *
- * In the absence of information from Ziatech and to preserve the BIOS and DOS sections,
- * this driver only uses the first range for a total of 8 x 0x40000 = 2Mb
- */
-
-enum {
- DQ7 = 0x80,
- DQ6 = 0x40,
- DQ5 = 0x20,
- DQ4 = 0x10,
- DQ3 = 0x08,
- DQ2 = 0x04,
- DQ1 = 0x02,
- DQ0 = 0x01,
-};
-
-enum {
- FLRDM = 0xFF, /* read */
- FLWTM = 0x10, /* write/program */
- FLCLR = 0x50, /* clear SR */
- FLBE1 = 0x20, /* block erase */
- FLBE2 = 0xD0, /* block erase */
- FLRSR = 0x70, /* read SR */
- FLDID = 0x90, /* read id */
-};
-
-#define DPRINT if(0)print
-#define EPRINT if(1)print
-
-static int
-zpcwait(uchar *p, ulong ticks)
-{
- uchar csr;
-
- ticks += m->ticks+1;
- while((*p & DQ7) != DQ7){
- sched();
- if(m->ticks >= ticks){
- EPRINT("flash: timed out: %8.8lux\n", (ulong)*p);
- return -1;
- }
- }
- csr = *p;
- if(csr & (DQ5|DQ4|DQ3)){
- EPRINT("flash: DQ5 error: %8.8lux %8.8lux\n", p, (ulong)csr);
- return 0;
- }
- return 1;
-}
-
-static int
-eraseall(Flash *f)
-{
- uchar r;
- uchar *p;
- int i, j, s;
-
- DPRINT("flash: erase all\n");
- for (i = 0; i < 8; i++) { /* page */
- /* set page */
- r = inb(SYSREG0);
- r &= 0x8f;
- r |= i<<4;
- outb(SYSREG0, r);
- p = (uchar *)f->addr;
- for (j = 0; j < 4; j++) { /* block within page */
- DPRINT("erasing page %d block %d addr %lux\n", i, j, p);
- s = splhi();
- *p = FLBE1;
- *p = FLBE2;
- splx(s);
- if(zpcwait(p, MS2TK(16*1000)) <= 0){
- *p = FLCLR; /* clr SR */
- *p = FLRDM; /* read mode */
- f->unusable = ~0;
- return -1;
- }
- *p = FLCLR;
- *p = FLRDM;
- p += FLASHPGSZ>>2;
- }
- }
- return 0;
-}
-
-static int
-erasezone(Flash *f, int zone)
-{
- uchar r;
- uchar *p;
- int s, pg, blk;
-
- DPRINT("flash: erase zone %d\n", zone);
- if(zone & ~31) {
- EPRINT("flash: bad erasezone %d\n", zone);
- return -1; /* bad zone */
- }
- pg = zone>>2;
- blk = zone&3;
- /* set page */
- r = inb(SYSREG0);
- r &= 0x8f;
- r |= pg<<4;
- outb(SYSREG0, r);
- p = (uchar *)f->addr + blk*(FLASHPGSZ>>2);
- DPRINT("erasing zone %d pg %d blk %d addr %lux\n", zone, pg, blk, p);
- s = splhi();
- *p = FLBE1;
- *p = FLBE2;
- splx(s);
- if(zpcwait(p, MS2TK(8*1000)) <= 0){
- *p = FLCLR;
- *p = FLRDM; /* reset */
- f->unusable |= 1<<zone;
- return -1;
- }
- *p = FLCLR;
- *p = FLRDM;
- return 0;
-}
-
-static int
-readx(Flash *f, ulong offset, void *buf, long n)
-{
- uchar r;
- ulong pg, o;
- long m;
- uchar *p = buf;
-
- pg = offset>>LOG2FPGSZ;
- o = offset&(FLASHPGSZ-1);
- while (n > 0) {
- if (pg < 0 || pg > 7) {
- EPRINT("flash: bad read %ld %ld\n", offset, n);
- return -1;
- }
- /* set page */
- r = inb(SYSREG0);
- r &= 0x8f;
- r |= pg<<4;
- outb(SYSREG0, r);
- if (o+n > FLASHPGSZ)
- m = FLASHPGSZ-o;
- else
- m = n;
- DPRINT("flash: read page %ld offset %lux buf %lux n %ld\n", pg, o, p-(uchar*)buf, m);
- memmove(p, (uchar *)f->addr + o, m);
- p += m;
- n -= m;
- pg++;
- o = 0;
- }
- return 0;
-}
-
-static int
-writex(Flash *f, ulong offset, void *buf, long n)
-{
- int i, s;
- uchar r;
- ulong pg, o;
- long m;
- uchar *a, *v = buf;
-
- DPRINT("flash: writex\n");
- pg = offset>>LOG2FPGSZ;
- o = offset&(FLASHPGSZ-1);
- while (n > 0) {
- if (pg < 0 || pg > 7) {
- EPRINT("flash: bad write %ld %ld\n", offset, n);
- return -1;
- }
- /* set page */
- r = inb(SYSREG0);
- r &= 0x8f;
- r |= pg<<4;
- outb(SYSREG0, r);
- if (o+n > FLASHPGSZ)
- m = FLASHPGSZ-o;
- else
- m = n;
- a = (uchar *)f->addr + o;
- DPRINT("flash: write page %ld offset %lux buf %lux n %ld\n", pg, o, v-(uchar*)buf, m);
- for (i = 0; i < m; i++, v++, a++) {
- if (~*a & *v) {
- EPRINT("flash: bad write: %lux %lux -> %lux\n", (ulong)a, (ulong)*a, (ulong)*v);
- return -1;
- }
- if (*a == *v)
- continue;
- s = splhi();
- *a = FLWTM; /* program */
- *a = *v;
- splx(s);
- microdelay(8);
- if(zpcwait(a, 5) <= 0){
- *a = FLCLR; /* clr SR */
- *a = FLRDM; /* read mode */
- f->unusable = ~0;
- return -1;
- }
- *a = FLCLR;
- *a = FLRDM;
- if (*a != *v) {
- EPRINT("flash: write %lux %lux -> %lux failed\n", (ulong)a, (ulong)*a, (ulong)*v);
- return -1;
- }
- }
- n -= m;
- pg++;
- o = 0;
- }
- return 0;
-}
-
-#ifdef ZERO
-/* search the whole of flash */
-static void
-flashsearch(Flash *f)
-{
- int d, m, p, b, n, i;
- uchar r, buf[64];
-
- for (d = 0; d < 2; d++) { /* flash device */
- r = inb(SYSREG0);
- r &= 0xfb;
- r |= (d<<2);
- outb(SYSREG0, r);
- for (m = 0; m < 2; m++) { /* lower/upper mem */
- if (m == 0)
- f->addr = (void *)FLASHMEM;
- else
- f->addr = (void *)FLASHEND;
- for (p = 0; p < 8; p++) { /* page */
- for (b = 0; b < 4; b++) { /* block */
- n = readx(f, (4*p+b)*FLASHBKSZ, buf, 64);
- if (n != 0) {
- print("bad read in search %d\n", n);
- goto end;
- }
- print("%d %d %d %d : ", d, m, p, b);
- if (buf[0] == 0x5a && buf[1] == 0x54) { /* DOS block */
- n = 0;
- for (i = 0; i < 64; i++) {
- if (buf[i] == 0xff)
- n++;
- }
- if (n == 64-28)
- print("un");
- print("used dos\n");
- }
- else if (buf[0] == 0x55 && buf[1] == 0xaa)
- print("bios start\n");
- else
- print("bios ?\n");
- }
- }
- }
- }
-end:
- r = inb(SYSREG0);
- r |= 4;
- outb(SYSREG0, r);
- f->addr = (void *)FLASHMEM;
-}
-#endif
-
-static int
-reset(Flash *f)
-{
- uchar r;
- int s;
- ulong pa;
- Pcidev *bridge;
-
- /* get bridge device */
- bridge = pcimatch(nil, 0x8086, 0x7000); /* Intel PIIX3 ISA bridge device */
- if (bridge == nil) {
- EPRINT("flash : failed to find bridge device\n");
- return 1;
- }
- /* enable extended BIOS and read/write */
- s = splhi();
- r = pcicfgr8(bridge, 0x4e);
- r |= 0x84;
- pcicfgw8(bridge, 0x4e, r);
- splx(s);
- /* set system register bits */
- r = inb(SYSREG0);
- r |= 0x86; /* chip enable, non-BIOS part, set r/w */
- outb(SYSREG0, r);
- /*
- * might have to grab memory starting at PADDR(FLASHMEM) ie 0x7ff80000
- * because if this is mapped via virtual address FLASHMEM we would get a
- * a kernel panic in mmukmap().
- * va = 0xfff80000 pa = 0xfff80000 for flash
- * va = 0xfff80000 pa = 0x7ff80000 if lower memory grabbed by anything
- */
- /*
- * upafree(FLASHMEM, FLASHPGSZ);
- * pa = upamalloc(FLASHMEM, FLASHPGSZ, 0);
- * if (pa != FLASHMEM)
- * error
- */
- pa = mmukmap(FLASHMEM, FLASHMEM, FLASHPGSZ);
- if (pa != FLASHEND) {
- EPRINT("failed to map flash memory");
- return 1;
- }
-/*
- pa = mmukmap(FLASHEND, FLASHEND, FLASHPGSZ);
- if (pa != 0) {
- EPRINT("failed to map flash memory");
- return 1;
- }
-*/
- f->id = 0x0089; /* can't use autoselect: might be running in flash */
- f->devid = 0x66a0;
- f->read = readx;
- f->write = writex;
- f->eraseall = eraseall;
- f->erasezone = erasezone;
- f->suspend = nil;
- f->resume = nil;
- f->width = 1; /* must be 1 since devflash.c must not read directly */
- f->erasesize = 64*1024;
- *(uchar*)f->addr = FLCLR; /* clear status registers */
- *(uchar*)f->addr = FLRDM; /* reset to read mode */
- return 0;
-}
-
-void
-flashzpclink(void)
-{
- addflashcard("DD28F032SA", reset);
-}
diff --git a/os/pc/floppy.h b/os/pc/floppy.h
deleted file mode 100644
index f84c9eae..00000000
--- a/os/pc/floppy.h
+++ /dev/null
@@ -1,183 +0,0 @@
-typedef struct FController FController;
-typedef struct FDrive FDrive;
-typedef struct FType FType;
-
-static void floppyintr(Ureg*);
-static int floppyon(FDrive*);
-static void floppyoff(FDrive*);
-static void floppysetdef(FDrive*);
-
-/*
- * a floppy drive
- */
-struct FDrive
-{
- FType *t; /* floppy type */
- int dt; /* drive type */
- int dev;
-
- ulong lasttouched; /* time last touched */
- int cyl; /* current arm position */
- int confused; /* needs to be recalibrated */
- int vers;
- int maxtries; /* max read attempts before Eio */
-
- int tcyl; /* target cylinder */
- int thead; /* target head */
- int tsec; /* target sector */
- long len; /* size of xfer */
-
- uchar *cache; /* track cache */
- int ccyl;
- int chead;
-};
-
-/*
- * controller for 4 floppys
- */
-struct FController
-{
- QLock; /* exclusive access to the contoller */
-
- int ndrive;
- FDrive *d; /* the floppy drives */
- FDrive *selected;
- int rate; /* current rate selected */
- uchar cmd[14]; /* command */
- int ncmd; /* # command bytes */
- uchar stat[14]; /* command status */
- int nstat; /* # status bytes */
- int confused; /* controler needs to be reset */
- Rendez r; /* wait here for command termination */
- int motor; /* bit mask of spinning disks */
-};
-
-/*
- * floppy types (all MFM encoding)
- */
-struct FType
-{
- char *name;
- int dt; /* compatible drive type */
- int bytes; /* bytes/sector */
- int sectors; /* sectors/track */
- int heads; /* number of heads */
- int steps; /* steps per cylinder */
- int tracks; /* tracks/disk */
- int gpl; /* intersector gap length for read/write */
- int fgpl; /* intersector gap length for format */
- int rate; /* rate code */
-
- /*
- * these depend on previous entries and are set filled in
- * by floppyinit
- */
- int bcode; /* coded version of bytes for the controller */
- long cap; /* drive capacity in bytes */
- long tsize; /* track size in bytes */
-};
-/* bits in the registers */
-enum
-{
- /* status registers a & b */
- Psra= 0x3f0,
- Psrb= 0x3f1,
-
- /* digital output register */
- Pdor= 0x3f2,
- Fintena= 0x8, /* enable floppy interrupt */
- Fena= 0x4, /* 0 == reset controller */
-
- /* main status register */
- Pmsr= 0x3f4,
- Fready= 0x80, /* ready to be touched */
- Ffrom= 0x40, /* data from controller */
- Ffloppybusy= 0x10, /* operation not over */
-
- /* data register */
- Pfdata= 0x3f5,
- Frecal= 0x07, /* recalibrate cmd */
- Fseek= 0x0f, /* seek cmd */
- Fsense= 0x08, /* sense cmd */
- Fread= 0x66, /* read cmd */
- Freadid= 0x4a, /* read track id */
- Fspec= 0x03, /* set hold times */
- Fwrite= 0x45, /* write cmd */
- Fformat= 0x4d, /* format cmd */
- Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
- Fdumpreg= 0x0e, /* dump internal registers */
-
- /* digital input register */
- Pdir= 0x3F7, /* disk changed port (read only) */
- Pdsr= 0x3F7, /* data rate select port (write only) */
- Fchange= 0x80, /* disk has changed */
-
- /* status 0 byte */
- Drivemask= 3<<0,
- Seekend= 1<<5,
- Codemask= (3<<6)|(3<<3),
- Cmdexec= 1<<6,
-
- /* status 1 byte */
- Overrun= 0x10,
-};
-
-
-static void
-pcfloppyintr(Ureg *ur, void *a)
-{
- USED(a);
-
- floppyintr(ur);
-}
-
-void
-floppysetup0(FController *fl)
-{
- fl->ndrive = 0;
- if(ioalloc(Psra, 6, 0, "floppy") < 0)
- return;
- if(ioalloc(Pdir, 1, 0, "floppy") < 0){
- iofree(Psra);
- return;
- }
- fl->ndrive = 2;
-}
-
-void
-floppysetup1(FController *fl)
-{
- uchar equip;
-
- /*
- * read nvram for types of floppies 0 & 1
- */
- equip = nvramread(0x10);
- if(fl->ndrive > 0){
- fl->d[0].dt = (equip >> 4) & 0xf;
- floppysetdef(&fl->d[0]);
- }
- if(fl->ndrive > 1){
- fl->d[1].dt = equip & 0xf;
- floppysetdef(&fl->d[1]);
- }
- intrenable(IrqFLOPPY, pcfloppyintr, fl, BUSUNKNOWN, "floppy");
-}
-
-/*
- * eject disk ( unknown on safari )
- */
-void
-floppyeject(FDrive *dp)
-{
- floppyon(dp);
- dp->vers++;
- floppyoff(dp);
-}
-
-int
-floppyexec(char *a, long b, int c)
-{
- USED(a, b, c);
- return b;
-}
diff --git a/os/pc/fns.h b/os/pc/fns.h
deleted file mode 100644
index aa326111..00000000
--- a/os/pc/fns.h
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "../port/portfns.h"
-void aamloop(int);
-Dirtab* addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
-void archinit(void);
-void bootargs(ulong);
-int cistrcmp(char*, char*);
-int cistrncmp(char*, char*, int);
-#define clearmmucache() /* x86 doesn't have one */
-void clockintr(Ureg*, void*);
-void (*coherence)(void);
-void cpuid(char*, int*, int*);
-int cpuidentify(void);
-void cpuidprint(void);
-void (*cycles)(uvlong*);
-void delay(int);
-int dmacount(int);
-int dmadone(int);
-void dmaend(int);
-int dmainit(int, int);
-long dmasetup(int, void*, long, int);
-void dumpregs(Ureg*);
-#define evenaddr(x) /* x86 doesn't care */
-void fpinit(void);
-void fpoff(void);
-void fprestore(FPU*);
-void fpsave(FPU*);
-ulong fpstatus(void);
-ulong getcr0(void);
-ulong getcr2(void);
-ulong getcr3(void);
-ulong getcr4(void);
-char* getconf(char*);
-void guesscpuhz(int);
-int i8042auxcmd(int);
-int i8042auxcmdval(int);
-void i8042auxenable(void (*)(int, int));
-int i8042auxdetect(void);
-void i8042reset(void);
-void i8250console(void);
-void i8253enable(void);
-void i8253init(void);
-void i8253link(void);
-uvlong i8253read(uvlong*);
-void i8253timerset(uvlong);
-void i8259init(void);
-int i8259isr(int);
-int i8259enable(Vctl*);
-int i8259vecno(int);
-int i8259disable(int);
-void idle(void);
-void idlehands(void);
-int inb(int);
-void insb(int, void*, int);
-ushort ins(int);
-void inss(int, void*, int);
-ulong inl(int);
-void insl(int, void*, int);
-int intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
-void intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
-void iofree(int);
-void ioinit(void);
-int iounused(int, int);
-int ioalloc(int, int, int, char*);
-int ioreserve(int, int, int, char*);
-int iprint(char*, ...);
-int isaconfig(char*, int, ISAConf*);
-int isvalid_va(void*);
-void kbdenable(void);
-void kbdinit(void);
-void kdbenable(void);
-#define kmapinval()
-void lapicclock(Ureg*, void*);
-void lapictimerset(uvlong);
-void lgdt(ushort[3]);
-void lidt(ushort[3]);
-void links(void);
-void ltr(ulong);
-void mach0init(void);
-void machinit(void);
-void mathinit(void);
-void mb386(void);
-void mb586(void);
-void meminit(ulong);
-#define mmuflushtlb(pdb) putcr3(pdb)
-void mmuinit(void);
-ulong mmukmap(ulong, ulong, int);
-int mmukmapsync(ulong);
-ulong* mmuwalk(ulong*, ulong, int, int);
-uchar nvramread(int);
-void nvramwrite(int, uchar);
-void outb(int, int);
-void outsb(int, void*, int);
-void outs(int, ushort);
-void outss(int, void*, int);
-void outl(int, ulong);
-void outsl(int, void*, int);
-int pciscan(int, Pcidev**);
-ulong pcibarsize(Pcidev*, int);
-int pcicfgr8(Pcidev*, int);
-int pcicfgr16(Pcidev*, int);
-int pcicfgr32(Pcidev*, int);
-void pcicfgw8(Pcidev*, int, int);
-void pcicfgw16(Pcidev*, int, int);
-void pcicfgw32(Pcidev*, int, int);
-void pciclrbme(Pcidev*);
-void pciclrioe(Pcidev*);
-void pciclrmwi(Pcidev*);
-int pcigetpms(Pcidev*);
-void pcihinv(Pcidev*);
-uchar pciipin(Pcidev*, uchar);
-Pcidev* pcimatch(Pcidev*, int, int);
-Pcidev* pcimatchtbdf(int);
-void pcireset(void);
-void pcisetbme(Pcidev*);
-void pcisetioe(Pcidev*);
-int pcisetpms(Pcidev*, int);
-void pcmcisread(PCMslot*);
-int pcmcistuple(int, int, int, void*, int);
-PCMmap* pcmmap(int, ulong, int, int);
-int pcmspecial(char*, ISAConf*);
-int (*_pcmspecial)(char *, ISAConf *);
-void pcmspecialclose(int);
-void (*_pcmspecialclose)(int);
-void pcmunmap(int, PCMmap*);
-void poolinit(void);
-void poolsizeinit(void);
-void procsave(Proc*);
-void procsetup(Proc*);
-void putcr3(ulong);
-void putcr4(ulong);
-void rdmsr(int, vlong*);
-ulong rdtsc32(void);
-void screeninit(void);
-int screenprint(char*, ...); /* debugging */
-void (*screenputs)(char*, int);
-int segflush(void*, ulong);
-void syncclock(void);
-uvlong tscticks(uvlong*);
-void trapenable(int, void (*)(Ureg*, void*), void*, char*);
-void trapinit(void);
-ulong umbmalloc(ulong, int, int);
-void umbfree(ulong, int);
-ulong umbrwmalloc(ulong, int, int);
-void umbrwfree(ulong, int);
-ulong upamalloc(ulong, int, int);
-void upafree(ulong, int);
-void upareserve(ulong, int);
-void vectortable(void);
-void* vmap(ulong, int);
-void vunmap(void*, int);
-void wrmsr(ulong, ulong);
-int xchgw(ushort*, int);
-ulong kzeromap(ulong, ulong, int);
-void nmiscreen(void);
-int kbdinready(void);
-
-#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
-#define getcallerpc(x) (((ulong*)(x))[-1])
-#define KADDR(a) ((void*)((ulong)(a)|KZERO))
-#define PADDR(a) ((ulong)(a)&~KZERO)
-
-#define dcflush(a, b)
-#define clockcheck();
-#define dumplongs(x, y, z)
-#define setpanic()
diff --git a/os/pc/fpi.h b/os/pc/fpi.h
deleted file mode 100644
index 7a368d18..00000000
--- a/os/pc/fpi.h
+++ /dev/null
@@ -1,61 +0,0 @@
-typedef int Word;
-typedef unsigned long Single;
-typedef struct {
- unsigned long l;
- unsigned long h;
-} Double;
-
-enum {
- FractBits = 28,
- CarryBit = 0x10000000,
- HiddenBit = 0x08000000,
- MsBit = HiddenBit,
- NGuardBits = 3,
- GuardMask = 0x07,
- LsBit = (1<<NGuardBits),
-
- SingleExpBias = 127,
- SingleExpMax = 255,
- DoubleExpBias = 1023,
- DoubleExpMax = 2047,
-
- ExpBias = DoubleExpBias,
- ExpInfinity = DoubleExpMax,
-};
-
-typedef struct {
- unsigned char s;
- short e;
- long l; /* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
- long h; /* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
-} Internal;
-
-#define IsWeird(n) ((n)->e >= ExpInfinity)
-#define IsInfinity(n) (IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0)
-#define SetInfinity(n) ((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0)
-#define IsNaN(n) (IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l))
-#define SetQNaN(n) ((n)->s = 0, (n)->e = ExpInfinity, \
- (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
-#define IsZero(n) ((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
-#define SetZero(n) ((n)->e = 1, (n)->h = 0, (n)->l = 0)
-
-/*
- * fpi.c
- */
-extern void fpiround(Internal *);
-extern void fpiadd(Internal *, Internal *, Internal *);
-extern void fpisub(Internal *, Internal *, Internal *);
-extern void fpimul(Internal *, Internal *, Internal *);
-extern void fpidiv(Internal *, Internal *, Internal *);
-extern int fpicmp(Internal *, Internal *);
-extern void fpinormalise(Internal*);
-
-/*
- * fpimem.c
- */
-extern void fpis2i(Internal *, void *);
-extern void fpid2i(Internal *, void *);
-extern void fpiw2i(Internal *, void *);
-extern void fpii2s(void *, Internal *);
-extern void fpii2d(void *, Internal *);
-extern void fpii2w(Word *, Internal *);
diff --git a/os/pc/fpi387.c b/os/pc/fpi387.c
deleted file mode 100644
index 76677549..00000000
--- a/os/pc/fpi387.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * Copyright © 1999 Vita Nuova Limited
- *
- * this doesn't attempt to implement 387 floating-point properties
- * that aren't visible in the Inferno environment. in particular,
- * all arithmetic is done in double precision, not extended precision.
- * furthermore, the FP trap status isn't updated.
- */
-
-#ifdef TEST
-#include <u.h>
-#include <libc.h>
-#include <ureg.h>
-#include "fpi.h"
-#include "tst.h"
-#else
-#include <u.h>
-#include "ureg.h"
-#include "fpi.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#endif
-
-#define fabs Fabs
-
-typedef struct FPI FPI;
-
-struct FPI {
- char* name;
- void (*f)(Ureg*, int, void*, Internal*, Internal*);
- int dstf;
-};
-
-enum {
- RndNearest = 0,
- RndDown,
- RndUp,
- Rnd0,
-
- C0 = 1<<8,
- C1 = 1<<9,
- C2 = 1<<10,
- C3 = 1<<14,
-};
-
-
-int fpemudebug = 0;
-
-static Internal fpconst[7] = { /* indexed by op&7 */
- /* s, e, l, h */
- {0, 0x3FF, 0x00000000, 0x08000000}, /* 1 */
- {0, 0x400, 0x0BCD1B8A, 0x0D49A784}, /* l2t */
- {0, 0x3FF, 0x095C17F0, 0x0B8AA3B2}, /* l2e */
- {0, 0x400, 0x022168C2, 0x0C90FDAA}, /* pi */
- {0, 0x3FD, 0x04FBCFF7, 0x09A209A8}, /* lg2 */
- {0, 0x3FE, 0x07D1CF79, 0x0B17217F}, /* ln2 */
- {0, 0x1, 0x00000000, 0x00000000}, /* z */
-};
-
-static Internal *fpstk(int i);
-#define ST(x) (*fpstk((x)))
-
-#define I387 (up->env->fpu)
-
-/* BUG: check fetch (not worthwhile in Inferno) */
-#define getubyte(a) (*(uchar*)(a))
-#define getuword(a) (*(ushort*)(a))
-#define getulong(a) (*(ulong*)(a))
-
-static void
-popfp(void)
-{
- ushort *s;
-
- s = &I387.status;
- *s = (*s & ~0x3800) | ((*s + 0x0800) & 0x3800);
-}
-
-static void
-pushfp(void)
-{
- ushort *s;
-
- s = &I387.status;
- *s = (*s & ~0x3800) | ((*s + 0x3800) & 0x3800);
-}
-
-static Internal *
-fpstk(int i)
-{
- return (Internal*)I387.istack[(i+(I387.status>>11))&7];
-}
-
-static void
-fldc(Ureg*, int op, void*, Internal*, Internal *d)
-{
- *d = fpconst[op&7];
-}
-
-static void
-fabs(Ureg*, int, void*, Internal*, Internal *d)
-{
- d->s = 0;
-}
-
-static void
-fchs(Ureg*, int, void*, Internal*, Internal *d)
-{
- d->s ^= 1;
-}
-
-static void
-fadd(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Internal l, r;
-
- l = *s;
- r = *d;
- (l.s == r.s? fpiadd: fpisub)(&l, &r, d);
-}
-
-static void
-fsub(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Internal l, r;
-
- l = *s;
- r = *d;
- l.s ^= 1;
- (l.s == r.s? fpiadd: fpisub)(&l, &r, d);
-}
-
-static void
-fsubr(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Internal l, r;
-
- l = *s;
- r = *d;
- r.s ^= 1;
- (l.s == r.s? fpiadd: fpisub)(&r, &l, d);
-}
-
-static void
-fmul(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Internal l, r;
-
- l = *s;
- r = *d;
- fpimul(&l, &r, d);
-}
-
-static void
-fdiv(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Internal l, r;
-
- l = *s;
- r = *d;
- fpidiv(&l, &r, d);
-}
-
-static void
-fdivr(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Internal l, r;
-
- l = *s;
- r = *d;
- fpidiv(&r, &l, d);
-}
-
-static void
-fcom(Ureg*, int, void*, Internal *s, Internal *d)
-{
- int i;
- ushort *p;
-
- p = &I387.status;
- if(IsWeird(s) || IsWeird(d)){
- *p |= C0|C2|C3;
- /* BUG: should trap if not masked */
- return;
- }
- *p &= ~(C0|C2|C3);
- i = fpicmp(d, s);
- if(i < 0)
- *p |= C0;
- else if(i == 0)
- *p |= C3;
-}
-
-static void
-fpush(Ureg*, int op, void*, Internal*, Internal*)
-{
- Internal *p;
-
- p = &ST(op & 7);
- pushfp();
- ST(0) = *p;
-}
-
-static void
-fmov(Ureg*, int, void*, Internal *s, Internal *d)
-{
- *d = *s;
-}
-
-static void
-fmovr(Ureg*, int, void*, Internal *s, Internal *d)
-{
- *s = *d;
-}
-
-static void
-fxch(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Internal t;
-
- t = *s; *s = *d; *d = t;
-}
-
-static void
-frstor(Ureg*, int, void *s, Internal*, Internal*)
-{
- validaddr(s, 108, 0);
- memmove(&I387, s, 108);
-}
-
-static void
-fsave(Ureg*, int, void *d, Internal*, Internal*)
-{
- validaddr(d, 108, 1);
- memmove(d, &I387, 108);
- I387.control = 0x037F;
- I387.status = 0;
- I387.tag = 0;
-}
-
-static void
-fstsw(Ureg*, int, void *d, Internal*, Internal*)
-{
- validaddr(d, 2, 1);
- *(short*)d = I387.status;
-}
-
-static void
-fldenv(Ureg*, int, void *s, Internal*, Internal*)
-{
- validaddr(s, 28, 0);
- memmove(&I387, s, 28);
-}
-
-static void
-fldcw(Ureg*, int, void *s, Internal*, Internal*)
-{
- validaddr(s, 2, 0);
- I387.control = *(short*)s;
-}
-
-static void
-fstenv(Ureg*, int, void *d, Internal*, Internal*)
-{
- validaddr(d, 4*7, 1);
- memmove(d, &I387, 4*7);
-}
-
-static void
-fstcw(Ureg*, int, void *d, Internal*, Internal*)
-{
- validaddr(d, 2, 1);
- *(short*)d = I387.control;
-}
-
-static void
-fincstp(Ureg*, int, void*, Internal*, Internal*)
-{
- popfp();
-}
-
-static void
-fdecstp(Ureg*, int, void*, Internal*, Internal*)
-{
- pushfp();
-}
-
-static void
-fscale(Ureg*, int, void*, Internal *s, Internal *d)
-{
- Word w;
-
- fpii2w(&w, s); /* should truncate towards zero ... */
- d->e += w;
-}
-
-static void
-fstswax(Ureg *ur, int, void*, Internal*, Internal*)
-{
- ur->ax = (ur->ax & ~0xFFFF) | (I387.status & 0xFFFF);
-}
-
-static void
-ftst(Ureg*, int, void*, Internal*, Internal *d)
-{
- ushort *p;
-
- p = &I387.status;
- if(IsWeird(d)){
- *p |= C0|C2|C3;
- return;
- }
- *p &= ~(C0|C2|C3);
- fpinormalise(d);
- if(IsZero(d))
- *p |= C3;
- else if(d->s)
- *p |=C0;
-}
-
-static void
-frndint(Ureg*, int, void*, Internal*, Internal *d)
-{
- fpiround(d); /* BUG: doesn't look at rounding mode */
-}
-
-static void
-fnop(Ureg*, int, void*, Internal*, Internal*)
-{
-}
-
-enum {
- Fpop1= 1<<0,
- Fpop2 = 1<<1,
- Fload = 1<<2,
-};
-
-/*
- * %e - effective address - Mod R/M value
- * %f - floating point register F0-F7 - from Mod R/M register
- */
-
-static void fload(Ureg*, int, void*, Internal*, Internal*);
-static void fstore(Ureg*, int, void*, Internal*, Internal*);
-
-#define X(a,b) (((a)<<2)|(b))
-
-static FPI optab1[4][4] = { /* normal mod r/m operand */
-[0] {
- [0] {"FLDENV %e", fldenv, 0},
- [1] {"FLDCW %e", fldcw, 0},
- [2] {"FSTENV %e", fstenv, 0},
- [3] {"FSTCW %e", fstcw, 0},
- },
-[1] {
- [1] {"FMOVX %e,F0", nil, Fload},
- [3] {"FMOVXP F0,%e", nil, Fpop1},
- },
-[2] {
- [0] {"FRSTOR %e", frstor, 0},
- [2] {"FSAVE %e", fsave, 0},
- [3] {"FSTSW %e", fstsw, 0},
- },
-[3] {
- [0] {"FMOVB %e", nil, 0},
- [1] {"FMOVV %e,F0", nil, Fload},
- [2] {"FMOVBP %e", nil, Fpop1},
- [3] {"FMOVVP F0,%e", nil, Fpop1},
- },
-};
-
-#undef X
-
-static FPI optab2a[1<<3] = { /* A=0 */
-[0] {"FADDx %e,F0", fadd, 0},
-[1] {"FMULx %e,F0", fmul, 0},
-[2] {"FCOMx %e,F0", fcom, 0},
-[3] {"FCOMxP %e,F0", fcom, Fpop1},
-[4] {"FSUBx %e,F0", fsub, 0},
-[5] {"FSUBRx %e,F0", fsubr, 0}, /* ?? */
-[6] {"FDIVx %e,F0", fdiv, 0},
-[7] {"FDIVRx %e,F0", fdivr, 0}, /* ?? */
-};
-
-static FPI optab2b[1<<2] = { /* A=1, B=0,2,3 */
-[0] {"FMOVx %e,F0", fload, Fload},
-[2] {"FMOVx F0,%e", fstore, 0},
-[3] {"FMOVxP F0,%e", fstore, Fpop1},
-};
-
-#define X(d,P,B) ((d<<4)|(P<<3)|B)
-
-static FPI optab3a[1<<5] = { /* A=0 */
-[X(0,0,0)] {"FADDD %f,F0", fadd, 0},
-[X(1,0,0)] {"FADDD F0,%f", fadd, 0},
-[X(1,1,0)] {"FADDDP F0,%f", fadd, Fpop1},
-[X(0,0,1)] {"FMULD %f,F0", fmul, 0},
-[X(1,0,1)] {"FMULD F0,%f", fmul, 0},
-[X(1,1,1)] {"FMULDP F0,%f", fmul, Fpop1},
-[X(0,0,2)] {"FCOMD %f,F0", fcom, 0},
-[X(0,0,3)] {"FCOMDP %f,F0", fcom, Fpop1},
-[X(1,1,3)] {"FCOMDPP", fcom, Fpop1|Fpop2},
-[X(0,0,4)] {"FSUBD %f,F0", fsub, 0},
-[X(1,0,4)] {"FSUBRD F0,%f", fsubr, 0},
-[X(1,1,4)] {"FSUBRDP F0,%f", fsubr, Fpop1},
-[X(0,0,5)] {"FSUBRD %f,F0", fsubr, 0},
-[X(1,0,5)] {"FSUBD F0,%f", fsub, 0},
-[X(1,1,5)] {"FSUBDP F0,%f", fsub, Fpop1},
-[X(0,1,5)] {"FUCOMPP", fcom, Fpop1|Fpop2},
-[X(0,0,6)] {"FDIVD %f,F0", fdiv, 0},
-[X(1,0,6)] {"FDIVRD F0,%f", fdivr, 0},
-[X(1,1,6)] {"FDIVRDP F0,%f", fdivr, Fpop1},
-[X(0,0,7)] {"FDIVRD %f,F0", fdivr, 0},
-[X(1,0,7)] {"FDIVD F0,%f", fdiv, 0},
-[X(1,1,7)] {"FDIVDP F0,%f", fdiv, Fpop1},
-};
-
-static FPI optab3b[1<<5] = { /* A=1 */
-[X(0,0,0)] {"FMOVD %f,F0", fmov, Fload},
-[X(0,0,1)] {"FXCHD %f,F0", fxch, 0},
-[X(0,0,2)] {"FNOP", fnop, 0}, /* F0 only */
-[X(1,0,0)] {"FFREED %f", fnop, 0},
-[X(1,0,2)] {"FMOVD F0,%f", fmovr, 0},
-[X(1,0,3)] {"FMOVDP F0,%f", fmovr, Fpop1},
-[X(1,1,4)] {"FSTSW AX", fstswax, 0},
-[X(1,0,4)] {"FUCOMD %f,F0", fcom, 0},
-[X(1,0,5)] {"FUCOMDP %f,F0", fcom, Fpop1},
-};
-
-#undef X
-
-static FPI optab4[1<<6] = {
-[0x00] {"FCHS", fchs, 0},
-[0x01] {"FABS", fabs, 0},
-[0x04] {"FTST", ftst, 0},
-[0x05] {"FXAM", nil, 0},
-[0x08] {"FLD1", fldc, Fload},
-[0x09] {"FLDL2T", fldc, Fload},
-[0x0a] {"FLDL2E", fldc, Fload},
-[0x0b] {"FLDPI", fldc, Fload},
-[0x0c] {"FLDLG2", fldc, Fload},
-[0x0d] {"FLDLN2", fldc, Fload},
-[0x0e] {"FLDZ", fldc, Fload},
-[0x10] {"F2XM1", nil, 0},
-[0x11] {"FYL2X", nil, 0},
-[0x12] {"FPTAN", nil, 0},
-[0x13] {"FPATAN", nil, 0},
-[0x14] {"FXTRACT", nil, 0},
-[0x15] {"FPREM1", nil, 0},
-[0x16] {"FDECSTP", fdecstp, 0},
-[0x17] {"FINCSTP", fincstp, 0},
-[0x18] {"FPREM", nil, 0},
-[0x19] {"FYL2XP1", nil, 0},
-[0x1a] {"FSQRT", nil, 0},
-[0x1b] {"FSINCOS", nil, 0},
-[0x1c] {"FRNDINT", frndint, 0},
-[0x1d] {"FSCALE", fscale, 0},
-[0x1e] {"FSIN", nil, 0},
-[0x1f] {"FCOS", nil, 0},
-};
-
-static void
-loadr32(void *s, Internal *d)
-{
- validaddr(s, 4, 0);
- fpis2i(d, s);
-}
-
-static void
-loadi32(void *s, Internal *d)
-{
- validaddr(s, 4, 0);
- fpiw2i(d, s);
-}
-
-static void
-loadr64(void *s, Internal *d)
-{
- validaddr(s, 8, 0);
- fpid2i(d, s);
-}
-
-static void
-loadi16(void *s, Internal *d)
-{
- Word w;
-
- validaddr(s, 2, 0);
- w = *(short*)s;
- fpiw2i(d, &w);
-}
-
-static void (*loadf[4])(void*, Internal*) ={
- loadr32, loadi32, loadr64, loadi16
-};
-
-static void
-storer32(Internal s, void *d)
-{
- validaddr(d, 4, 1);
- fpii2s(d, &s);
-}
-
-static void
-storei32(Internal s, void *d)
-{
- validaddr(d, 4, 1);
- fpii2w(d, &s);
-}
-
-static void
-storer64(Internal s, void *d)
-{
- validaddr(d, 8, 1);
- fpii2d(d, &s);
-}
-
-static void
-storei16(Internal s, void *d)
-{
- Word w;
-
- validaddr(d, 2, 1);
- fpii2w(&w, &s);
- if((short)w != w)
- ; /* overflow */
- *(short*)d = w;
-}
-
-static void (*storef[4])(Internal, void*) ={
- storer32, storei32, storer64, storei16
-};
-
-static void
-fload(Ureg*, int op, void *mem, Internal*, Internal *d)
-{
- (*loadf[(op>>9)&3])(mem, d);
-}
-
-static void
-fstore(Ureg*, int op, void *mem, Internal *s, Internal*)
-{
- (*storef[(op>>9)&3])(*s, mem);
-}
-
-#define REG(x) (*(ulong*)(((char*)ur)+roff[(x)]))
-
-static int roff[] = {
- offsetof(Ureg, ax),
- offsetof(Ureg, cx),
- offsetof(Ureg, dx),
- offsetof(Ureg, bx),
- offsetof(Ureg, ecode), /* ksp */
- offsetof(Ureg, bp),
- offsetof(Ureg, si),
- offsetof(Ureg, di),
-};
-
-static long
-getdisp(Ureg *ur, int mod, int rm)
-{
- uchar c;
- long disp;
-
- if(mod > 2)
- return 0;
- disp = 0;
- if(mod == 1) {
- c = getubyte(ur->pc++);
- if(c&0x80)
- disp = c|(~0<<8);
- else
- disp = c;
- } else if(mod == 2 || rm == 5) {
- disp = getulong(ur->pc);
- ur->pc += 4;
- }
- if(mod || rm != 5)
- disp += REG(rm); /* base */
- return disp;
-}
-
-static ulong
-modrm(Ureg *ur, uchar c)
-{
- uchar rm, mod;
- int reg;
- ulong base;
-
- mod = (c>>6)&3;
- rm = c&7;
- if(mod == 3) /* register */
- error("sys: fpemu: invalid addr mode");
- /* no 16-bit mode */
- if(rm == 4) { /* scummy sib byte */
- c = getubyte(ur->pc++);
- reg = (c>>3)&0x07; /* index */
- base = getdisp(ur, mod, c&7);
- if(reg != 4)
- base += (REG(reg) << (c>>6)); /* index */
- if(fpemudebug>1)
- print("ur=#%lux sib=#%x reg=%d mod=%d base=%d basev=#%lux sp=%lux\n", ur, c, reg, mod, c&7, base, ur->usp);
- return base;
- }
- if(rm == 5 && mod == 0){
- ur->pc += 4;
- return getulong(ur->pc-4);
- }
- return getdisp(ur, mod, rm);
-}
-
-static void *
-ea(Ureg *ur, uchar op)
-{
- ulong addr;
-
- addr = modrm(ur, op);
- I387.operand = addr;
- if(fpemudebug>1)
- print("EA=#%lux\n", addr);
- return (void*)addr;
-}
-
-void
-fpi387(Ureg *ur)
-{
- int op, i;
- ulong pc;
- FPenv *ufp;
- FPI *fp;
- Internal tmp, *s, *d;
- void *mem;
- char buf[60];
-
- ur->ecode = (ulong)&ur->sp; /* BUG: TEMPORARY compensation for incorrect Ureg for kernel mode */
- ufp = &up->env->fpu; /* because all the state is in Osenv, it need not be saved/restored */
- if(ufp->fpistate != FPACTIVE) {
- ufp->fpistate = FPACTIVE;
- ufp->control = 0x037f;
- ufp->status = 0;
- ufp->tag = 0;
- ufp->oselector = 0x17;
- }
- while((op = getubyte(ur->pc)) >= 0xd8 && op <= 0xdf || op == 0x9B){
- if(op == 0x9B){ /* WAIT */
- ur->pc++;
- continue;
- }
- if(ufp->control & ufp->status & 0x3F)
- ufp->status |= 0x8000;
- else
- ufp->status &= 0x7FFF;
- pc = ur->pc;
- op = (op<<8) | getubyte(pc+1);
- ufp->selector = ur->cs;
- ufp->r4 = op-0xD800;
- ur->pc += 2;
- mem = nil;
- s = nil;
- d = nil;
- /* decode op, following table 10.2.4 in i486 handbook */
- i = op & 0xFFE0;
- if(i == 0xD9E0){
- fp = &optab4[op&0x1F];
- s = &ST(0);
- if(fp->dstf & Fload)
- pushfp();
- d = &ST(0);
- } else if(i == 0xDBE0){
- i = op & 0x1F;
- if(i == 2){ /* FCLEX */
- ufp->status &= 0x7f00;
- continue;
- } else if(i == 3){ /* FINIT */
- ufp->control = 0x037f;
- ufp->status = 0;
- ufp->tag = 0;
- continue;
- }
- fp = nil;
- } else if((op & 0xF8C0) == 0xD8C0){
- i = ((op>>6)&030)|((op>>3)&7);
- if(op & (1<<8)){
- fp = &optab3b[i];
- s = &ST(op&7);
- if(fp->dstf & Fload)
- pushfp();
- d = &ST(0);
- } else {
- fp = &optab3a[i];
- i = op & 7;
- if(op & (1<<10)){
- s = &ST(0);
- d = &ST(i);
- }else{
- s = &ST(i);
- d = &ST(0);
- }
- }
- } else if((op & 0xF920) == 0xD920){
- mem = ea(ur, op&0xFF);
- fp = &optab1[(op>>9)&3][(op>>3)&3];
- } else {
- mem = ea(ur, op&0xFF);
- if(op & (1<<8)){
- /* load/store */
- fp = &optab2b[(op>>3)&7];
- if(fp->dstf & Fload){
- pushfp();
- d = &ST(0);
- } else
- s = &ST(0);
- } else {
- /* mem OP reg */
- fp = &optab2a[(op>>3)&7];
- (*loadf[(op>>9)&3])(mem, &tmp);
- s = &tmp;
- d = &ST(0);
- }
- }
- if(fp == nil || fp->f == nil){
- if(fp == nil || fp->name == nil)
- snprint(buf, sizeof(buf), "sys: fp: pc=%lux invalid fp 0x%.4x", pc, op);
- else
- snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.4x (%s)", pc, op, fp->name);
- error(buf);
- }
- if(fpemudebug)
- print("%8.8lux %.4x %s\n", pc, op, fp->name);
- (*fp->f)(ur, op, mem, s, d);
- if(fp->dstf & Fpop1){
- popfp();
- if(fp->dstf & Fpop2)
- popfp();
- }
- if(anyhigher())
- sched();
- }
-}
diff --git a/os/pc/fpsave.s b/os/pc/fpsave.s
deleted file mode 100644
index 8bf9448e..00000000
--- a/os/pc/fpsave.s
+++ /dev/null
@@ -1,9 +0,0 @@
-TEXT FPsave(SB), 1, $0 /* save FPU environment without waiting */
- MOVL fpu+0(FP), AX
- FSTENV 0(AX)
- RET
-
-TEXT FPrestore(SB), 1, $0 /* restore FPU environment without waiting */
- MOVL fpu+0(FP), AX
- FLDENV 0(AX)
- RET
diff --git a/os/pc/i8250.c b/os/pc/i8250.c
deleted file mode 100644
index c625013e..00000000
--- a/os/pc/i8250.c
+++ /dev/null
@@ -1,328 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-/*
- * INS8250 uart
- */
-enum
-{
- /*
- * register numbers
- */
- Data= 0, /* xmit/rcv buffer */
- Iena= 1, /* interrupt enable */
- Ircv= (1<<0), /* for char rcv'd */
- Ixmt= (1<<1), /* for xmit buffer empty */
- Irstat=(1<<2), /* for change in rcv'er status */
- Imstat=(1<<3), /* for change in modem status */
- Istat= 2, /* interrupt flag (read) */
- Fenabd=(3<<6), /* on if fifo's enabled */
- Fifoctl=2, /* fifo control (write) */
- Fena= (1<<0), /* enable xmit/rcv fifos */
- Ftrig= (1<<6), /* trigger after 4 input characters */
- Fclear=(3<<1), /* clear xmit & rcv fifos */
- Format= 3, /* byte format */
- Bits8= (3<<0), /* 8 bits/byte */
- Stop2= (1<<2), /* 2 stop bits */
- Pena= (1<<3), /* generate parity */
- Peven= (1<<4), /* even parity */
- Pforce=(1<<5), /* force parity */
- Break= (1<<6), /* generate a break */
- Dra= (1<<7), /* address the divisor */
- Mctl= 4, /* modem control */
- Dtr= (1<<0), /* data terminal ready */
- Rts= (1<<1), /* request to send */
- Ri= (1<<2), /* ring */
- Inton= (1<<3), /* turn on interrupts */
- Loop= (1<<4), /* loop back */
- Lstat= 5, /* line status */
- Inready=(1<<0), /* receive buffer full */
- Oerror=(1<<1), /* receiver overrun */
- Perror=(1<<2), /* receiver parity error */
- Ferror=(1<<3), /* rcv framing error */
- Outready=(1<<5), /* output buffer empty */
- Mstat= 6, /* modem status */
- Ctsc= (1<<0), /* clear to send changed */
- Dsrc= (1<<1), /* data set ready changed */
- Rire= (1<<2), /* rising edge of ring indicator */
- Dcdc= (1<<3), /* data carrier detect changed */
- Cts= (1<<4), /* complement of clear to send line */
- Dsr= (1<<5), /* complement of data set ready line */
- Ring= (1<<6), /* complement of ring indicator line */
- Dcd= (1<<7), /* complement of data carrier detect line */
- Scratch=7, /* scratchpad */
- Dlsb= 0, /* divisor lsb */
- Dmsb= 1, /* divisor msb */
-
- Serial= 0,
- Modem= 1,
-};
-
-typedef struct Uart Uart;
-struct Uart
-{
- int port;
- uchar sticky[8]; /* sticky write register values */
- int nofifo;
-
- void (*rx)(int); /* routine to take a received character */
- int (*tx)(void); /* routine to get a character to transmit */
-
- ulong frame;
- ulong overrun;
-};
-
-static Uart i8250uart[1];
-
-#define UartFREQ 1843200
-
-#define i8250regw(u, r, v) outb((u)->port+(r), (u)->sticky[(r)]|(v))
-#define i8250regr(u, r) inb((u)->port+(r))
-
-/*
- * set the baud rate by calculating and setting the baudrate
- * generator constant. This will work with fairly non-standard
- * baud rates.
- */
-static void
-i8250setbaud(Uart* uart, int rate)
-{
- ulong brconst;
-
- brconst = (UartFREQ+8*rate-1)/(16*rate);
-
- i8250regw(uart, Format, Dra);
- outb(uart->port+Dmsb, (brconst>>8) & 0xff);
- outb(uart->port+Dlsb, brconst & 0xff);
- i8250regw(uart, Format, 0);
-}
-
-/*
- * toggle DTR
- */
-static void
-i8250dtr(Uart* uart, int n)
-{
- if(n)
- uart->sticky[Mctl] |= Dtr;
- else
- uart->sticky[Mctl] &= ~Dtr;
- i8250regw(uart, Mctl, 0);
-}
-
-/*
- * toggle RTS
- */
-static void
-i8250rts(Uart* uart, int n)
-{
- if(n)
- uart->sticky[Mctl] |= Rts;
- else
- uart->sticky[Mctl] &= ~Rts;
- i8250regw(uart, Mctl, 0);
-}
-
-/*
- * Enable/disable FIFOs (if possible).
- */
-static void
-i8250fifo(Uart* uart, int n)
-{
- int i, s;
-
- if(uart->nofifo)
- return;
-
- s = splhi();
-
- /* reset fifos */
- i8250regw(uart, Fifoctl, Fclear);
-
- /* empty buffer and interrupt conditions */
- for(i = 0; i < 16; i++){
- if(i8250regr(uart, Istat))
- {}
- if(i8250regr(uart, Data))
- {}
- }
-
- /* turn on fifo */
- if(n){
- i8250regw(uart, Fifoctl, Fena|Ftrig);
-
- if((i8250regr(uart, Istat) & Fenabd) == 0){
- /* didn't work, must be an earlier chip type */
- uart->nofifo = 1;
- }
- }
-
- splx(s);
-}
-
-#ifdef notdef
-static void
-i8250intr(Ureg*, void* arg)
-{
- Uart *uart;
- int ch;
- int s, l, loops;
-
- uart = arg;
- for(loops = 0; loops < 1024; loops++){
- s = i8250regr(uart, Istat);
- switch(s & 0x3F){
- case 6: /* receiver line status */
- l = i8250regr(uart, Lstat);
- if(l & Ferror)
- uart->frame++;
- if(l & Oerror)
- uart->overrun++;
- break;
-
- case 4: /* received data available */
- case 12:
- ch = inb(uart->port+Data);
- if(uart->rx)
- (*uart->rx)(ch & 0x7F);
- break;
-
- case 2: /* transmitter empty */
- ch = -1;
- if(uart->tx)
- ch = (*uart->tx)();
- if(ch != -1)
- outb(uart->port+Data, ch);
- break;
-
- case 0: /* modem status */
- i8250regr(uart, Mstat);
- break;
-
- default:
- if(s&1)
- return;
- print("weird modem interrupt #%2.2ux\n", s);
- break;
- }
- }
- panic("i8250intr: 0x%2.2ux\n", i8250regr(uart, Istat));
-}
-#endif /* notdef */
-
-/*
- * turn on a port's interrupts. set DTR and RTS
- */
-static void
-i8250enable(Uart* uart)
-{
- /*
- * turn on interrupts
- */
- uart->sticky[Iena] = 0;
-#ifdef notdef
- if(uart->tx)
- uart->sticky[Iena] |= Ixmt;
- if(uart->rx)
- uart->sticky[Iena] |= Ircv|Irstat;
-#endif /* notdef */
-
- /*
- * turn on DTR and RTS
- */
- i8250dtr(uart, 1);
- i8250rts(uart, 1);
- i8250fifo(uart, 1);
-
- i8250regw(uart, Iena, 0);
-}
-
-void
-i8250special(int port, void (*rx)(int), int (*tx)(void), int baud)
-{
- Uart *uart = &i8250uart[0];
-
- if(uart->port)
- return;
-
- switch(port){
-
- case 0:
- uart->port = 0x3F8;
-#ifdef notdef
- intrenable(VectorUART0, i8250intr, uart, BUSUNKNOWN);
-#endif /* notdef */
- break;
-
- case 1:
- uart->port = 0x2F8;
-#ifdef notdef
- intrenable(VectorUART1, i8250intr, uart, BUSUNKNOWN);
-#endif /* notdef */
- break;
-
- default:
- return;
- }
-
- /*
- * set rate to 9600 baud.
- * 8 bits/character.
- * 1 stop bit.
- * interrupts enabled.
- */
- i8250setbaud(uart, 9600);
- uart->sticky[Format] = Bits8;
- i8250regw(uart, Format, 0);
- uart->sticky[Mctl] |= Inton;
- i8250regw(uart, Mctl, 0x0);
-
- uart->rx = rx;
- uart->tx = tx;
- i8250enable(uart);
- if(baud)
- i8250setbaud(uart, baud);
-}
-
-int
-i8250getc(void)
-{
- Uart *uart = &i8250uart[0];
-
- if(i8250regr(uart, Lstat) & Inready)
- return inb(uart->port+Data);
- return 0;
-}
-
-void
-i8250putc(int c)
-{
- Uart *uart = &i8250uart[0];
- int i;
-
- for(i = 0; i < 100; i++){
- if(i8250regr(uart, Lstat) & Outready)
- break;
- delay(1);
- }
- outb(uart->port+Data, c);
-}
-
-void
-i8250puts(char* s, int n)
-{
- int x;
-
- x = splhi();
- while(n--){
- if(*s == '\n')
- i8250putc('\r');
- i8250putc(*s++);
- }
- splx(x);
-}
diff --git a/os/pc/i8253.c b/os/pc/i8253.c
deleted file mode 100644
index 0759088f..00000000
--- a/os/pc/i8253.c
+++ /dev/null
@@ -1,314 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-/*
- * 8253 timer
- */
-enum
-{
- T0cntr= 0x40, /* counter ports */
- T1cntr= 0x41, /* ... */
- T2cntr= 0x42, /* ... */
- Tmode= 0x43, /* mode port (control word register) */
- T2ctl= 0x61, /* counter 2 control port */
-
- /* commands */
- Latch0= 0x00, /* latch counter 0's value */
- Load0l= 0x10, /* load counter 0's lsb */
- Load0m= 0x20, /* load counter 0's msb */
- Load0= 0x30, /* load counter 0 with 2 bytes */
-
- Latch1= 0x40, /* latch counter 1's value */
- Load1l= 0x50, /* load counter 1's lsb */
- Load1m= 0x60, /* load counter 1's msb */
- Load1= 0x70, /* load counter 1 with 2 bytes */
-
- Latch2= 0x80, /* latch counter 2's value */
- Load2l= 0x90, /* load counter 2's lsb */
- Load2m= 0xa0, /* load counter 2's msb */
- Load2= 0xb0, /* load counter 2 with 2 bytes */
-
- /* 8254 read-back command: everything > pc-at has an 8254 */
- Rdback= 0xc0, /* readback counters & status */
- Rdnstat=0x10, /* don't read status */
- Rdncnt= 0x20, /* don't read counter value */
- Rd0cntr=0x02, /* read back for which counter */
- Rd1cntr=0x04,
- Rd2cntr=0x08,
-
- /* modes */
- ModeMsk=0xe,
- Square= 0x6, /* periodic square wave */
- Trigger=0x0, /* interrupt on terminal count */
- Sstrobe=0x8, /* software triggered strobe */
-
- /* T2ctl bits */
- T2gate= (1<<0), /* enable T2 counting */
- T2spkr= (1<<1), /* connect T2 out to speaker */
- T2out= (1<<5), /* output of T2 */
-
- Freq= 1193182, /* Real clock frequency */
- Tickshift=8, /* extra accuracy */
- MaxPeriod=Freq/HZ,
- MinPeriod=Freq/(100*HZ),
-};
-
-typedef struct I8253 I8253;
-struct I8253
-{
- Lock;
- ulong period; /* current clock period */
- int enabled;
- uvlong hz;
-
- ushort last; /* last value of clock 1 */
- uvlong ticks; /* cumulative ticks of counter 1 */
-
- ulong periodset;
-};
-I8253 i8253;
-
-void
-i8253init(void)
-{
- int loops, x;
-
- ioalloc(T0cntr, 4, 0, "i8253");
- ioalloc(T2ctl, 1, 0, "i8253.cntr2ctl");
-
- i8253.period = Freq/HZ;
-
- /*
- * enable a 1/HZ interrupt for providing scheduling interrupts
- */
- outb(Tmode, Load0|Square);
- outb(T0cntr, (Freq/HZ)); /* low byte */
- outb(T0cntr, (Freq/HZ)>>8); /* high byte */
-
- /*
- * enable a longer period counter to use as a clock
- */
- outb(Tmode, Load2|Square);
- outb(T2cntr, 0); /* low byte */
- outb(T2cntr, 0); /* high byte */
- x = inb(T2ctl);
- x |= T2gate;
- outb(T2ctl, x);
-
- /*
- * Introduce a little delay to make sure the count is
- * latched and the timer is counting down; with a fast
- * enough processor this may not be the case.
- * The i8254 (which this probably is) has a read-back
- * command which can be used to make sure the counting
- * register has been written into the counting element.
- */
- x = (Freq/HZ);
- for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){
- outb(Tmode, Latch0);
- x = inb(T0cntr);
- x |= inb(T0cntr)<<8;
- }
-}
-
-void
-guesscpuhz(int aalcycles)
-{
- int loops, incr, x, y;
- uvlong a, b, cpufreq;
-
- /* find biggest loop that doesn't wrap */
- incr = 16000000/(aalcycles*HZ*2);
- x = 2000;
- for(loops = incr; loops < 64*1024; loops += incr) {
-
- /*
- * measure time for the loop
- *
- * MOVL loops,CX
- * aaml1: AAM
- * LOOP aaml1
- *
- * the time for the loop should be independent of external
- * cache and memory system since it fits in the execution
- * prefetch buffer.
- *
- */
- outb(Tmode, Latch0);
- cycles(&a);
- x = inb(T0cntr);
- x |= inb(T0cntr)<<8;
- aamloop(loops);
- outb(Tmode, Latch0);
- cycles(&b);
- y = inb(T0cntr);
- y |= inb(T0cntr)<<8;
- x -= y;
-
- if(x < 0)
- x += Freq/HZ;
-
- if(x > Freq/(3*HZ))
- break;
- }
-
- /*
- * figure out clock frequency and a loop multiplier for delay().
- * n.b. counter goes up by 2*Freq
- */
- cpufreq = (vlong)loops*((aalcycles*2*Freq)/x);
- m->loopconst = (cpufreq/1000)/aalcycles; /* AAM+LOOP's for 1 ms */
-
- if(m->havetsc){
- /* counter goes up by 2*Freq */
- b = (b-a)<<1;
- b *= Freq;
- b /= x;
-
- /*
- * round to the nearest megahz
- */
- m->cpumhz = (b+500000)/1000000L;
- m->cpuhz = b;
- m->cyclefreq = b;
- } else {
- /*
- * add in possible 0.5% error and convert to MHz
- */
- m->cpumhz = (cpufreq + cpufreq/200)/1000000;
- m->cpuhz = cpufreq;
- }
-
- i8253.hz = Freq<<Tickshift;
-}
-
-void
-i8253timerset(uvlong next)
-{
- long period;
- ulong want;
- ulong now;
-
- period = MaxPeriod;
- if(next != 0){
- want = next>>Tickshift;
- now = i8253.ticks; /* assuming whomever called us just did fastticks() */
-
- period = want - now;
- if(period < MinPeriod)
- period = MinPeriod;
- else if(period > MaxPeriod)
- period = MaxPeriod;
- }
-
- /* hysteresis */
- if(i8253.period != period){
- ilock(&i8253);
- /* load new value */
- outb(Tmode, Load0|Square);
- outb(T0cntr, period); /* low byte */
- outb(T0cntr, period >> 8); /* high byte */
-
- /* remember period */
- i8253.period = period;
- i8253.periodset++;
- iunlock(&i8253);
- }
-}
-
-static void
-i8253clock(Ureg* ureg, void*)
-{
- timerintr(ureg, 0);
-}
-
-void
-i8253enable(void)
-{
- i8253.enabled = 1;
- i8253.period = Freq/HZ;
- intrenable(IrqCLOCK, i8253clock, 0, BUSUNKNOWN, "clock");
-}
-
-void
-i8253link(void)
-{
-}
-
-/*
- * return the total ticks of counter 2. We shift by
- * 8 to give timesync more wriggle room for interpretation
- * of the frequency
- */
-uvlong
-i8253read(uvlong *hz)
-{
- ushort y, x;
- uvlong ticks;
-
- if(hz)
- *hz = i8253.hz;
-
- ilock(&i8253);
- outb(Tmode, Latch2);
- y = inb(T2cntr);
- y |= inb(T2cntr)<<8;
-
- if(y < i8253.last)
- x = i8253.last - y;
- else {
- x = i8253.last + (0x10000 - y);
- if (x > 3*MaxPeriod) {
- outb(Tmode, Load2|Square);
- outb(T2cntr, 0); /* low byte */
- outb(T2cntr, 0); /* high byte */
- y = 0xFFFF;
- x = i8253.period;
- }
- }
- i8253.last = y;
- i8253.ticks += x>>1;
- ticks = i8253.ticks;
- iunlock(&i8253);
-
- return ticks<<Tickshift;
-}
-
-void
-delay(int millisecs)
-{
- millisecs *= m->loopconst;
- if(millisecs <= 0)
- millisecs = 1;
- aamloop(millisecs);
-}
-
-void
-microdelay(int microsecs)
-{
- microsecs *= m->loopconst;
- microsecs /= 1000;
- if(microsecs <= 0)
- microsecs = 1;
- aamloop(microsecs);
-}
-
-/*
- * performance measurement ticks. must be low overhead.
- * doesn't have to count over a second.
- */
-ulong
-perfticks(void)
-{
- uvlong x;
-
- if(m->havetsc)
- cycles(&x);
- else
- x = 0;
- return x;
-}
diff --git a/os/pc/i8259.c b/os/pc/i8259.c
deleted file mode 100644
index 562196b9..00000000
--- a/os/pc/i8259.c
+++ /dev/null
@@ -1,199 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-/*
- * 8259 interrupt controllers
- */
-enum
-{
- Int0ctl= 0x20, /* control port (ICW1, OCW2, OCW3) */
- Int0aux= 0x21, /* everything else (ICW2, ICW3, ICW4, OCW1) */
- Int1ctl= 0xA0, /* control port */
- Int1aux= 0xA1, /* everything else (ICW2, ICW3, ICW4, OCW1) */
-
- Icw1= 0x10, /* select bit in ctl register */
- Ocw2= 0x00,
- Ocw3= 0x08,
-
- EOI= 0x20, /* non-specific end of interrupt */
-
- Elcr1= 0x4D0, /* Edge/Level Triggered Register */
- Elcr2= 0x4D1,
-};
-
-static Lock i8259lock;
-static int i8259mask = 0xFFFF; /* disabled interrupts */
-int i8259elcr; /* mask of level-triggered interrupts */
-
-void
-i8259init(void)
-{
- int x;
-
- ioalloc(Int0ctl, 2, 0, "i8259.0");
- ioalloc(Int1ctl, 2, 0, "i8259.1");
- ilock(&i8259lock);
-
- /*
- * Set up the first 8259 interrupt processor.
- * Make 8259 interrupts start at CPU vector VectorPIC.
- * Set the 8259 as master with edge triggered
- * input with fully nested interrupts.
- */
- outb(Int0ctl, (1<<4)|(0<<3)|(1<<0)); /* ICW1 - master, edge triggered,
- ICW4 will be sent */
- outb(Int0aux, VectorPIC); /* ICW2 - interrupt vector offset */
- outb(Int0aux, 0x04); /* ICW3 - have slave on level 2 */
- outb(Int0aux, 0x01); /* ICW4 - 8086 mode, not buffered */
-
- /*
- * Set up the second 8259 interrupt processor.
- * Make 8259 interrupts start at CPU vector VectorPIC+8.
- * Set the 8259 as slave with edge triggered
- * input with fully nested interrupts.
- */
- outb(Int1ctl, (1<<4)|(0<<3)|(1<<0)); /* ICW1 - master, edge triggered,
- ICW4 will be sent */
- outb(Int1aux, VectorPIC+8); /* ICW2 - interrupt vector offset */
- outb(Int1aux, 0x02); /* ICW3 - I am a slave on level 2 */
- outb(Int1aux, 0x01); /* ICW4 - 8086 mode, not buffered */
- outb(Int1aux, (i8259mask>>8) & 0xFF);
-
- /*
- * pass #2 8259 interrupts to #1
- */
- i8259mask &= ~0x04;
- outb(Int0aux, i8259mask & 0xFF);
-
- /*
- * Set Ocw3 to return the ISR when ctl read.
- * After initialisation status read is set to IRR.
- * Read IRR first to possibly deassert an outstanding
- * interrupt.
- */
- inb(Int0ctl);
- outb(Int0ctl, Ocw3|0x03);
- inb(Int1ctl);
- outb(Int1ctl, Ocw3|0x03);
-
- /*
- * Check for Edge/Level register.
- * This check may not work for all chipsets.
- * First try a non-intrusive test - the bits for
- * IRQs 13, 8, 2, 1 and 0 must be edge (0). If
- * that's OK try a R/W test.
- */
- x = (inb(Elcr2)<<8)|inb(Elcr1);
- if(!(x & 0x2107)){
- outb(Elcr1, 0);
- if(inb(Elcr1) == 0){
- outb(Elcr1, 0x20);
- if(inb(Elcr1) == 0x20)
- i8259elcr = x;
- outb(Elcr1, x & 0xFF);
- print("ELCR: %4.4uX\n", i8259elcr);
- }
- }
- iunlock(&i8259lock);
-}
-
-int
-i8259isr(int vno)
-{
- int irq, isr;
-
- if(vno < VectorPIC || vno > VectorPIC+MaxIrqPIC)
- return 0;
- irq = vno-VectorPIC;
-
- /*
- * tell the 8259 that we're done with the
- * highest level interrupt (interrupts are still
- * off at this point)
- */
- ilock(&i8259lock);
- isr = inb(Int0ctl);
- outb(Int0ctl, EOI);
- if(irq >= 8){
- isr |= inb(Int1ctl)<<8;
- outb(Int1ctl, EOI);
- }
- iunlock(&i8259lock);
-
- return isr & (1<<irq);
-}
-
-int
-i8259enable(Vctl* v)
-{
- int irq, irqbit;
-
- /*
- * Given an IRQ, enable the corresponding interrupt in the i8259
- * and return the vector to be used. The i8259 is set to use a fixed
- * range of vectors starting at VectorPIC.
- */
- irq = v->irq;
- if(irq < 0 || irq > MaxIrqPIC){
- print("i8259enable: irq %d out of range\n", irq);
- return -1;
- }
- irqbit = 1<<irq;
-
- ilock(&i8259lock);
- if(!(i8259mask & irqbit) && !(i8259elcr & irqbit)){
- print("i8259enable: irq %d shared but not level\n", irq);
- iunlock(&i8259lock);
- return -1;
- }
- i8259mask &= ~irqbit;
- if(irq < 8)
- outb(Int0aux, i8259mask & 0xFF);
- else
- outb(Int1aux, (i8259mask>>8) & 0xFF);
-
- if(i8259elcr & irqbit)
- v->eoi = i8259isr;
- else
- v->isr = i8259isr;
- iunlock(&i8259lock);
-
- return VectorPIC+irq;
-}
-
-int
-i8259vecno(int irq)
-{
- return VectorPIC+irq;
-}
-
-int
-i8259disable(int irq)
-{
- int irqbit;
-
- /*
- * Given an IRQ, disable the corresponding interrupt
- * in the 8259.
- */
- if(irq < 0 || irq > MaxIrqPIC){
- print("i8259disable: irq %d out of range\n", irq);
- return -1;
- }
- irqbit = 1<<irq;
-
- ilock(&i8259lock);
- if(!(i8259mask & irqbit)){
- i8259mask |= irqbit;
- if(irq < 8)
- outb(Int0aux, i8259mask & 0xFF);
- else
- outb(Int1aux, (i8259mask>>8) & 0xFF);
- }
- iunlock(&i8259lock);
- return 0;
-}
diff --git a/os/pc/io.h b/os/pc/io.h
deleted file mode 100644
index 2a89edee..00000000
--- a/os/pc/io.h
+++ /dev/null
@@ -1,371 +0,0 @@
-#define X86STEPPING(x) ((x) & 0x0F)
-#define X86MODEL(x) (((x)>>4) & 0x0F)
-#define X86FAMILY(x) (((x)>>8) & 0x0F)
-
-enum {
- VectorDBG = 1, /* debug exception */
- VectorNMI = 2, /* non-maskable interrupt */
- VectorBPT = 3, /* breakpoint */
- VectorUD = 6, /* invalid opcode exception */
- VectorCNA = 7, /* coprocessor not available */
- Vector2F = 8, /* double fault */
- VectorCSO = 9, /* coprocessor segment overrun */
- VectorPF = 14, /* page fault */
- Vector15 = 15, /* reserved */
- VectorCERR = 16, /* coprocessor error */
-
- VectorPIC = 32, /* external i8259 interrupts */
- IrqCLOCK = 0,
- IrqKBD = 1,
- IrqUART1 = 3,
- IrqUART0 = 4,
- IrqPCMCIA = 5,
- IrqFLOPPY = 6,
- IrqLPT = 7,
- IrqIRQ7 = 7,
- IrqAUX = 12, /* PS/2 port */
- IrqIRQ13 = 13, /* coprocessor on 386 */
- IrqATA0 = 14,
- IrqATA1 = 15,
- MaxIrqPIC = 15,
-
- VectorLAPIC = VectorPIC+16, /* local APIC interrupts */
- IrqLINT0 = 16, /* LINT[01] must be offsets 0 and 1 */
- IrqLINT1 = 17,
- IrqTIMER = 18,
- IrqERROR = 19,
- IrqPCINT = 20,
- IrqSPURIOUS = 31, /* must have bits [3-0] == 0x0F */
- MaxIrqLAPIC = 31,
-
- VectorSYSCALL = 64,
-
- VectorAPIC = 65, /* external APIC interrupts */
- MaxVectorAPIC = 255,
-};
-
-typedef struct Vctl {
- Vctl* next; /* handlers on this vector */
-
- char name[KNAMELEN]; /* of driver */
- int isintr; /* interrupt or fault/trap */
- int irq;
- int tbdf;
- int (*isr)(int); /* get isr bit for this irq */
- int (*eoi)(int); /* eoi */
-
- void (*f)(Ureg*, void*); /* handler to call */
- void* a; /* argument to call it with */
-} Vctl;
-
-enum {
- BusCBUS = 0, /* Corollary CBUS */
- BusCBUSII, /* Corollary CBUS II */
- BusEISA, /* Extended ISA */
- BusFUTURE, /* IEEE Futurebus */
- BusINTERN, /* Internal bus */
- BusISA, /* Industry Standard Architecture */
- BusMBI, /* Multibus I */
- BusMBII, /* Multibus II */
- BusMCA, /* Micro Channel Architecture */
- BusMPI, /* MPI */
- BusMPSA, /* MPSA */
- BusNUBUS, /* Apple Macintosh NuBus */
- BusPCI, /* Peripheral Component Interconnect */
- BusPCMCIA, /* PC Memory Card International Association */
- BusTC, /* DEC TurboChannel */
- BusVL, /* VESA Local bus */
- BusVME, /* VMEbus */
- BusXPRESS, /* Express System Bus */
-};
-
-#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
-#define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
-#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
-#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
-#define BUSTYPE(tbdf) ((tbdf)>>24)
-#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00)
-#define BUSUNKNOWN (-1)
-
-enum {
- MaxEISA = 16,
- CfgEISA = 0xC80,
-};
-
-/*
- * PCI support code.
- */
-enum { /* type 0 & type 1 pre-defined header */
- PciVID = 0x00, /* vendor ID */
- PciDID = 0x02, /* device ID */
- PciPCR = 0x04, /* command */
- PciPSR = 0x06, /* status */
- PciRID = 0x08, /* revision ID */
- PciCCRp = 0x09, /* programming interface class code */
- PciCCRu = 0x0A, /* sub-class code */
- PciCCRb = 0x0B, /* base class code */
- PciCLS = 0x0C, /* cache line size */
- PciLTR = 0x0D, /* latency timer */
- PciHDT = 0x0E, /* header type */
- PciBST = 0x0F, /* BIST */
-
- PciBAR0 = 0x10, /* base address */
- PciBAR1 = 0x14,
-
- PciINTL = 0x3C, /* interrupt line */
- PciINTP = 0x3D, /* interrupt pin */
-};
-
-/* ccrb (base class code) values; controller types */
-enum {
- Pcibcpci1 = 0, /* pci 1.0; no class codes defined */
- Pcibcstore = 1, /* mass storage */
- Pcibcnet = 2, /* network */
- Pcibcdisp = 3, /* display */
- Pcibcmmedia = 4, /* multimedia */
- Pcibcmem = 5, /* memory */
- Pcibcbridge = 6, /* bridge */
- Pcibccomm = 7, /* simple comms (e.g., serial) */
- Pcibcbasesys = 8, /* base system */
- Pcibcinput = 9, /* input */
- Pcibcdock = 0xa, /* docking stations */
- Pcibcproc = 0xb, /* processors */
- Pcibcserial = 0xc, /* serial bus (e.g., USB) */
- Pcibcwireless = 0xd, /* wireless */
- Pcibcintell = 0xe, /* intelligent i/o */
- Pcibcsatcom = 0xf, /* satellite comms */
- Pcibccrypto = 0x10, /* encryption/decryption */
- Pcibcdacq = 0x11, /* data acquisition & signal proc. */
-};
-
-/* ccru (sub-class code) values; common cases only */
-enum {
- /* mass storage */
- Pciscscsi = 0, /* SCSI */
- Pciscide = 1, /* IDE (ATA) */
-
- /* network */
- Pciscether = 0, /* Ethernet */
-
- /* display */
- Pciscvga = 0, /* VGA */
- Pciscxga = 1, /* XGA */
- Pcisc3d = 2, /* 3D */
-
- /* bridges */
- Pcischostpci = 0, /* host/pci */
- Pciscpcicpci = 1, /* pci/pci */
-
- /* simple comms */
- Pciscserial = 0, /* 16450, etc. */
- Pciscmultiser = 1, /* multiport serial */
-
- /* serial bus */
- Pciscusb = 3, /* USB */
-};
-
-enum { /* type 0 pre-defined header */
- PciCIS = 0x28, /* cardbus CIS pointer */
- PciSVID = 0x2C, /* subsystem vendor ID */
- PciSID = 0x2E, /* cardbus CIS pointer */
- PciEBAR0 = 0x30, /* expansion ROM base address */
- PciMGNT = 0x3E, /* burst period length */
- PciMLT = 0x3F, /* maximum latency between bursts */
-};
-
-enum { /* type 1 pre-defined header */
- PciPBN = 0x18, /* primary bus number */
- PciSBN = 0x19, /* secondary bus number */
- PciUBN = 0x1A, /* subordinate bus number */
- PciSLTR = 0x1B, /* secondary latency timer */
- PciIBR = 0x1C, /* I/O base */
- PciILR = 0x1D, /* I/O limit */
- PciSPSR = 0x1E, /* secondary status */
- PciMBR = 0x20, /* memory base */
- PciMLR = 0x22, /* memory limit */
- PciPMBR = 0x24, /* prefetchable memory base */
- PciPMLR = 0x26, /* prefetchable memory limit */
- PciPUBR = 0x28, /* prefetchable base upper 32 bits */
- PciPULR = 0x2C, /* prefetchable limit upper 32 bits */
- PciIUBR = 0x30, /* I/O base upper 16 bits */
- PciIULR = 0x32, /* I/O limit upper 16 bits */
- PciEBAR1 = 0x28, /* expansion ROM base address */
- PciBCR = 0x3E, /* bridge control register */
-};
-
-enum { /* type 2 pre-defined header */
- PciCBExCA = 0x10,
- PciCBSPSR = 0x16,
- PciCBPBN = 0x18, /* primary bus number */
- PciCBSBN = 0x19, /* secondary bus number */
- PciCBUBN = 0x1A, /* subordinate bus number */
- PciCBSLTR = 0x1B, /* secondary latency timer */
- PciCBMBR0 = 0x1C,
- PciCBMLR0 = 0x20,
- PciCBMBR1 = 0x24,
- PciCBMLR1 = 0x28,
- PciCBIBR0 = 0x2C, /* I/O base */
- PciCBILR0 = 0x30, /* I/O limit */
- PciCBIBR1 = 0x34, /* I/O base */
- PciCBILR1 = 0x38, /* I/O limit */
- PciCBSVID = 0x40, /* subsystem vendor ID */
- PciCBSID = 0x42, /* subsystem ID */
- PciCBLMBAR = 0x44, /* legacy mode base address */
-};
-
-typedef struct Pcisiz Pcisiz;
-struct Pcisiz
-{
- Pcidev* dev;
- int siz;
- int bar;
-};
-
-typedef struct Pcidev Pcidev;
-struct Pcidev
-{
- int tbdf; /* type+bus+device+function */
- ushort vid; /* vendor ID */
- ushort did; /* device ID */
-
- ushort pcr;
-
- uchar rid;
- uchar ccrp;
- uchar ccru;
- uchar ccrb;
- uchar cls;
- uchar ltr;
-
- struct {
- ulong bar; /* base address */
- int size;
- } mem[6];
-
- struct {
- ulong bar;
- int size;
- } rom;
- uchar intl; /* interrupt line */
-
- Pcidev* list;
- Pcidev* link; /* next device on this bno */
-
- Pcidev* bridge; /* down a bus */
- struct {
- ulong bar;
- int size;
- } ioa, mema;
-
- int pmrb; /* power management register block */
-};
-
-#define PCIWINDOW 0
-#define PCIWADDR(va) (PADDR(va)+PCIWINDOW)
-#define ISAWINDOW 0
-#define ISAWADDR(va) (PADDR(va)+ISAWINDOW)
-
-/* SMBus transactions */
-enum
-{
- SMBquick, /* sends address only */
-
- /* write */
- SMBsend, /* sends address and cmd */
- SMBbytewrite, /* sends address and cmd and 1 byte */
- SMBwordwrite, /* sends address and cmd and 2 bytes */
-
- /* read */
- SMBrecv, /* sends address, recvs 1 byte */
- SMBbyteread, /* sends address and cmd, recv's byte */
- SMBwordread, /* sends address and cmd, recv's 2 bytes */
-};
-
-typedef struct SMBus SMBus;
-struct SMBus {
- QLock; /* mutex */
- Rendez r; /* rendezvous point for completion interrupts */
- void *arg; /* implementation dependent */
- ulong base; /* port or memory base of smbus */
- int busy;
- void (*transact)(SMBus*, int, int, int, uchar*);
-};
-
-/*
- * PCMCIA support code.
- */
-
-typedef struct PCMslot PCMslot;
-typedef struct PCMconftab PCMconftab;
-
-/*
- * Map between ISA memory space and PCMCIA card memory space.
- */
-struct PCMmap {
- ulong ca; /* card address */
- ulong cea; /* card end address */
- ulong isa; /* ISA address */
- int len; /* length of the ISA area */
- int attr; /* attribute memory */
- int ref;
-};
-
-/* configuration table entry */
-struct PCMconftab
-{
- int index;
- ushort irqs; /* legal irqs */
- uchar irqtype;
- uchar bit16; /* true for 16 bit access */
- struct {
- ulong start;
- ulong len;
- } io[16];
- int nio;
- uchar vpp1;
- uchar vpp2;
- uchar memwait;
- ulong maxwait;
- ulong readywait;
- ulong otherwait;
-};
-
-/* a card slot */
-struct PCMslot
-{
- Lock;
- int ref;
-
- void *cp; /* controller for this slot */
- long memlen; /* memory length */
- uchar base; /* index register base */
- uchar slotno; /* slot number */
-
- /* status */
- uchar special; /* in use for a special device */
- uchar already; /* already inited */
- uchar occupied;
- uchar battery;
- uchar wrprot;
- uchar powered;
- uchar configed;
- uchar enabled;
- uchar busy;
-
- /* cis info */
- ulong msec; /* time of last slotinfo call */
- char verstr[512]; /* version string */
- int ncfg; /* number of configurations */
- struct {
- ushort cpresent; /* config registers present */
- ulong caddr; /* relative address of config registers */
- } cfg[8];
- int nctab; /* number of config table entries */
- PCMconftab ctab[8];
- PCMconftab *def; /* default conftab */
-
- /* memory maps */
- Lock mlock; /* lock down the maps */
- int time;
- PCMmap mmap[4]; /* maps, last is always for the kernel */
-};
diff --git a/os/pc/kbd.c b/os/pc/kbd.c
deleted file mode 100644
index 8db7009c..00000000
--- a/os/pc/kbd.c
+++ /dev/null
@@ -1,477 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-enum {
- Data= 0x60, /* data port */
-
- Status= 0x64, /* status port */
- Inready= 0x01, /* input character ready */
- Outbusy= 0x02, /* output busy */
- Sysflag= 0x04, /* system flag */
- Cmddata= 0x08, /* cmd==0, data==1 */
- Inhibit= 0x10, /* keyboard/mouse inhibited */
- Minready= 0x20, /* mouse character ready */
- Rtimeout= 0x40, /* general timeout */
- Parity= 0x80,
-
- Cmd= 0x64, /* command port (write only) */
-
- Spec= 0x80,
-
- PF= Spec|0x20, /* num pad function key */
- View= Spec|0x00, /* view (shift window up) */
- KF= 0xF000, /* function key (begin Unicode private space) */
- Shift= Spec|0x60,
- Break= Spec|0x61,
- Ctrl= Spec|0x62,
- Latin= Spec|0x63,
- Caps= Spec|0x64,
- Num= Spec|0x65,
- Middle= Spec|0x66,
- No= 0x00, /* peter */
-
- Home= KF|13,
- Up= KF|14,
- Pgup= KF|15,
- Print= KF|16,
- Left= KF|17,
- Right= KF|18,
- End= '\r',
- Down= View,
- Pgdown= KF|19,
- Ins= KF|20,
- Del= 0x7F,
- Scroll= KF|21,
-};
-
-/*
- * The codes at 0x79 and 0x81 are produed by the PFU Happy Hacking keyboard.
- * A 'standard' keyboard doesn't produce anything above 0x58.
- */
-Rune kbtab[] =
-{
-[0x00] No, 0x1b, '1', '2', '3', '4', '5', '6',
-[0x08] '7', '8', '9', '0', '-', '=', '\b', '\t',
-[0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
-[0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's',
-[0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
-[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v',
-[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*',
-[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
-[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
-[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
-[0x50] '2', '3', '0', '.', No, No, No, KF|11,
-[0x58] KF|12, No, No, No, No, No, No, No,
-[0x60] No, No, No, No, No, No, No, No,
-[0x68] No, No, No, No, No, No, No, No,
-[0x70] No, No, No, No, No, No, No, No,
-[0x78] No, View, No, Up, No, No, No, No,
-};
-
-Rune kbtabshift[] =
-{
-[0x00] No, 0x1b, '!', '@', '#', '$', '%', '^',
-[0x08] '&', '*', '(', ')', '_', '+', '\b', '\t',
-[0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
-[0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S',
-[0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
-[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V',
-[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*',
-[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
-[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
-[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
-[0x50] '2', '3', '0', '.', No, No, No, KF|11,
-[0x58] KF|12, No, No, No, No, No, No, No,
-[0x60] No, No, No, No, No, No, No, No,
-[0x68] No, No, No, No, No, No, No, No,
-[0x70] No, No, No, No, No, No, No, No,
-[0x78] No, Up, No, Up, No, No, No, No,
-};
-
-Rune kbtabesc1[] =
-{
-[0x00] No, No, No, No, No, No, No, No,
-[0x08] No, No, No, No, No, No, No, No,
-[0x10] No, No, No, No, No, No, No, No,
-[0x18] No, No, No, No, '\n', Ctrl, No, No,
-[0x20] No, No, No, No, No, No, No, No,
-[0x28] No, No, Shift, No, No, No, No, No,
-[0x30] No, No, No, No, No, '/', No, Print,
-[0x38] Latin, No, No, No, No, No, No, No,
-[0x40] No, No, No, No, No, No, Break, Home,
-[0x48] Up, Pgup, No, Left, No, Right, No, End,
-[0x50] Down, Pgdown, Ins, Del, No, No, No, No,
-[0x58] No, No, No, No, No, No, No, No,
-[0x60] No, No, No, No, No, No, No, No,
-[0x68] No, No, No, No, No, No, No, No,
-[0x70] No, No, No, No, No, No, No, No,
-[0x78] No, Up, No, No, No, No, No, No,
-};
-
-enum
-{
- /* controller command byte */
- Cscs1= (1<<6), /* scan code set 1 */
- Cauxdis= (1<<5), /* mouse disable */
- Ckbddis= (1<<4), /* kbd disable */
- Csf= (1<<2), /* system flag */
- Cauxint= (1<<1), /* mouse interrupt enable */
- Ckbdint= (1<<0), /* kbd interrupt enable */
-};
-
-int mouseshifted;
-
-static Lock i8042lock;
-static uchar ccc;
-static void (*auxputc)(int, int);
-
-/*
- * wait for output no longer busy
- */
-static int
-outready(void)
-{
- int tries;
-
- for(tries = 0; (inb(Status) & Outbusy); tries++){
- if(tries > 500)
- return -1;
- delay(2);
- }
- return 0;
-}
-
-/*
- * wait for input
- */
-static int
-inready(void)
-{
- int tries;
-
- for(tries = 0; !(inb(Status) & Inready); tries++){
- if(tries > 500)
- return -1;
- delay(2);
- }
- return 0;
-}
-
-/*
- * ask 8042 to reset the machine
- */
-void
-i8042reset(void)
-{
- ushort *s = KADDR(0x472);
- int i, x;
-
- *s = 0x1234; /* BIOS warm-boot flag */
-
- /*
- * newer reset the machine command
- */
- outready();
- outb(Cmd, 0xFE);
- outready();
-
- /*
- * Pulse it by hand (old somewhat reliable)
- */
- x = 0xDF;
- for(i = 0; i < 5; i++){
- x ^= 1;
- outready();
- outb(Cmd, 0xD1);
- outready();
- outb(Data, x); /* toggle reset */
- delay(100);
- }
-}
-
-int
-i8042auxcmd(int cmd)
-{
- unsigned int c;
- int tries;
-
- c = 0;
- tries = 0;
-
- ilock(&i8042lock);
- do{
- if(tries++ > 2)
- break;
- if(outready() < 0)
- break;
- outb(Cmd, 0xD4);
- if(outready() < 0)
- break;
- outb(Data, cmd);
- if(outready() < 0)
- break;
- if(inready() < 0)
- break;
- c = inb(Data);
- } while(c == 0xFE || c == 0);
- iunlock(&i8042lock);
-
- if(c != 0xFA){
- print("i8042: %2.2ux returned to the %2.2ux command\n", c, cmd);
- return -1;
- }
- return 0;
-}
-
-int
-i8042auxcmds(uchar *cmd, int ncmd)
-{
- int i;
-
- ilock(&i8042lock);
- for(i=0; i<ncmd; i++){
- if(outready() < 0)
- break;
- outb(Cmd, 0xD4);
- if(outready() < 0)
- break;
- outb(Data, cmd[i]);
- }
- iunlock(&i8042lock);
- return i;
-}
-
-/*
- * keyboard interrupt
- */
-static void
-i8042intr(Ureg*, void*)
-{
- int s, c, i;
- static int esc1, esc2;
- static int alt, caps, ctl, num, shift;
- static int collecting, nk;
- static Rune kc[5];
- int keyup;
-
- /*
- * get status
- */
- lock(&i8042lock);
- s = inb(Status);
- if(!(s&Inready)){
- unlock(&i8042lock);
- return;
- }
-
- /*
- * get the character
- */
- c = inb(Data);
- unlock(&i8042lock);
-
- /*
- * if it's the aux port...
- */
- if(s & Minready){
- if(auxputc != nil)
- auxputc(c, shift);
- return;
- }
-
- /*
- * e0's is the first of a 2 character sequence
- */
- if(c == 0xe0){
- esc1 = 1;
- return;
- } else if(c == 0xe1){
- esc2 = 2;
- return;
- }
-
- keyup = c&0x80;
- c &= 0x7f;
- if(c > sizeof kbtab){
- c |= keyup;
- if(c != 0xFF) /* these come fairly often: CAPSLOCK U Y */
- print("unknown key %ux\n", c);
- return;
- }
-
- if(esc1){
- c = kbtabesc1[c];
- esc1 = 0;
- } else if(esc2){
- esc2--;
- return;
- } else if(shift)
- c = kbtabshift[c];
- else
- c = kbtab[c];
-
- if(caps && c<='z' && c>='a')
- c += 'A' - 'a';
-
- /*
- * keyup only important for shifts
- */
- if(keyup){
- switch(c){
- case Latin:
- alt = 0;
- break;
- case Shift:
- shift = 0;
- mouseshifted = 0;
- break;
- case Ctrl:
- ctl = 0;
- break;
- }
- return;
- }
-
- /*
- * normal character
- */
- if(!(c & (Spec|KF))){
- if(ctl){
- if(alt && c == Del)
- exit(0);
- c &= 0x1f;
- }
- if(!collecting){
- kbdputc(kbdq, c);
- return;
- }
- kc[nk++] = c;
- c = latin1(kc, nk);
- if(c < -1) /* need more keystrokes */
- return;
- if(c != -1) /* valid sequence */
- kbdputc(kbdq, c);
- else /* dump characters */
- for(i=0; i<nk; i++)
- kbdputc(kbdq, kc[i]);
- nk = 0;
- collecting = 0;
- return;
- } else {
- switch(c){
- case Caps:
- caps ^= 1;
- return;
- case Num:
- num ^= 1;
- return;
- case Shift:
- shift = 1;
- mouseshifted = 1;
- return;
- case Latin:
- alt = 1;
- /*
- * VMware uses Ctl-Alt as the key combination
- * to make the VM give up keyboard and mouse focus.
- * This has the unfortunate side effect that when you
- * come back into focus, Plan 9 thinks you want to type
- * a compose sequence (you just typed alt).
- *
- * As a clumsy hack around this, we look for ctl-alt
- * and don't treat it as the start of a compose sequence.
- */
- if(!ctl){
- collecting = 1;
- nk = 0;
- }
- return;
- case Ctrl:
- collecting = 0;
- nk = 0;
- ctl = 1;
- return;
- }
- }
- kbdputc(kbdq, c);
-}
-
-void
-i8042auxenable(void (*putc)(int, int))
-{
- char *err = "i8042: aux init failed\n";
-
- /* enable kbd/aux xfers and interrupts */
- ccc &= ~Cauxdis;
- ccc |= Cauxint;
-
- ilock(&i8042lock);
- if(outready() < 0)
- print(err);
- outb(Cmd, 0x60); /* write control register */
- if(outready() < 0)
- print(err);
- outb(Data, ccc);
- if(outready() < 0)
- print(err);
- outb(Cmd, 0xA8); /* auxilliary device enable */
- if(outready() < 0){
- iunlock(&i8042lock);
- return;
- }
- auxputc = putc;
- intrenable(IrqAUX, i8042intr, 0, BUSUNKNOWN, "kbdaux");
- iunlock(&i8042lock);
-}
-
-void
-kbdinit(void)
-{
- int c;
-
- /* wait for a quiescent controller */
- while((c = inb(Status)) & (Outbusy | Inready))
- if(c & Inready)
- inb(Data);
-
- /* get current controller command byte */
- outb(Cmd, 0x20);
- if(inready() < 0){
- print("kbdinit: can't read ccc\n");
- ccc = 0;
- } else
- ccc = inb(Data);
-
- /* enable kbd xfers and interrupts */
- /* disable mouse */
- ccc &= ~Ckbddis;
- ccc |= Csf | Ckbdint | Cscs1;
- if(outready() < 0)
- print("kbd init failed\n");
- outb(Cmd, 0x60);
- if(outready() < 0)
- print("kbd init failed\n");
- outb(Data, ccc);
- outready();
-}
-
-void
-kbdenable(void)
-{
- if(kbdq == nil){
- kbdq = qopen(4*1024, 0, 0, 0);
- if(kbdq == nil)
- panic("kbdinit");
- qnoblock(kbdq, 1);
- }
-
- ioalloc(Data, 1, 0, "kbd");
- ioalloc(Cmd, 1, 0, "kbd");
-
- intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN, "kbd");
-}
diff --git a/os/pc/l.s b/os/pc/l.s
deleted file mode 100644
index 71c97d26..00000000
--- a/os/pc/l.s
+++ /dev/null
@@ -1,953 +0,0 @@
-#include "mem.h"
-
-#define PADDR(a) ((a) & ~KZERO)
-#define KADDR(a) (KZERO|(a))
-
-/*
- * Some machine instructions not handled by 8[al].
- */
-#define OP16 BYTE $0x66
-#define DELAY BYTE $0xEB; BYTE $0x00 /* JMP .+2 */
-#define CPUID BYTE $0x0F; BYTE $0xA2 /* CPUID, argument in AX */
-#define WRMSR BYTE $0x0F; BYTE $0x30 /* WRMSR, argument in AX/DX (lo/hi) */
-#define RDTSC BYTE $0x0F; BYTE $0x31 /* RDTSC, result in AX/DX (lo/hi) */
-#define RDMSR BYTE $0x0F; BYTE $0x32 /* RDMSR, result in AX/DX (lo/hi) */
-#define WBINVD BYTE $0x0F; BYTE $0x09
-#define HLT BYTE $0xF4
-
-/*
- * Macros for calculating offsets within the page directory base
- * and page tables. Note that these are assembler-specific hence
- * the '<<2'.
- */
-#define PDO(a) (((((a))>>22) & 0x03FF)<<2)
-#define PTO(a) (((((a))>>12) & 0x03FF)<<2)
-
-/*
- * For backwards compatiblity with 9load - should go away when 9load is changed
- * 9load currently sets up the mmu, however the first 16MB of memory is identity
- * mapped, so behave as if the mmu was not setup
- */
-TEXT _start0x80100020(SB), $0
- MOVL $_start0x00100020(SB), AX
- ANDL $~KZERO, AX
- JMP* AX
-
-/*
- * Must be 4-byte aligned.
- */
-TEXT _multibootheader(SB), $0
- LONG $0x1BADB002 /* magic */
- LONG $0x00010003 /* flags */
- LONG $-(0x1BADB002 + 0x00010003) /* checksum */
- LONG $_multibootheader-KZERO(SB) /* header_addr */
- LONG $_start0x80100020-KZERO(SB) /* load_addr */
- LONG $edata-KZERO(SB) /* load_end_addr */
- LONG $end-KZERO(SB) /* bss_end_addr */
- LONG $_start0x80100020-KZERO(SB) /* entry_addr */
- LONG $0 /* mode_type */
- LONG $0 /* width */
- LONG $0 /* height */
- LONG $0 /* depth */
-
-/*
- * In protected mode with paging turned off and segment registers setup to linear map all memory.
- * Entered via a jump to 0x00100020, the physical address of the virtual kernel entry point of 0x80100020
- * Make the basic page tables for processor 0. Four pages are needed for the basic set:
- * a page directory, a page table for mapping the first 4MB of physical memory to KZERO,
- * and virtual and physical pages for mapping the Mach structure.
- * The remaining PTEs will be allocated later when memory is sized.
- * An identity mmu map is also needed for the switch to virtual mode. This
- * identity mapping is removed once the MMU is going and the JMP has been made
- * to virtual memory.
- */
-TEXT _start0x00100020(SB), $0
- CLI /* make sure interrupts are off */
-
- /* set up the gdt so we have sane plan 9 style gdts. */
- MOVL $tgdtptr(SB), AX
- ANDL $~KZERO, AX
- MOVL (AX), GDTR
- MOVW $1, AX
- MOVW AX, MSW
-
- /* clear prefetch queue (weird code to avoid optimizations) */
- DELAY
-
- /* set segs to something sane (avoid traps later) */
- MOVW $(1<<3), AX
- MOVW AX, DS
- MOVW AX, SS
- MOVW AX, ES
- MOVW AX, FS
- MOVW AX, GS
-
-/* JMP $(2<<3):$mode32bit(SB) /**/
- BYTE $0xEA
- LONG $mode32bit-KZERO(SB)
- WORD $(2<<3)
-
-/*
- * gdt to get us to 32-bit/segmented/unpaged mode
- */
-TEXT tgdt(SB), $0
-
- /* null descriptor */
- LONG $0
- LONG $0
-
- /* data segment descriptor for 4 gigabytes (PL 0) */
- LONG $(0xFFFF)
- LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
-
- /* exec segment descriptor for 4 gigabytes (PL 0) */
- LONG $(0xFFFF)
- LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-
-/*
- * pointer to initial gdt
- * Note the -KZERO which puts the physical address in the gdtptr.
- * that's needed as we start executing in physical addresses.
- */
-TEXT tgdtptr(SB), $0
-
- WORD $(3*8)
- LONG $tgdt-KZERO(SB)
-
-TEXT mode32bit(SB), $0
- /* At this point, the GDT setup is done. */
-
- MOVL $PADDR(CPU0PDB), DI /* clear 4 pages for the tables etc. */
- XORL AX, AX
- MOVL $(4*BY2PG), CX
- SHRL $2, CX
-
- CLD
- REP; STOSL
-
- MOVL $PADDR(CPU0PDB), AX
- ADDL $PDO(KZERO), AX /* page directory offset for KZERO */
- MOVL $PADDR(CPU0PTE), (AX) /* PTE's for 0x80000000 */
- MOVL $(PTEWRITE|PTEVALID), BX /* page permissions */
- ORL BX, (AX)
-
- MOVL $PADDR(CPU0PTE), AX /* first page of page table */
- MOVL $1024, CX /* 1024 pages in 4MB */
-_setpte:
- MOVL BX, (AX)
- ADDL $(1<<PGSHIFT), BX
- ADDL $4, AX
- LOOP _setpte
-
- MOVL $PADDR(CPU0PTE), AX
- ADDL $PTO(MACHADDR), AX /* page table entry offset for MACHADDR */
- MOVL $PADDR(CPU0MACH), (AX) /* PTE for Mach */
- MOVL $(PTEWRITE|PTEVALID), BX /* page permissions */
- ORL BX, (AX)
-
-/*
- * Now ready to use the new map. Make sure the processor options are what is wanted.
- * It is necessary on some processors to immediately follow mode switching with a JMP instruction
- * to clear the prefetch queues.
- */
- MOVL $PADDR(CPU0PDB), CX /* load address of page directory */
- MOVL (PDO(KZERO))(CX), DX /* double-map KZERO at 0 */
- MOVL DX, (PDO(0))(CX)
- MOVL CX, CR3
- DELAY /* JMP .+2 */
-
- MOVL CR0, DX
- ORL $0x80010000, DX /* PG|WP */
- ANDL $~0x6000000A, DX /* ~(CD|NW|TS|MP) */
-
- MOVL $_startpg(SB), AX /* this is a virtual address */
- MOVL DX, CR0 /* turn on paging */
- JMP* AX /* jump to the virtual nirvana */
-
-/*
- * Basic machine environment set, can clear BSS and create a stack.
- * The stack starts at the top of the page containing the Mach structure.
- * The x86 architecture forces the use of the same virtual address for
- * each processor's Mach structure, so the global Mach pointer 'm' can
- * be initialised here.
- */
-TEXT _startpg(SB), $0
- MOVL $0, (PDO(0))(CX) /* undo double-map of KZERO at 0 */
- MOVL CX, CR3 /* load and flush the mmu */
-
-_clearbss:
- MOVL $edata(SB), DI
- XORL AX, AX
- MOVL $end(SB), CX
- SUBL DI, CX /* end-edata bytes */
- SHRL $2, CX /* end-edata doublewords */
-
- CLD
- REP; STOSL /* clear BSS */
-
- MOVL $MACHADDR, SP
- MOVL SP, m(SB) /* initialise global Mach pointer */
- MOVL $0, 0(SP) /* initialise m->machno */
-
- ADDL $(MACHSIZE-4), SP /* initialise stack */
-
-/*
- * Need to do one final thing to ensure a clean machine environment,
- * clear the EFLAGS register, which can only be done once there is a stack.
- */
- MOVL $0, AX
- PUSHL AX
- POPFL
-
- CALL main(SB)
-
-/*
- * Park a processor. Should never fall through a return from main to here,
- * should only be called by application processors when shutting down.
- */
-TEXT idle(SB), $0
-_idle:
- STI
- HLT
- JMP _idle
-
-/*
- * Port I/O.
- * in[bsl] input a byte|short|long
- * ins[bsl] input a string of bytes|shorts|longs
- * out[bsl] output a byte|short|long
- * outs[bsl] output a string of bytes|shorts|longs
- */
-TEXT inb(SB), $0
- MOVL port+0(FP), DX
- XORL AX, AX
- INB
- RET
-
-TEXT insb(SB), $0
- MOVL port+0(FP), DX
- MOVL address+4(FP), DI
- MOVL count+8(FP), CX
- CLD
- REP; INSB
- RET
-
-TEXT ins(SB), $0
- MOVL port+0(FP), DX
- XORL AX, AX
- OP16; INL
- RET
-
-TEXT inss(SB), $0
- MOVL port+0(FP), DX
- MOVL address+4(FP), DI
- MOVL count+8(FP), CX
- CLD
- REP; OP16; INSL
- RET
-
-TEXT inl(SB), $0
- MOVL port+0(FP), DX
- INL
- RET
-
-TEXT insl(SB), $0
- MOVL port+0(FP), DX
- MOVL address+4(FP), DI
- MOVL count+8(FP), CX
- CLD
- REP; INSL
- RET
-
-TEXT outb(SB), $0
- MOVL port+0(FP), DX
- MOVL byte+4(FP), AX
- OUTB
- RET
-
-TEXT outsb(SB), $0
- MOVL port+0(FP), DX
- MOVL address+4(FP), SI
- MOVL count+8(FP), CX
- CLD
- REP; OUTSB
- RET
-
-TEXT outs(SB), $0
- MOVL port+0(FP), DX
- MOVL short+4(FP), AX
- OP16; OUTL
- RET
-
-TEXT outss(SB), $0
- MOVL port+0(FP), DX
- MOVL address+4(FP), SI
- MOVL count+8(FP), CX
- CLD
- REP; OP16; OUTSL
- RET
-
-TEXT outl(SB), $0
- MOVL port+0(FP), DX
- MOVL long+4(FP), AX
- OUTL
- RET
-
-TEXT outsl(SB), $0
- MOVL port+0(FP), DX
- MOVL address+4(FP), SI
- MOVL count+8(FP), CX
- CLD
- REP; OUTSL
- RET
-
-/* there's a macro in fns.h but libinterp can't see it */
-TEXT getcallerpc(SB), $0
- MOVL a+0(FP), AX
- RET
-
-/*
- * Read/write various system registers.
- * CR4 and the 'model specific registers' should only be read/written
- * after it has been determined the processor supports them
- */
-TEXT lgdt(SB), $0 /* GDTR - global descriptor table */
- MOVL gdtptr+0(FP), AX
- MOVL (AX), GDTR
- RET
-
-TEXT lidt(SB), $0 /* IDTR - interrupt descriptor table */
- MOVL idtptr+0(FP), AX
- MOVL (AX), IDTR
- RET
-
-TEXT ltr(SB), $0 /* TR - task register */
- MOVL tptr+0(FP), AX
- MOVW AX, TASK
- RET
-
-TEXT getcr0(SB), $0 /* CR0 - processor control */
- MOVL CR0, AX
- RET
-
-TEXT getcr2(SB), $0 /* CR2 - page fault linear address */
- MOVL CR2, AX
- RET
-
-TEXT getcr3(SB), $0 /* CR3 - page directory base */
- MOVL CR3, AX
- RET
-
-TEXT putcr3(SB), $0
- MOVL cr3+0(FP), AX
- MOVL AX, CR3
- RET
-
-TEXT getcr4(SB), $0 /* CR4 - extensions */
- MOVL CR4, AX
- RET
-
-TEXT putcr4(SB), $0
- MOVL cr4+0(FP), AX
- MOVL AX, CR4
- RET
-
-TEXT _cycles(SB), $0 /* time stamp counter; cycles since power up */
- RDTSC
- MOVL vlong+0(FP), CX /* &vlong */
- MOVL AX, 0(CX) /* lo */
- MOVL DX, 4(CX) /* hi */
- RET
-
-TEXT rdmsr(SB), $0 /* model-specific register */
- MOVL index+0(FP), CX
- RDMSR
- MOVL vlong+4(FP), CX /* &vlong */
- MOVL AX, 0(CX) /* lo */
- MOVL DX, 4(CX) /* hi */
- RET
-
-TEXT wrmsr(SB), $0
- MOVL index+0(FP), CX
- MOVL lo+4(FP), AX
- MOVL hi+8(FP), DX
- WRMSR
- RET
-
-TEXT wbinvd(SB), $0
- WBINVD
- RET
-
-TEXT rdtsc32(SB), $0
- CPUID
- RDTSC
- RET
-
-/*
- * Try to determine the CPU type which requires fiddling with EFLAGS.
- * If the Id bit can be toggled then the CPUID instruction can be used
- * to determine CPU identity and features. First have to check if it's
- * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
- * toggled then it's an older 486 of some kind.
- *
- * cpuid(id[], &ax, &dx);
- */
-TEXT cpuid(SB), $0
- MOVL $0x240000, AX
- PUSHL AX
- POPFL /* set Id|Ac */
-
- PUSHFL
- POPL BX /* retrieve value */
-
- MOVL $0, AX
- PUSHL AX
- POPFL /* clear Id|Ac, EFLAGS initialised */
-
- PUSHFL
- POPL AX /* retrieve value */
- XORL BX, AX
- TESTL $0x040000, AX /* Ac */
- JZ _cpu386 /* can't set this bit on 386 */
- TESTL $0x200000, AX /* Id */
- JZ _cpu486 /* can't toggle this bit on some 486 */
-
- MOVL $0, AX
- CPUID
- MOVL id+0(FP), BP
- MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */
- MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */
- MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */
-
- MOVL $1, AX
- CPUID
- JMP _cpuid
-
-_cpu486:
- MOVL $0x400, AX
- MOVL $0, DX
- JMP _cpuid
-
-_cpu386:
- MOVL $0x300, AX
- MOVL $0, DX
-
-_cpuid:
- MOVL ax+4(FP), BP
- MOVL AX, 0(BP)
- MOVL dx+8(FP), BP
- MOVL DX, 0(BP)
- RET
-
-/*
- * Basic timing loop to determine CPU frequency.
- */
-TEXT aamloop(SB), $0
- MOVL count+0(FP), CX
-_aamloop:
- AAM
- LOOP _aamloop
- RET
-
-/*
- * Floating point.
- * Note: the encodings for the FCLEX, FINIT, FSAVE, FSTCW, FSENV and FSTSW
- * instructions do NOT have the WAIT prefix byte (i.e. they act like their
- * FNxxx variations) so WAIT instructions must be explicitly placed in the
- * code as necessary.
- */
-#define FPOFF(l) ;\
- MOVL CR0, AX ;\
- ANDL $0xC, AX /* EM, TS */ ;\
- CMPL AX, $0x8 ;\
- JEQ l ;\
- WAIT ;\
-l: ;\
- MOVL CR0, AX ;\
- ANDL $~0x4, AX /* EM=0 */ ;\
- ORL $0x28, AX /* NE=1, TS=1 */ ;\
- MOVL AX, CR0
-
-#define FPON ;\
- MOVL CR0, AX ;\
- ANDL $~0xC, AX /* EM=0, TS=0 */ ;\
- MOVL AX, CR0
-
-TEXT fpoff(SB), $0 /* disable */
- FPOFF(l1)
- RET
-
-TEXT fpinit(SB), $0 /* enable and init */
- FPON
- FINIT
- WAIT
- /* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */
- /* note that low 6 bits are masks, not enables, on this chip */
- PUSHW $0x0232
- FLDCW 0(SP)
- POPW AX
- WAIT
- RET
-
-TEXT fpsave(SB), $0 /* save state and disable */
- MOVL p+0(FP), AX
- FSAVE 0(AX) /* no WAIT */
- FPOFF(l2)
- RET
-
-TEXT fprestore(SB), $0 /* enable and restore state */
- FPON
- MOVL p+0(FP), AX
- FRSTOR 0(AX)
- WAIT
- RET
-
-TEXT fpstatus(SB), $0 /* get floating point status */
- FSTSW AX
- RET
-
-TEXT fpenv(SB), $0 /* save state without waiting */
- MOVL p+0(FP), AX
- FSTENV 0(AX)
- RET
-
-TEXT fpclear(SB), $0 /* clear pending exceptions */
- FPON
- FCLEX /* no WAIT */
- FPOFF(l3)
- RET
-
-/*
- */
-TEXT splhi(SB), $0
- MOVL $(MACHADDR+0x04), AX /* save PC in m->splpc */
- MOVL (SP), BX
- MOVL BX, (AX)
-
- PUSHFL
- POPL AX
- CLI
- RET
-
-TEXT spllo(SB), $0
- PUSHFL
- POPL AX
- STI
- RET
-
-TEXT splx(SB), $0
- MOVL $(MACHADDR+0x04), AX /* save PC in m->splpc */
- MOVL (SP), BX
- MOVL BX, (AX)
- /*FALLTHROUGH*/
-
-TEXT splxpc(SB), $0 /* for iunlock */
- MOVL s+0(FP), AX
- PUSHL AX
- POPFL
- RET
-
-TEXT spldone(SB), $0
- RET
-
-TEXT islo(SB), $0
- PUSHFL
- POPL AX
- ANDL $0x200, AX /* interrupt enable flag */
- RET
-
-/*
- * Test-And-Set
- */
-TEXT _tas(SB), $0
- MOVL $0xDEADDEAD, AX
- MOVL lock+0(FP), BX
- XCHGL AX, (BX) /* lock->key */
- RET
-
-TEXT _xinc(SB), $0 /* void _xinc(long*); */
- MOVL l+0(FP), AX
- LOCK; INCL 0(AX)
- RET
-
-TEXT _xdec(SB), $0 /* long _xdec(long*); */
- MOVL l+0(FP), BX
- XORL AX, AX
- LOCK; DECL 0(BX)
- JLT _xdeclt
- JGT _xdecgt
- RET
-_xdecgt:
- INCL AX
- RET
-_xdeclt:
- DECL AX
- RET
-
-TEXT mb386(SB), $0
- POPL AX /* return PC */
- PUSHFL
- PUSHL CS
- PUSHL AX
- IRETL
-
-TEXT mb586(SB), $0
- XORL AX, AX
- CPUID
- RET
-
-TEXT xchgw(SB), $0
- MOVL v+4(FP), AX
- MOVL p+0(FP), BX
- XCHGW AX, (BX)
- RET
-
-TEXT mul64fract(SB), $0
-/*
- * Multiply two 64-bit number s and keep the middle 64 bits from the 128-bit result
- * See ../port/tod.c for motivation.
- */
- MOVL r+0(FP), CX
- XORL BX, BX /* BX = 0 */
-
- MOVL a+8(FP), AX
- MULL b+16(FP) /* a1*b1 */
- MOVL AX, 4(CX) /* r2 = lo(a1*b1) */
-
- MOVL a+8(FP), AX
- MULL b+12(FP) /* a1*b0 */
- MOVL AX, 0(CX) /* r1 = lo(a1*b0) */
- ADDL DX, 4(CX) /* r2 += hi(a1*b0) */
-
- MOVL a+4(FP), AX
- MULL b+16(FP) /* a0*b1 */
- ADDL AX, 0(CX) /* r1 += lo(a0*b1) */
- ADCL DX, 4(CX) /* r2 += hi(a0*b1) + carry */
-
- MOVL a+4(FP), AX
- MULL b+12(FP) /* a0*b0 */
- ADDL DX, 0(CX) /* r1 += hi(a0*b0) */
- ADCL BX, 4(CX) /* r2 += carry */
- RET
-
-/*
- * label consists of a stack pointer and a PC
- */
-TEXT gotolabel(SB), $0
- MOVL label+0(FP), AX
- MOVL 0(AX), SP /* restore sp */
- MOVL 4(AX), AX /* put return pc on the stack */
- MOVL AX, 0(SP)
- MOVL $1, AX /* return 1 */
- RET
-
-TEXT setlabel(SB), $0
- MOVL label+0(FP), AX
- MOVL SP, 0(AX) /* store sp */
- MOVL 0(SP), BX /* store return pc */
- MOVL BX, 4(AX)
- MOVL $0, AX /* return 0 */
- RET
-
-TEXT halt(SB), $0
- STI
- HLT
- RET
-
-/*
- * Interrupt/exception handling.
- * Each entry in the vector table calls either _strayintr or _strayintrx depending
- * on whether an error code has been automatically pushed onto the stack
- * (_strayintrx) or not, in which case a dummy entry must be pushed before retrieving
- * the trap type from the vector table entry and placing it on the stack as part
- * of the Ureg structure.
- * The size of each entry in the vector table (6 bytes) is known in trapinit().
- */
-TEXT _strayintr(SB), $0
- PUSHL AX /* save AX */
- MOVL 4(SP), AX /* return PC from vectortable(SB) */
- JMP intrcommon
-
-TEXT _strayintrx(SB), $0
- XCHGL AX, (SP) /* exchange AX with pointer to trap type */
-intrcommon:
- PUSHL DS
- MOVBLZX (AX), AX /* trap type -> AX */
- XCHGL AX, 4(SP) /* exchange trap type with AX */
- PUSHL ES
- PUSHL FS
- PUSHL GS
- PUSHAL
- MOVL $(KDSEL), AX
- MOVW AX, DS
- MOVW AX, ES
- PUSHL SP /* Ureg* argument to trap */
- CALL trap(SB)
-
-TEXT forkret(SB), $0
- POPL AX
- POPAL
- POPL GS
- POPL FS
- POPL ES
- POPL DS
- ADDL $8, SP /* pop error code and trap type */
- IRETL
-
-TEXT vectortable(SB), $0
- CALL _strayintr(SB); BYTE $0x00 /* divide error */
- CALL _strayintr(SB); BYTE $0x01 /* debug exception */
- CALL _strayintr(SB); BYTE $0x02 /* NMI interrupt */
- CALL _strayintr(SB); BYTE $0x03 /* breakpoint */
- CALL _strayintr(SB); BYTE $0x04 /* overflow */
- CALL _strayintr(SB); BYTE $0x05 /* bound */
- CALL _strayintr(SB); BYTE $0x06 /* invalid opcode */
- CALL _strayintr(SB); BYTE $0x07 /* no coprocessor available */
- CALL _strayintrx(SB); BYTE $0x08 /* double fault */
- CALL _strayintr(SB); BYTE $0x09 /* coprocessor segment overflow */
- CALL _strayintrx(SB); BYTE $0x0A /* invalid TSS */
- CALL _strayintrx(SB); BYTE $0x0B /* segment not available */
- CALL _strayintrx(SB); BYTE $0x0C /* stack exception */
- CALL _strayintrx(SB); BYTE $0x0D /* general protection error */
- CALL _strayintrx(SB); BYTE $0x0E /* page fault */
- CALL _strayintr(SB); BYTE $0x0F /* */
- CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */
- CALL _strayintrx(SB); BYTE $0x11 /* alignment check */
- CALL _strayintr(SB); BYTE $0x12 /* machine check */
- CALL _strayintr(SB); BYTE $0x13
- CALL _strayintr(SB); BYTE $0x14
- CALL _strayintr(SB); BYTE $0x15
- CALL _strayintr(SB); BYTE $0x16
- CALL _strayintr(SB); BYTE $0x17
- CALL _strayintr(SB); BYTE $0x18
- CALL _strayintr(SB); BYTE $0x19
- CALL _strayintr(SB); BYTE $0x1A
- CALL _strayintr(SB); BYTE $0x1B
- CALL _strayintr(SB); BYTE $0x1C
- CALL _strayintr(SB); BYTE $0x1D
- CALL _strayintr(SB); BYTE $0x1E
- CALL _strayintr(SB); BYTE $0x1F
- CALL _strayintr(SB); BYTE $0x20 /* VectorLAPIC */
- CALL _strayintr(SB); BYTE $0x21
- CALL _strayintr(SB); BYTE $0x22
- CALL _strayintr(SB); BYTE $0x23
- CALL _strayintr(SB); BYTE $0x24
- CALL _strayintr(SB); BYTE $0x25
- CALL _strayintr(SB); BYTE $0x26
- CALL _strayintr(SB); BYTE $0x27
- CALL _strayintr(SB); BYTE $0x28
- CALL _strayintr(SB); BYTE $0x29
- CALL _strayintr(SB); BYTE $0x2A
- CALL _strayintr(SB); BYTE $0x2B
- CALL _strayintr(SB); BYTE $0x2C
- CALL _strayintr(SB); BYTE $0x2D
- CALL _strayintr(SB); BYTE $0x2E
- CALL _strayintr(SB); BYTE $0x2F
- CALL _strayintr(SB); BYTE $0x30
- CALL _strayintr(SB); BYTE $0x31
- CALL _strayintr(SB); BYTE $0x32
- CALL _strayintr(SB); BYTE $0x33
- CALL _strayintr(SB); BYTE $0x34
- CALL _strayintr(SB); BYTE $0x35
- CALL _strayintr(SB); BYTE $0x36
- CALL _strayintr(SB); BYTE $0x37
- CALL _strayintr(SB); BYTE $0x38
- CALL _strayintr(SB); BYTE $0x39
- CALL _strayintr(SB); BYTE $0x3A
- CALL _strayintr(SB); BYTE $0x3B
- CALL _strayintr(SB); BYTE $0x3C
- CALL _strayintr(SB); BYTE $0x3D
- CALL _strayintr(SB); BYTE $0x3E
- CALL _strayintr(SB); BYTE $0x3F
- CALL _strayintr(SB); BYTE $0x40 /* VectorSYSCALL */
- CALL _strayintr(SB); BYTE $0x41
- CALL _strayintr(SB); BYTE $0x42
- CALL _strayintr(SB); BYTE $0x43
- CALL _strayintr(SB); BYTE $0x44
- CALL _strayintr(SB); BYTE $0x45
- CALL _strayintr(SB); BYTE $0x46
- CALL _strayintr(SB); BYTE $0x47
- CALL _strayintr(SB); BYTE $0x48
- CALL _strayintr(SB); BYTE $0x49
- CALL _strayintr(SB); BYTE $0x4A
- CALL _strayintr(SB); BYTE $0x4B
- CALL _strayintr(SB); BYTE $0x4C
- CALL _strayintr(SB); BYTE $0x4D
- CALL _strayintr(SB); BYTE $0x4E
- CALL _strayintr(SB); BYTE $0x4F
- CALL _strayintr(SB); BYTE $0x50
- CALL _strayintr(SB); BYTE $0x51
- CALL _strayintr(SB); BYTE $0x52
- CALL _strayintr(SB); BYTE $0x53
- CALL _strayintr(SB); BYTE $0x54
- CALL _strayintr(SB); BYTE $0x55
- CALL _strayintr(SB); BYTE $0x56
- CALL _strayintr(SB); BYTE $0x57
- CALL _strayintr(SB); BYTE $0x58
- CALL _strayintr(SB); BYTE $0x59
- CALL _strayintr(SB); BYTE $0x5A
- CALL _strayintr(SB); BYTE $0x5B
- CALL _strayintr(SB); BYTE $0x5C
- CALL _strayintr(SB); BYTE $0x5D
- CALL _strayintr(SB); BYTE $0x5E
- CALL _strayintr(SB); BYTE $0x5F
- CALL _strayintr(SB); BYTE $0x60
- CALL _strayintr(SB); BYTE $0x61
- CALL _strayintr(SB); BYTE $0x62
- CALL _strayintr(SB); BYTE $0x63
- CALL _strayintr(SB); BYTE $0x64
- CALL _strayintr(SB); BYTE $0x65
- CALL _strayintr(SB); BYTE $0x66
- CALL _strayintr(SB); BYTE $0x67
- CALL _strayintr(SB); BYTE $0x68
- CALL _strayintr(SB); BYTE $0x69
- CALL _strayintr(SB); BYTE $0x6A
- CALL _strayintr(SB); BYTE $0x6B
- CALL _strayintr(SB); BYTE $0x6C
- CALL _strayintr(SB); BYTE $0x6D
- CALL _strayintr(SB); BYTE $0x6E
- CALL _strayintr(SB); BYTE $0x6F
- CALL _strayintr(SB); BYTE $0x70
- CALL _strayintr(SB); BYTE $0x71
- CALL _strayintr(SB); BYTE $0x72
- CALL _strayintr(SB); BYTE $0x73
- CALL _strayintr(SB); BYTE $0x74
- CALL _strayintr(SB); BYTE $0x75
- CALL _strayintr(SB); BYTE $0x76
- CALL _strayintr(SB); BYTE $0x77
- CALL _strayintr(SB); BYTE $0x78
- CALL _strayintr(SB); BYTE $0x79
- CALL _strayintr(SB); BYTE $0x7A
- CALL _strayintr(SB); BYTE $0x7B
- CALL _strayintr(SB); BYTE $0x7C
- CALL _strayintr(SB); BYTE $0x7D
- CALL _strayintr(SB); BYTE $0x7E
- CALL _strayintr(SB); BYTE $0x7F
- CALL _strayintr(SB); BYTE $0x80 /* Vector[A]PIC */
- CALL _strayintr(SB); BYTE $0x81
- CALL _strayintr(SB); BYTE $0x82
- CALL _strayintr(SB); BYTE $0x83
- CALL _strayintr(SB); BYTE $0x84
- CALL _strayintr(SB); BYTE $0x85
- CALL _strayintr(SB); BYTE $0x86
- CALL _strayintr(SB); BYTE $0x87
- CALL _strayintr(SB); BYTE $0x88
- CALL _strayintr(SB); BYTE $0x89
- CALL _strayintr(SB); BYTE $0x8A
- CALL _strayintr(SB); BYTE $0x8B
- CALL _strayintr(SB); BYTE $0x8C
- CALL _strayintr(SB); BYTE $0x8D
- CALL _strayintr(SB); BYTE $0x8E
- CALL _strayintr(SB); BYTE $0x8F
- CALL _strayintr(SB); BYTE $0x90
- CALL _strayintr(SB); BYTE $0x91
- CALL _strayintr(SB); BYTE $0x92
- CALL _strayintr(SB); BYTE $0x93
- CALL _strayintr(SB); BYTE $0x94
- CALL _strayintr(SB); BYTE $0x95
- CALL _strayintr(SB); BYTE $0x96
- CALL _strayintr(SB); BYTE $0x97
- CALL _strayintr(SB); BYTE $0x98
- CALL _strayintr(SB); BYTE $0x99
- CALL _strayintr(SB); BYTE $0x9A
- CALL _strayintr(SB); BYTE $0x9B
- CALL _strayintr(SB); BYTE $0x9C
- CALL _strayintr(SB); BYTE $0x9D
- CALL _strayintr(SB); BYTE $0x9E
- CALL _strayintr(SB); BYTE $0x9F
- CALL _strayintr(SB); BYTE $0xA0
- CALL _strayintr(SB); BYTE $0xA1
- CALL _strayintr(SB); BYTE $0xA2
- CALL _strayintr(SB); BYTE $0xA3
- CALL _strayintr(SB); BYTE $0xA4
- CALL _strayintr(SB); BYTE $0xA5
- CALL _strayintr(SB); BYTE $0xA6
- CALL _strayintr(SB); BYTE $0xA7
- CALL _strayintr(SB); BYTE $0xA8
- CALL _strayintr(SB); BYTE $0xA9
- CALL _strayintr(SB); BYTE $0xAA
- CALL _strayintr(SB); BYTE $0xAB
- CALL _strayintr(SB); BYTE $0xAC
- CALL _strayintr(SB); BYTE $0xAD
- CALL _strayintr(SB); BYTE $0xAE
- CALL _strayintr(SB); BYTE $0xAF
- CALL _strayintr(SB); BYTE $0xB0
- CALL _strayintr(SB); BYTE $0xB1
- CALL _strayintr(SB); BYTE $0xB2
- CALL _strayintr(SB); BYTE $0xB3
- CALL _strayintr(SB); BYTE $0xB4
- CALL _strayintr(SB); BYTE $0xB5
- CALL _strayintr(SB); BYTE $0xB6
- CALL _strayintr(SB); BYTE $0xB7
- CALL _strayintr(SB); BYTE $0xB8
- CALL _strayintr(SB); BYTE $0xB9
- CALL _strayintr(SB); BYTE $0xBA
- CALL _strayintr(SB); BYTE $0xBB
- CALL _strayintr(SB); BYTE $0xBC
- CALL _strayintr(SB); BYTE $0xBD
- CALL _strayintr(SB); BYTE $0xBE
- CALL _strayintr(SB); BYTE $0xBF
- CALL _strayintr(SB); BYTE $0xC0
- CALL _strayintr(SB); BYTE $0xC1
- CALL _strayintr(SB); BYTE $0xC2
- CALL _strayintr(SB); BYTE $0xC3
- CALL _strayintr(SB); BYTE $0xC4
- CALL _strayintr(SB); BYTE $0xC5
- CALL _strayintr(SB); BYTE $0xC6
- CALL _strayintr(SB); BYTE $0xC7
- CALL _strayintr(SB); BYTE $0xC8
- CALL _strayintr(SB); BYTE $0xC9
- CALL _strayintr(SB); BYTE $0xCA
- CALL _strayintr(SB); BYTE $0xCB
- CALL _strayintr(SB); BYTE $0xCC
- CALL _strayintr(SB); BYTE $0xCD
- CALL _strayintr(SB); BYTE $0xCE
- CALL _strayintr(SB); BYTE $0xCF
- CALL _strayintr(SB); BYTE $0xD0
- CALL _strayintr(SB); BYTE $0xD1
- CALL _strayintr(SB); BYTE $0xD2
- CALL _strayintr(SB); BYTE $0xD3
- CALL _strayintr(SB); BYTE $0xD4
- CALL _strayintr(SB); BYTE $0xD5
- CALL _strayintr(SB); BYTE $0xD6
- CALL _strayintr(SB); BYTE $0xD7
- CALL _strayintr(SB); BYTE $0xD8
- CALL _strayintr(SB); BYTE $0xD9
- CALL _strayintr(SB); BYTE $0xDA
- CALL _strayintr(SB); BYTE $0xDB
- CALL _strayintr(SB); BYTE $0xDC
- CALL _strayintr(SB); BYTE $0xDD
- CALL _strayintr(SB); BYTE $0xDE
- CALL _strayintr(SB); BYTE $0xDF
- CALL _strayintr(SB); BYTE $0xE0
- CALL _strayintr(SB); BYTE $0xE1
- CALL _strayintr(SB); BYTE $0xE2
- CALL _strayintr(SB); BYTE $0xE3
- CALL _strayintr(SB); BYTE $0xE4
- CALL _strayintr(SB); BYTE $0xE5
- CALL _strayintr(SB); BYTE $0xE6
- CALL _strayintr(SB); BYTE $0xE7
- CALL _strayintr(SB); BYTE $0xE8
- CALL _strayintr(SB); BYTE $0xE9
- CALL _strayintr(SB); BYTE $0xEA
- CALL _strayintr(SB); BYTE $0xEB
- CALL _strayintr(SB); BYTE $0xEC
- CALL _strayintr(SB); BYTE $0xED
- CALL _strayintr(SB); BYTE $0xEE
- CALL _strayintr(SB); BYTE $0xEF
- CALL _strayintr(SB); BYTE $0xF0
- CALL _strayintr(SB); BYTE $0xF1
- CALL _strayintr(SB); BYTE $0xF2
- CALL _strayintr(SB); BYTE $0xF3
- CALL _strayintr(SB); BYTE $0xF4
- CALL _strayintr(SB); BYTE $0xF5
- CALL _strayintr(SB); BYTE $0xF6
- CALL _strayintr(SB); BYTE $0xF7
- CALL _strayintr(SB); BYTE $0xF8
- CALL _strayintr(SB); BYTE $0xF9
- CALL _strayintr(SB); BYTE $0xFA
- CALL _strayintr(SB); BYTE $0xFB
- CALL _strayintr(SB); BYTE $0xFC
- CALL _strayintr(SB); BYTE $0xFD
- CALL _strayintr(SB); BYTE $0xFE
- CALL _strayintr(SB); BYTE $0xFF
diff --git a/os/pc/main.c b/os/pc/main.c
deleted file mode 100644
index 11e8d4db..00000000
--- a/os/pc/main.c
+++ /dev/null
@@ -1,468 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-
-extern int main_pool_pcnt;
-extern int heap_pool_pcnt;
-extern int image_pool_pcnt;
-int pckdebug;
-
-Mach *m;
-
-static uchar *sp; /* stack pointer for /boot */
-
-/*
- * Where configuration info is left for the loaded programme.
- * This will turn into a structure as more is done by the boot loader
- * (e.g. why parse the .ini file twice?).
- * There are 3584 bytes available at CONFADDR.
- */
-#define BOOTLINE ((char*)CONFADDR)
-#define BOOTLINELEN 64
-#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN))
-#define BOOTARGSLEN (4096-0x200-BOOTLINELEN)
-#define MAXCONF 64
-
-char bootdisk[KNAMELEN];
-char *confname[MAXCONF];
-char *confval[MAXCONF];
-int nconf;
-
-static void
-options(void)
-{
- long i, n;
- char *cp, *line[MAXCONF], *p, *q;
-
- /*
- * parse configuration args from dos file plan9.ini
- */
- cp = BOOTARGS; /* where b.com leaves its config */
- cp[BOOTARGSLEN-1] = 0;
-
- /*
- * Strip out '\r', change '\t' -> ' '.
- */
- p = cp;
- for(q = cp; *q; q++){
- if(*q == '\r')
- continue;
- if(*q == '\t')
- *q = ' ';
- *p++ = *q;
- }
- *p = 0;
-
- n = getfields(cp, line, MAXCONF, 1, "\n");
- for(i = 0; i < n; i++){
- if(*line[i] == '#')
- continue;
- cp = strchr(line[i], '=');
- if(cp == nil)
- continue;
- *cp++ = '\0';
- confname[nconf] = line[i];
- confval[nconf] = cp;
- nconf++;
- }
-}
-
-static void
-doc(char *m)
-{
- int i;
- print("%s...\n", m);
- for(i = 0; i < 100*1024*1024; i++)
- i++;
-}
-
-void
-main(void)
-{
- outb(0x3F2, 0x00); /* botch: turn off the floppy motor */
-
- mach0init();
- options();
- ioinit();
- i8250console();
- quotefmtinstall();
- kbdinit();
- i8253init();
- cpuidentify();
- confinit();
- archinit();
- xinit();
- poolsizeinit();
- trapinit();
- printinit();
- screeninit();
- cpuidprint();
- mmuinit();
- eve = strdup("inferno");
- if(arch->intrinit){ /* launches other processors on an mp */
- doc("intrinit");
- arch->intrinit();
- }
- doc("timersinit");
- timersinit();
- doc("mathinit");
- mathinit();
- doc("kbdenable");
- kbdenable();
- if(arch->clockenable){
- doc("clockinit");
- arch->clockenable();
- }
- doc("procinit");
- procinit();
- doc("links");
- links();
- doc("chandevreset");
- chandevreset();
- doc("userinit");
- userinit();
- doc("schedinit");
- active.thunderbirdsarego = 1;
- schedinit();
-
-}
-
-void
-mach0init(void)
-{
- conf.nmach = 1;
- MACHP(0) = (Mach*)CPU0MACH;
- m->pdb = (ulong*)CPU0PDB;
- m->gdt = (Segdesc*)CPU0GDT;
-
- machinit();
-
- active.machs = 1;
- active.exiting = 0;
-}
-
-void
-machinit(void)
-{
- int machno;
- ulong *pdb;
- Segdesc *gdt;
-
- machno = m->machno;
- pdb = m->pdb;
- gdt = m->gdt;
- memset(m, 0, sizeof(Mach));
- m->machno = machno;
- m->pdb = pdb;
- m->gdt = gdt;
-
- /*
- * For polled uart output at boot, need
- * a default delay constant. 100000 should
- * be enough for a while. Cpuidentify will
- * calculate the real value later.
- */
- m->loopconst = 100000;
-}
-
-void
-init0(void)
-{
- Osenv *o;
- int i;
- char buf[2*KNAMELEN];
-
- up->nerrlab = 0;
-
- spllo();
- if(waserror())
- panic("init0: %r");
- /*
- * These are o.k. because rootinit is null.
- * Then early kproc's will have a root and dot.
- */
- o = up->env;
- o->pgrp->slash = namec("#/", Atodir, 0, 0);
- cnameclose(o->pgrp->slash->name);
- o->pgrp->slash->name = newcname("/");
- o->pgrp->dot = cclone(o->pgrp->slash);
-
- chandevinit();
-
- if(!waserror()){
- ksetenv("cputype", "386", 0);
- snprint(buf, sizeof(buf), "386 %s", conffile);
- ksetenv("terminal", buf, 0);
- for(i = 0; i < nconf; i++){
- if(confname[i][0] != '*')
- ksetenv(confname[i], confval[i], 0);
- ksetenv(confname[i], confval[i], 1);
- }
- poperror();
- }
-
- poperror();
-
- disinit("/osinit.dis");
-}
-
-void
-userinit(void)
-{
- Proc *p;
- Osenv *o;
-
- p = newproc();
- o = p->env;
-
- o->fgrp = newfgrp(nil);
-
- o->pgrp = newpgrp();
- kstrdup(&o->user, eve);
-
- strcpy(p->text, "interp");
-
- p->fpstate = FPINIT;
- fpoff();
-
- /*
- * Kernel Stack
- *
- * N.B. make sure there's
- * 4 bytes for gotolabel's return PC
- */
- p->sched.pc = (ulong)init0;
- p->sched.sp = (ulong)p->kstack+KSTACK-BY2WD;
-
- ready(p);
-}
-
-Conf conf;
-
-char*
-getconf(char *name)
-{
- int i;
-
- for(i = 0; i < nconf; i++)
- if(cistrcmp(confname[i], name) == 0)
- return confval[i];
- return 0;
-}
-
-void
-confinit(void)
-{
- char *p;
- int pcnt;
- ulong maxmem;
-
- if(p = getconf("*maxmem"))
- maxmem = strtoul(p, 0, 0);
- else
- maxmem = 0;
- if(p = getconf("*kernelpercent"))
- pcnt = 100 - strtol(p, 0, 0);
- else
- pcnt = 0;
-
- meminit(maxmem);
-
- conf.npage = conf.npage0 + conf.npage1;
- if(pcnt < 10)
- pcnt = 70;
- conf.ialloc = (((conf.npage*(100-pcnt))/100)/2)*BY2PG;
-
- conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
-}
-
-void
-poolsizeinit(void)
-{
- ulong nb;
-
- nb = conf.npage*BY2PG;
- poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
- poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
- poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
-}
-
-static char *mathmsg[] =
-{
- "invalid operation",
- "denormalized operand",
- "division by zero",
- "numeric overflow",
- "numeric underflow",
- "precision loss",
- "stack",
- "error",
-};
-
-/*
- * math coprocessor error
- */
-void
-matherror(Ureg* ureg, void* arg)
-{
- ulong status;
- int i;
- char *msg;
- char note[ERRMAX];
-
- USED(arg);
-
- /*
- * a write cycle to port 0xF0 clears the interrupt latch attached
- * to the error# line from the 387
- */
- if(!(m->cpuiddx & 0x01))
- outb(0xF0, 0xFF);
-
- /*
- * save floating point state to check out error
- */
- FPsave(&up->fpsave.env);
- status = up->fpsave.env.status;
-
- msg = 0;
- for(i = 0; i < 8; i++)
- if((1<<i) & status){
- msg = mathmsg[i];
- sprint(note, "sys: fp: %s fppc=0x%lux", msg, up->fpsave.env.pc);
- error(note);
- break;
- }
- if(msg == 0){
- sprint(note, "sys: fp: unknown fppc=0x%lux", up->fpsave.env.pc);
- error(note);
- }
- if(ureg->pc & KZERO)
- panic("fp: status %lux fppc=0x%lux pc=0x%lux", status,
- up->fpsave.env.pc, ureg->pc);
-}
-
-/*
- * math coprocessor emulation fault
- */
-void
-mathemu(Ureg* ureg, void* arg)
-{
- USED(ureg, arg);
- switch(up->fpstate){
- case FPINIT:
- fpinit();
- up->fpstate = FPACTIVE;
- break;
- case FPINACTIVE:
- fprestore(&up->fpsave);
- up->fpstate = FPACTIVE;
- break;
- case FPACTIVE:
- panic("math emu");
- break;
- }
-}
-
-/*
- * math coprocessor segment overrun
- */
-void
-mathover(Ureg* ureg, void* arg)
-{
- USED(arg);
- print("sys: fp: math overrun pc 0x%lux pid %ld\n", ureg->pc, up->pid);
- pexit("math overrun", 0);
-}
-
-void
-mathinit(void)
-{
- trapenable(VectorCERR, matherror, 0, "matherror");
- if(X86FAMILY(m->cpuidax) == 3)
- intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
- trapenable(VectorCNA, mathemu, 0, "mathemu");
- trapenable(VectorCSO, mathover, 0, "mathover");
-}
-
-/*
- * Save the mach dependent part of the process state.
- */
-void
-procsave(Proc *p)
-{
- if(p->fpstate == FPACTIVE){
- if(p->state == Moribund)
- fpoff();
- else
- fpsave(&up->fpsave);
- p->fpstate = FPINACTIVE;
- }
-}
-
-void
-exit(int ispanic)
-{
- USED(ispanic);
-
- up = 0;
- print("exiting\n");
-
- /* Shutdown running devices */
- chandevshutdown();
-
- arch->reset();
-}
-
-void
-reboot(void)
-{
- exit(0);
-}
-
-int
-isaconfig(char *class, int ctlrno, ISAConf *isa)
-{
- char cc[32], *p;
- int i;
-
- snprint(cc, sizeof cc, "%s%d", class, ctlrno);
- p = getconf(cc);
- if(p == nil)
- return 0;
-
- isa->nopt = tokenize(p, isa->opt, NISAOPT);
- for(i = 0; i < isa->nopt; i++){
- p = isa->opt[i];
- if(cistrncmp(p, "type=", 5) == 0)
- isa->type = p + 5;
- else if(cistrncmp(p, "port=", 5) == 0)
- isa->port = strtoul(p+5, &p, 0);
- else if(cistrncmp(p, "irq=", 4) == 0)
- isa->irq = strtoul(p+4, &p, 0);
- else if(cistrncmp(p, "dma=", 4) == 0)
- isa->dma = strtoul(p+4, &p, 0);
- else if(cistrncmp(p, "mem=", 4) == 0)
- isa->mem = strtoul(p+4, &p, 0);
- else if(cistrncmp(p, "size=", 5) == 0)
- isa->size = strtoul(p+5, &p, 0);
- else if(cistrncmp(p, "freq=", 5) == 0)
- isa->freq = strtoul(p+5, &p, 0);
- }
- return 1;
-}
-
-/*
- * put the processor in the halt state if we've no processes to run.
- * an interrupt will get us going again.
- */
-void
-idlehands(void)
-{
- if(conf.nmach == 1)
- halt();
-}
diff --git a/os/pc/mem.h b/os/pc/mem.h
deleted file mode 100644
index b67252ee..00000000
--- a/os/pc/mem.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Memory and machine-specific definitions. Used in C and assembler.
- */
-
-/*
- * Sizes
- */
-#define BI2BY 8 /* bits per byte */
-#define BI2WD 32 /* bits per word */
-#define BY2WD 4 /* bytes per word */
-#define BY2V 8 /* bytes per double word */
-#define BY2PG 4096 /* bytes per page */
-#define WD2PG (BY2PG/BY2WD) /* words per page */
-#define PGSHIFT 12 /* log(BY2PG) */
-#define ROUND(s, sz) (((s)+((sz)-1))&~((sz)-1))
-#define PGROUND(s) ROUND(s, BY2PG)
-#define BLOCKALIGN 8
-
-#define MAXMACH 8 /* max # cpus system can run */
-#define KSTACK 8192 /* Size of kernel stack */
-
-/*
- * Time
- */
-#define HZ (100) /* clock frequency */
-#define MS2HZ (1000/HZ) /* millisec per clock tick */
-#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
-#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */
-
-/*
- * Fundamental addresses
- */
-#define IDTADDR 0x80000800 /* idt */
-#define REBOOTADDR 0x00001000 /* reboot code - physical address */
-#define APBOOTSTRAP 0x80001000 /* AP bootstrap code */
-#define CONFADDR 0x80001200 /* info passed from boot loader */
-#define CPU0PDB 0x80002000 /* bootstrap processor PDB */
-#define CPU0PTE 0x80003000 /* bootstrap processor PTE's for 0-4MB */
-#define CPU0GDT 0x80004000 /* bootstrap processor GDT */
-#define MACHADDR 0x80005000 /* as seen by current processor */
-#define CPU0MACH 0x80006000 /* Mach for bootstrap processor */
-#define MACHSIZE BY2PG
-/*
- * N.B. ramscan knows that CPU0MACH+BY2PG is the end of reserved data
- * N.B. _start0x00100020 knows that CPU0PDB is the first reserved page
- * and that there are 5 of them.
- */
-
-/*
- * Address spaces
- *
- * User is at 0-2GB
- * Kernel is at 2GB-4GB
- */
-#define UZERO 0 /* base of user address space */
-#define UTZERO (UZERO+BY2PG) /* first address in user text */
-#define KZERO 0x80000000 /* base of kernel address space */
-#define KTZERO 0x80100000 /* first address in kernel text */
-#define USTKTOP (KZERO-BY2PG) /* byte just beyond user stack */
-#define USTKSIZE (16*1024*1024) /* size of user stack */
-#define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */
-#define TSTKSIZ 100
-
-/*
- * known x86 segments (in GDT) and their selectors
- */
-#define NULLSEG 0 /* null segment */
-#define KDSEG 1 /* kernel data/stack */
-#define KESEG 2 /* kernel executable */
-#define UDSEG 3 /* user data/stack */
-#define UESEG 4 /* user executable */
-#define TSSSEG 5 /* task segment */
-#define APMCSEG 6 /* APM code segment */
-#define APMCSEG16 7 /* APM 16-bit code segment */
-#define APMDSEG 8 /* APM data segment */
-#define NGDT 10 /* number of GDT entries required */
-/* #define APM40SEG 8 /* APM segment 0x40 */
-
-#define SELGDT (0<<2) /* selector is in gdt */
-#define SELLDT (1<<2) /* selector is in ldt */
-
-#define SELECTOR(i, t, p) (((i)<<3) | (t) | (p))
-
-#define NULLSEL SELECTOR(NULLSEG, SELGDT, 0)
-#define KDSEL SELECTOR(KDSEG, SELGDT, 0)
-#define KESEL SELECTOR(KESEG, SELGDT, 0)
-#define UESEL SELECTOR(UESEG, SELGDT, 3)
-#define UDSEL SELECTOR(UDSEG, SELGDT, 3)
-#define TSSSEL SELECTOR(TSSSEG, SELGDT, 0)
-#define APMCSEL SELECTOR(APMCSEG, SELGDT, 0)
-#define APMCSEL16 SELECTOR(APMCSEG16, SELGDT, 0)
-#define APMDSEL SELECTOR(APMDSEG, SELGDT, 0)
-/* #define APM40SEL SELECTOR(APM40SEG, SELGDT, 0) */
-
-/*
- * fields in segment descriptors
- */
-#define SEGDATA (0x10<<8) /* data/stack segment */
-#define SEGEXEC (0x18<<8) /* executable segment */
-#define SEGTSS (0x9<<8) /* TSS segment */
-#define SEGCG (0x0C<<8) /* call gate */
-#define SEGIG (0x0E<<8) /* interrupt gate */
-#define SEGTG (0x0F<<8) /* trap gate */
-#define SEGTYPE (0x1F<<8)
-
-#define SEGP (1<<15) /* segment present */
-#define SEGPL(x) ((x)<<13) /* priority level */
-#define SEGB (1<<22) /* granularity 1==4k (for expand-down) */
-#define SEGG (1<<23) /* granularity 1==4k (for other) */
-#define SEGE (1<<10) /* expand down */
-#define SEGW (1<<9) /* writable (for data/stack) */
-#define SEGR (1<<9) /* readable (for code) */
-#define SEGD (1<<22) /* default 1==32bit (for code) */
-
-/*
- * virtual MMU
- */
-#define PTEMAPMEM (1024*1024)
-#define PTEPERTAB (PTEMAPMEM/BY2PG)
-#define SEGMAPSIZE 1984
-#define SSEGMAPSIZE 16
-#define PPN(x) ((x)&~(BY2PG-1))
-
-/*
- * physical MMU
- */
-#define PTEVALID (1<<0)
-#define PTEWT (1<<3)
-#define PTEUNCACHED (1<<4)
-#define PTEWRITE (1<<1)
-#define PTERONLY (0<<1)
-#define PTEKERNEL (0<<2)
-#define PTEUSER (1<<2)
-#define PTESIZE (1<<7)
-#define PTEGLOBAL (1<<8)
-
-/*
- * Macros for calculating offsets within the page directory base
- * and page tables.
- */
-#define PDX(va) ((((ulong)(va))>>22) & 0x03FF)
-#define PTX(va) ((((ulong)(va))>>12) & 0x03FF)
-
-#define getpgcolor(a) 0
diff --git a/os/pc/memory.c b/os/pc/memory.c
deleted file mode 100644
index 85658248..00000000
--- a/os/pc/memory.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Size memory and create the kernel page-tables on the fly while doing so.
- * Called from main(), this code should only be run by the bootstrap processor.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#define MEMDEBUG 0
-
-enum {
- MemUPA = 0, /* unbacked physical address */
- MemRAM = 1, /* physical memory */
- MemUMB = 2, /* upper memory block (<16MB) */
- NMemType = 3,
-
- KB = 1024,
-
- MemMinMB = 4, /* minimum physical memory (<=4MB) */
- MemMaxMB = 768, /* maximum physical memory to check */
-
- NMemBase = 10,
-};
-
-typedef struct {
- int size;
- ulong addr;
-} Map;
-
-typedef struct {
- char* name;
- Map* map;
- Map* mapend;
-
- Lock;
-} RMap;
-
-static Map mapupa[16];
-static RMap rmapupa = {
- "unallocated unbacked physical memory",
- mapupa,
- &mapupa[nelem(mapupa)-1],
-};
-
-static Map xmapupa[16];
-static RMap xrmapupa = {
- "unbacked physical memory",
- xmapupa,
- &xmapupa[nelem(xmapupa)-1],
-};
-
-static Map mapram[16];
-static RMap rmapram = {
- "physical memory",
- mapram,
- &mapram[nelem(mapram)-1],
-};
-
-static Map mapumb[64];
-static RMap rmapumb = {
- "upper memory block",
- mapumb,
- &mapumb[nelem(mapumb)-1],
-};
-
-static Map mapumbrw[16];
-static RMap rmapumbrw = {
- "UMB device memory",
- mapumbrw,
- &mapumbrw[nelem(mapumbrw)-1],
-};
-
-void
-mapprint(RMap *rmap)
-{
- Map *mp;
-
- print("%s\n", rmap->name);
- for(mp = rmap->map; mp->size; mp++)
- print("\t%8.8luX %8.8uX %8.8luX\n", mp->addr, mp->size, mp->addr+mp->size);
-}
-
-void
-memdebug(void)
-{
- ulong maxpa, maxpa1, maxpa2;
-
- if(MEMDEBUG == 0)
- return;
-
- maxpa = (nvramread(0x18)<<8)|nvramread(0x17);
- maxpa1 = (nvramread(0x31)<<8)|nvramread(0x30);
- maxpa2 = (nvramread(0x16)<<8)|nvramread(0x15);
- print("maxpa = %luX -> %luX, maxpa1 = %luX maxpa2 = %luX\n",
- maxpa, MB+maxpa*KB, maxpa1, maxpa2);
-
- mapprint(&rmapram);
- mapprint(&rmapumb);
- mapprint(&rmapumbrw);
- mapprint(&rmapupa);
-}
-
-void
-mapfree(RMap* rmap, ulong addr, ulong size)
-{
- Map *mp;
- ulong t;
-
- if(size <= 0)
- return;
-
- lock(rmap);
- for(mp = rmap->map; mp->addr <= addr && mp->size; mp++)
- ;
-
- if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){
- (mp-1)->size += size;
- if(addr+size == mp->addr){
- (mp-1)->size += mp->size;
- while(mp->size){
- mp++;
- (mp-1)->addr = mp->addr;
- (mp-1)->size = mp->size;
- }
- }
- }
- else{
- if(addr+size == mp->addr && mp->size){
- mp->addr -= size;
- mp->size += size;
- }
- else do{
- if(mp >= rmap->mapend){
- print("mapfree: %s: losing 0x%luX, %ld\n",
- rmap->name, addr, size);
- break;
- }
- t = mp->addr;
- mp->addr = addr;
- addr = t;
- t = mp->size;
- mp->size = size;
- mp++;
- }while(size = t);
- }
- unlock(rmap);
-}
-
-ulong
-mapalloc(RMap* rmap, ulong addr, int size, int align)
-{
- Map *mp;
- ulong maddr, oaddr;
-
- lock(rmap);
- for(mp = rmap->map; mp->size; mp++){
- maddr = mp->addr;
-
- if(addr){
- /*
- * A specific address range has been given:
- * if the current map entry is greater then
- * the address is not in the map;
- * if the current map entry does not overlap
- * the beginning of the requested range then
- * continue on to the next map entry;
- * if the current map entry does not entirely
- * contain the requested range then the range
- * is not in the map.
- */
- if(maddr > addr)
- break;
- if(mp->size < addr - maddr) /* maddr+mp->size < addr, but no overflow */
- continue;
- if(addr - maddr > mp->size - size) /* addr+size > maddr+mp->size, but no overflow */
- break;
- maddr = addr;
- }
-
- if(align > 0)
- maddr = ((maddr+align-1)/align)*align;
- if(mp->addr+mp->size-maddr < size)
- continue;
-
- oaddr = mp->addr;
- mp->addr = maddr+size;
- mp->size -= maddr-oaddr+size;
- if(mp->size == 0){
- do{
- mp++;
- (mp-1)->addr = mp->addr;
- }while((mp-1)->size = mp->size);
- }
-
- unlock(rmap);
- if(oaddr != maddr)
- mapfree(rmap, oaddr, maddr-oaddr);
-
- return maddr;
- }
- unlock(rmap);
-
- return 0;
-}
-
-static void
-umbscan(void)
-{
- uchar *p;
-
- /*
- * Scan the Upper Memory Blocks (0xA0000->0xF0000) for pieces
- * which aren't used; they can be used later for devices which
- * want to allocate some virtual address space.
- * Check for two things:
- * 1) device BIOS ROM. This should start with a two-byte header
- * of 0x55 0xAA, followed by a byte giving the size of the ROM
- * in 512-byte chunks. These ROM's must start on a 2KB boundary.
- * 2) device memory. This is read-write.
- * There are some assumptions: there's VGA memory at 0xA0000 and
- * the VGA BIOS ROM is at 0xC0000. Also, if there's no ROM signature
- * at 0xE0000 then the whole 64KB up to 0xF0000 is theoretically up
- * for grabs; check anyway.
- */
- p = KADDR(0xD0000);
- while(p < (uchar*)KADDR(0xE0000)){
- /*
- * Test for 0x55 0xAA before poking obtrusively,
- * some machines (e.g. Thinkpad X20) seem to map
- * something dynamic here (cardbus?) causing weird
- * problems if it is changed.
- */
- if(p[0] == 0x55 && p[1] == 0xAA){
- p += p[2]*512;
- continue;
- }
-
- p[0] = 0xCC;
- p[2*KB-1] = 0xCC;
- if(p[0] != 0xCC || p[2*KB-1] != 0xCC){
- p[0] = 0x55;
- p[1] = 0xAA;
- p[2] = 4;
- if(p[0] == 0x55 && p[1] == 0xAA){
- p += p[2]*512;
- continue;
- }
- if(p[0] == 0xFF && p[1] == 0xFF)
- mapfree(&rmapumb, PADDR(p), 2*KB);
- }
- else
- mapfree(&rmapumbrw, PADDR(p), 2*KB);
- p += 2*KB;
- }
-
- p = KADDR(0xE0000);
- if(p[0] != 0x55 || p[1] != 0xAA){
- p[0] = 0xCC;
- p[64*KB-1] = 0xCC;
- if(p[0] != 0xCC && p[64*KB-1] != 0xCC)
- mapfree(&rmapumb, PADDR(p), 64*KB);
- }
-}
-
-
-static void
-ramscan(ulong maxmem)
-{
- ulong *k0, kzero, map, maxpa, pa, *pte, *table, *va, x, n;
- int nvalid[NMemType];
- uchar *bda;
-
- /*
- * The bootstrap code has has created a prototype page
- * table which maps the first MemMinMB of physical memory to KZERO.
- * The page directory is at m->pdb and the first page of
- * free memory is after the per-processor MMU information.
- */
- /*
- * Initialise the memory bank information for conventional memory
- * (i.e. less than 640KB). The base is the first location after the
- * bootstrap processor MMU information and the limit is obtained from
- * the BIOS data area.
- */
- x = PADDR(CPU0MACH+BY2PG);
- bda = (uchar*)KADDR(0x400);
- n = ((bda[0x14]<<8)|bda[0x13])*KB-x;
- mapfree(&rmapram, x, n);
-// memset(KADDR(x), 0, n); /* keep us honest */
-
- x = PADDR(PGROUND((ulong)end));
- pa = MemMinMB*MB;
- mapfree(&rmapram, x, pa-x);
-// memset(KADDR(x), 0, pa-x); /* keep us honest */
-
- /*
- * Check if the extended memory size can be obtained from the CMOS.
- * If it's 0 then it's either not known or >= 64MB. Always check
- * at least 24MB in case there's a memory gap (up to 8MB) below 16MB;
- * in this case the memory from the gap is remapped to the top of
- * memory.
- * The value in CMOS is supposed to be the number of KB above 1MB.
- */
- if(maxmem == 0){
- x = (nvramread(0x18)<<8)|nvramread(0x17);
- if(x == 0 || x >= (63*KB))
- maxpa = MemMaxMB*MB;
- else
- maxpa = MB+x*KB;
- if(maxpa < 24*MB)
- maxpa = 24*MB;
- maxmem = MemMaxMB*MB;
- }
- else
- maxpa = maxmem;
-
- /*
- * March up memory from MemMinMB to maxpa 1MB at a time,
- * mapping the first page and checking the page can
- * be written and read correctly. The page tables are created here
- * on the fly, allocating from low memory as necessary.
- */
- k0 = (ulong*)KADDR(0);
- kzero = *k0;
- map = 0;
- x = 0x12345678;
- memset(nvalid, 0, sizeof(nvalid));
- while(pa < maxpa){
- /*
- * Map the page. Use mapalloc(&rmapram, ...) to make
- * the page table if necessary, it will be returned to the
- * pool later if it isn't needed.
- */
- va = KADDR(pa);
- table = &m->pdb[PDX(va)];
- if(*table == 0){
- if(map == 0 && (map = mapalloc(&rmapram, 0, BY2PG, BY2PG)) == 0)
- break;
- memset(KADDR(map), 0, BY2PG);
- *table = map|PTEWRITE|PTEVALID;
- memset(nvalid, 0, sizeof(nvalid));
- }
- table = KADDR(PPN(*table));
- pte = &table[PTX(va)];
-
- *pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
- mmuflushtlb(PADDR(m->pdb));
-
- /*
- * Write a pattern to the page and write a different
- * pattern to a possible mirror at KZER0. If the data
- * reads back correctly the chunk is some type of RAM (possibly
- * a linearly-mapped VGA framebuffer, for instance...) and
- * can be cleared and added to the memory pool. If not, the
- * chunk is marked uncached and added to the UMB pool if <16MB
- * or is marked invalid and added to the UPA pool.
- */
- *va = x;
- *k0 = ~x;
- if(*va == x){
- nvalid[MemRAM] += MB/BY2PG;
- mapfree(&rmapram, pa, MB);
-
- do{
- *pte++ = pa|PTEWRITE|PTEVALID;
- pa += BY2PG;
- }while(pa % MB);
- mmuflushtlb(PADDR(m->pdb));
- /* memset(va, 0, MB); so damn slow to memset all of memory */
- }
- else if(pa < 16*MB){
- nvalid[MemUMB] += MB/BY2PG;
- mapfree(&rmapumb, pa, MB);
-
- do{
- *pte++ = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
- pa += BY2PG;
- }while(pa % MB);
- }
- else{
- nvalid[MemUPA] += MB/BY2PG;
- mapfree(&rmapupa, pa, MB);
-
- *pte = 0;
- pa += MB;
- }
-
- /*
- * Done with this 4MB chunk, review the options:
- * 1) not physical memory and >=16MB - invalidate the PDB entry;
- * 2) physical memory - use the 4MB page extension if possible;
- * 3) not physical memory and <16MB - use the 4MB page extension
- * if possible;
- * 4) mixed or no 4MB page extension - commit the already
- * initialised space for the page table.
- */
- if((pa % (4*MB)) == 0){
- table = &m->pdb[PDX(va)];
- if(nvalid[MemUPA] == (4*MB)/BY2PG)
- *table = 0;
- else if(nvalid[MemRAM] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
- *table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEVALID;
- else if(nvalid[MemUMB] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
- *table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
- else
- map = 0;
- }
-
- mmuflushtlb(PADDR(m->pdb));
- x += 0x3141526;
- }
-
- /*
- * If we didn't reach the end of the 4MB chunk, that part won't
- * be mapped. Commit the already initialised space for the page table.
- */
- if(pa % (4*MB))
- map = 0;
-
- if(map)
- mapfree(&rmapram, map, BY2PG);
- if(pa < maxmem)
- mapfree(&rmapupa, pa, maxmem-pa);
- if(maxmem < 0xFFE00000)
- mapfree(&rmapupa, maxmem, 0x00000000-maxmem);
- if(MEMDEBUG)
- print("maxmem %luX %luX\n", maxmem, 0x00000000-maxmem);
- *k0 = kzero;
-}
-
-void
-meminit(ulong maxmem)
-{
- Map *mp, *xmp;
- ulong pa, *pte;
-
- /*
- * Set special attributes for memory between 640KB and 1MB:
- * VGA memory is writethrough;
- * BIOS ROM's/UMB's are uncached;
- * then scan for useful memory.
- */
- for(pa = 0xA0000; pa < 0xC0000; pa += BY2PG){
- pte = mmuwalk(m->pdb, (ulong)KADDR(pa), 2, 0);
- *pte |= PTEWT;
- }
- for(pa = 0xC0000; pa < 0x100000; pa += BY2PG){
- pte = mmuwalk(m->pdb, (ulong)KADDR(pa), 2, 0);
- *pte |= PTEUNCACHED;
- }
- mmuflushtlb(PADDR(m->pdb));
-
- umbscan();
- ramscan(maxmem);
-
- /*
- * Set the conf entries describing two banks of allocatable memory.
- * Grab the first and largest entries in rmapram as left by ramscan().
- *
- * It would be nice to have more than 2 memory banks describable in conf.
- */
- mp = rmapram.map;
- conf.base0 = mp->addr;
- conf.npage0 = mp->size/BY2PG;
- mp++;
- for(xmp = 0; mp->size; mp++){
- if(xmp == 0 || mp->size > xmp->size)
- xmp = mp;
- }
-
- if(xmp){
- conf.base1 = xmp->addr;
- conf.npage1 = xmp->size/BY2PG;
- }
- if(MEMDEBUG)
- memdebug();
-}
-
-ulong
-umbmalloc(ulong addr, int size, int align)
-{
- ulong a;
-
- if(a = mapalloc(&rmapumb, addr, size, align))
- return (ulong)KADDR(a);
-
- return 0;
-}
-
-void
-umbfree(ulong addr, int size)
-{
- mapfree(&rmapumb, PADDR(addr), size);
-}
-
-ulong
-umbrwmalloc(ulong addr, int size, int align)
-{
- ulong a;
- uchar *p;
-
- if(a = mapalloc(&rmapumbrw, addr, size, align))
- return(ulong)KADDR(a);
-
- /*
- * Perhaps the memory wasn't visible before
- * the interface is initialised, so try again.
- */
- if((a = umbmalloc(addr, size, align)) == 0)
- return 0;
- p = (uchar*)a;
- p[0] = 0xCC;
- p[size-1] = 0xCC;
- if(p[0] == 0xCC && p[size-1] == 0xCC)
- return a;
- umbfree(a, size);
-
- return 0;
-}
-
-void
-umbrwfree(ulong addr, int size)
-{
- mapfree(&rmapumbrw, PADDR(addr), size);
-}
-
-ulong
-upamalloc(ulong pa, int size, int align)
-{
- ulong a, ae;
-
- if(a = mapalloc(&xrmapupa, pa, size, align))
- return a;
-
- if((a = mapalloc(&rmapupa, pa, size, align)) == 0){
- memdebug();
- return 0;
- }
-
- /*
- * Upamalloc is a request to map a range of physical addresses.
- * Therefore, if pa is 0 mapalloc will choose the base address.
- * Note, however, mmukmap is always asked to give a 1-to-1 mapping
- * of va to pa.
- */
- ae = mmukmap(a, a, size);
-
- /*
- * Should check here that it was all delivered
- * and put it back and barf if not.
- */
- USED(ae);
-
- /*
- * Be very careful this returns a PHYSICAL address
- * mapped 1-to-1 with the virtual address.
- * If a < KZERO it's probably not a good idea to
- * try KADDR(a)...
- */
- return a;
-}
-
-void
-upafree(ulong pa, int size)
-{
- mapfree(&xrmapupa, pa, size);
-}
-
-void
-upareserve(ulong pa, int size)
-{
- ulong a;
-
- a = mapalloc(&rmapupa, pa, size, 0);
- if(a != pa){
- /*
- * This can happen when we're using the E820
- * map, which might have already reserved some
- * of the regions claimed by the pci devices.
- */
- // print("upareserve: cannot reserve pa=%#.8lux size=%d\n", pa, size);
- if(a != 0)
- mapfree(&rmapupa, a, size);
- }
-}
diff --git a/os/pc/mkfile b/os/pc/mkfile
deleted file mode 100644
index c7366fd2..00000000
--- a/os/pc/mkfile
+++ /dev/null
@@ -1,83 +0,0 @@
-<../../mkconfig
-
-#Configurable parameters
-
-CONF=pc #default configuration
-CONFLIST=pc pcdisk
-CLEANCONFLIST=pc pcdisk zpc zpcrem pix pcsoe
-
-SYSTARG=$OSTARG
-OBJTYPE=386
-INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin #path of directory where kernel is installed
-#INSTALLDIR=/$OBJTYPE
-
-#end configurable parameters
-
-<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE #set vars based on target system
-
-<| $SHELLNAME ../port/mkdevlist $CONF #sets $IP, $DEVS, $ETHERS, $VGAS, $PORT, $MISC, $LIBS, $OTHERS
-
-OBJ=\
- l.$O\
- fpsave.$O\
- portclock.$O\
- tod.$O\
- i8250.$O\
- i8253.$O\
- i8259.$O\
- kbd.$O\
- main.$O\
- memory.$O\
- mmu.$O\
- trap.$O\
- $CONF.root.$O\
- $IP\
- $DEVS\
- $ETHERS\
- $LINKS\
- $PORT\
- $MISC\
- $OTHERS\
-
-LIBNAMES=${LIBS:%=lib%.a}
-
-HFILES=\
- mem.h\
- dat.h\
- fns.h\
- io.h\
-
-CFLAGS=-wFVT -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp -I../port
-KERNDATE=`{$NDATE}
-
-default:V: i$CONF
-
-i$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES
- $CC $CFLAGS '-DKERNDATE='$KERNDATE $CONF.c
- $LD -o $target -T0x80100020 -l $OBJ $CONF.$O $LIBFILES
- $KSIZE $target
-
-install:V: i$CONF
- cp i$CONF $INSTALLDIR/i$CONF
-
-<../port/portmkfile
-
-clock.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
-devether.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
-fault386.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
-main.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
-trap.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
-
-devether.$O $ETHERS: etherif.h ../port/netif.h
-$IP devip.$O: ../ip/ip.h
-
-# to be moved to port/interp
-bench.h:D: ../../module/bench.m
- rm -f $target && limbo -a -I../../module ../../module/bench.m > $target
-benchmod.h:D: ../../module/bench.m
- rm -f $target && limbo -t Bench -I../../module ../../module/bench.m > $target
-devbench.$O: bench.h benchmod.h
-$VGA screen.$O: screen.h vga.h
-
-devuart.$O: ../port/devuart.c ../port/uart.h
- $CC $CFLAGS ../port/devuart.c
diff --git a/os/pc/mmu.c b/os/pc/mmu.c
deleted file mode 100644
index da86517d..00000000
--- a/os/pc/mmu.c
+++ /dev/null
@@ -1,343 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#define DATASEGM(p) { 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
-#define EXECSEGM(p) { 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
-#define TSSSEGM(b,p) { ((b)<<16)|sizeof(Tss),\
- ((b)&0xFF000000)|(((b)>>16)&0xFF)|SEGTSS|SEGPL(p)|SEGP }
-
-Segdesc gdt[NGDT] =
-{
-[NULLSEG] { 0, 0}, /* null descriptor */
-[KDSEG] DATASEGM(0), /* kernel data/stack */
-[KESEG] EXECSEGM(0), /* kernel code */
-[UDSEG] DATASEGM(3), /* user data/stack */
-[UESEG] EXECSEGM(3), /* user code */
-[TSSSEG] TSSSEGM(0,0), /* tss segment */
-};
-
-static void
-taskswitch(ulong pdb, ulong stack)
-{
- Tss *tss;
-
- tss = m->tss;
- tss->ss0 = KDSEL;
- tss->esp0 = stack;
- tss->ss1 = KDSEL;
- tss->esp1 = stack;
- tss->ss2 = KDSEL;
- tss->esp2 = stack;
- tss->cr3 = pdb;
- putcr3(pdb);
-}
-
-/*
- * On processors that support it, we set the PTEGLOBAL bit in
- * page table and page directory entries that map kernel memory.
- * Doing this tells the processor not to bother flushing them
- * from the TLB when doing the TLB flush associated with a
- * context switch (write to CR3). Since kernel memory mappings
- * are never removed, this is safe. (If we ever remove kernel memory
- * mappings, we can do a full flush by turning off the PGE bit in CR4,
- * writing to CR3, and then turning the PGE bit back on.)
- *
- * See also mmukmap below.
- *
- * Processor support for the PTEGLOBAL bit is enabled in devarch.c.
- */
-static void
-memglobal(void)
-{
- int i, j;
- ulong *pde, *pte;
-
- /* only need to do this once, on bootstrap processor */
- if(m->machno != 0)
- return;
-
- if(!m->havepge)
- return;
-
- pde = m->pdb;
- for(i=512; i<1024; i++){ /* 512: start at entry for virtual 0x80000000 */
- if(pde[i] & PTEVALID){
- pde[i] |= PTEGLOBAL;
- if(!(pde[i] & PTESIZE)){
- pte = KADDR(pde[i]&~(BY2PG-1));
- for(j=0; j<1024; j++)
- if(pte[j] & PTEVALID)
- pte[j] |= PTEGLOBAL;
- }
- }
- }
-}
-
-void
-mmuinit(void)
-{
- ulong x, *p;
- ushort ptr[3];
-
- memglobal();
-
- m->tss = malloc(sizeof(Tss));
- memset(m->tss, 0, sizeof(Tss));
- m->tss->iomap = 0xDFFF<<16;
-
- /*
- * We used to keep the GDT in the Mach structure, but it
- * turns out that that slows down access to the rest of the
- * page. Since the Mach structure is accessed quite often,
- * it pays off anywhere from a factor of 1.25 to 2 on real
- * hardware to separate them (the AMDs are more sensitive
- * than Intels in this regard). Under VMware it pays off
- * a factor of about 10 to 100.
- */
-
- memmove(m->gdt, gdt, sizeof gdt);
- x = (ulong)m->tss;
- m->gdt[TSSSEG].d0 = (x<<16)|sizeof(Tss);
- m->gdt[TSSSEG].d1 = (x&0xFF000000)|((x>>16)&0xFF)|SEGTSS|SEGPL(0)|SEGP;
-
- ptr[0] = sizeof(gdt)-1;
- x = (ulong)m->gdt;
- ptr[1] = x & 0xFFFF;
- ptr[2] = (x>>16) & 0xFFFF;
- lgdt(ptr);
-
- ptr[0] = sizeof(Segdesc)*256-1;
- x = IDTADDR;
- ptr[1] = x & 0xFFFF;
- ptr[2] = (x>>16) & 0xFFFF;
- lidt(ptr);
-
- /* make kernel text unwritable */
- for(x = KTZERO; x < (ulong)etext; x += BY2PG){
- p = mmuwalk(m->pdb, x, 2, 0);
- if(p == nil)
- panic("mmuinit");
- *p &= ~PTEWRITE;
- }
-
- taskswitch(PADDR(m->pdb), (ulong)m + BY2PG);
- ltr(TSSSEL);
-}
-
-
-
-
-ulong*
-mmuwalk(ulong* pdb, ulong va, int level, int create)
-{
- ulong pa, *table;
-
- /*
- * Walk the page-table pointed to by pdb and return a pointer
- * to the entry for virtual address va at the requested level.
- * If the entry is invalid and create isn't requested then bail
- * out early. Otherwise, for the 2nd level walk, allocate a new
- * page-table page and register it in the 1st level.
- */
- table = &pdb[PDX(va)];
- if(!(*table & PTEVALID) && create == 0)
- return 0;
-
- switch(level){
-
- default:
- return 0;
-
- case 1:
- return table;
-
- case 2:
- if(*table & PTESIZE)
- panic("mmuwalk2: va %luX entry %luX\n", va, *table);
- if(!(*table & PTEVALID)){
- pa = PADDR(xspanalloc(BY2PG, BY2PG, 0));
- *table = pa|PTEWRITE|PTEVALID;
- }
- table = KADDR(PPN(*table));
-
- return &table[PTX(va)];
- }
-}
-
-static Lock mmukmaplock;
-
-int
-mmukmapsync(ulong va)
-{
- Mach *mach0;
- ulong entry, *pte;
-
- mach0 = MACHP(0);
-
- ilock(&mmukmaplock);
-
- if((pte = mmuwalk(mach0->pdb, va, 1, 0)) == nil){
- iunlock(&mmukmaplock);
- return 0;
- }
- if(!(*pte & PTESIZE) && mmuwalk(mach0->pdb, va, 2, 0) == nil){
- iunlock(&mmukmaplock);
- return 0;
- }
- entry = *pte;
-
- if(!(m->pdb[PDX(va)] & PTEVALID))
- m->pdb[PDX(va)] = entry;
-
-// if(up && up->mmupdb){
-// ((ulong*)up->mmupdb->va)[PDX(va)] = entry;
-// mmuflushtlb(up->mmupdb->pa);
-// }
-// else
- mmuflushtlb(PADDR(m->pdb));
-
- iunlock(&mmukmaplock);
-
- return 1;
-}
-
-ulong
-mmukmap(ulong pa, ulong va, int size)
-{
- Mach *mach0;
- ulong ova, pae, *table, pgsz, *pte, x;
- int pse, sync;
-
- mach0 = MACHP(0);
- if((mach0->cpuiddx & 0x08) && (getcr4() & 0x10))
- pse = 1;
- else
- pse = 0;
- sync = 0;
-
- pa = PPN(pa);
- if(va == 0)
- va = (ulong)KADDR(pa);
- else
- va = PPN(va);
- ova = va;
-
- pae = pa + size;
- ilock(&mmukmaplock);
- while(pa < pae){
- table = &mach0->pdb[PDX(va)];
- /*
- * Possibly already mapped.
- */
- if(*table & PTEVALID){
- if(*table & PTESIZE){
- /*
- * Big page. Does it fit within?
- * If it does, adjust pgsz so the correct end can be
- * returned and get out.
- * If not, adjust pgsz up to the next 4MB boundary
- * and continue.
- */
- x = PPN(*table);
- if(x != pa)
- panic("mmukmap1: pa %luX entry %luX\n",
- pa, *table);
- x += 4*MB;
- if(pae <= x){
- pa = pae;
- break;
- }
- pgsz = x - pa;
- pa += pgsz;
- va += pgsz;
-
- continue;
- }
- else{
- /*
- * Little page. Walk to the entry.
- * If the entry is valid, set pgsz and continue.
- * If not, make it so, set pgsz, sync and continue.
- */
- pte = mmuwalk(mach0->pdb, va, 2, 0);
- if(pte && *pte & PTEVALID){
- x = PPN(*pte);
- if(x != pa)
- panic("mmukmap2: pa %luX entry %luX\n",
- pa, *pte);
- pgsz = BY2PG;
- pa += pgsz;
- va += pgsz;
- sync++;
-
- continue;
- }
- }
- }
-
- /*
- * Not mapped. Check if it can be mapped using a big page -
- * starts on a 4MB boundary, size >= 4MB and processor can do it.
- * If not a big page, walk the walk, talk the talk.
- * Sync is set.
- *
- * If we're creating a kernel mapping, we know that it will never
- * expire and thus we can set the PTEGLOBAL bit to make the entry
- * persist in the TLB across flushes. If we do add support later for
- * unmapping kernel addresses, see devarch.c for instructions on
- * how to do a full TLB flush.
- */
- if(pse && (pa % (4*MB)) == 0 && (pae >= pa+4*MB)){
- *table = pa|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
- if((va&KZERO) && m->havepge)
- *table |= PTEGLOBAL;
- pgsz = 4*MB;
- }
- else{
- pte = mmuwalk(mach0->pdb, va, 2, 1);
- *pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
- if((va&KZERO) && m->havepge)
- *pte |= PTEGLOBAL;
- pgsz = BY2PG;
- }
- pa += pgsz;
- va += pgsz;
- sync++;
- }
- iunlock(&mmukmaplock);
-
- /*
- * If something was added
- * then need to sync up.
- */
- if(sync)
- mmukmapsync(ova);
-
- return pa;
-}
-
-void*
-vmap(ulong pa, int size)
-{
- pa = upamalloc(pa, size, 0);
- if(pa == 0)
- return nil;
- return KADDR(pa);
-}
-
-void
-vunmap(void *va, int size)
-{
- if(va != nil)
- upafree(PADDR(va), size);
-}
-
-int
-segflush(void*, ulong)
-{
- return 0;
-}
diff --git a/os/pc/mouse.c b/os/pc/mouse.c
deleted file mode 100644
index 49654bad..00000000
--- a/os/pc/mouse.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-/*
- * mouse types
- */
-enum
-{
- Mouseother= 0,
- Mouseserial= 1,
- MousePS2= 2,
-};
-
-static int mousetype;
-
-/*
- * ps/2 mouse message is three bytes
- *
- * byte 0 - 0 0 SDY SDX 1 M R L
- * byte 1 - DX
- * byte 2 - DY
- *
- * shift & left button is the same as middle button
- */
-static void
-ps2mouseputc(int c, int shift)
-{
- static short msg[3];
- static int nb;
- static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 };
- int buttons, dx, dy;
-
- /*
- * check byte 0 for consistency
- */
- if(nb==0 && (c&0xc8)!=0x08)
- return;
-
- msg[nb] = c;
- if(++nb == 3){
- nb = 0;
- if(msg[0] & 0x10)
- msg[1] |= 0xFF00;
- if(msg[0] & 0x20)
- msg[2] |= 0xFF00;
-
- buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
- dx = msg[1];
- dy = -msg[2];
- mousetrack(buttons, dx, dy, 1);
- }
- return;
-}
-
-/*
- * set up a ps2 mouse
- */
-static void
-ps2mouse(void)
-{
- if(mousetype == MousePS2)
- return;
-
- i8042auxenable(ps2mouseputc);
- /* make mouse streaming, enabled */
- i8042auxcmd(0xEA);
- i8042auxcmd(0xF4);
-
- mousetype = MousePS2;
-}
-
-void
-ps2mouselink(void)
-{
- /*
- * hack
- */
- ps2mouse();
-}
diff --git a/os/pc/mp.c b/os/pc/mp.c
deleted file mode 100644
index f16fab91..00000000
--- a/os/pc/mp.c
+++ /dev/null
@@ -1,815 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-
-#include "mp.h"
-#include "apbootstrap.h"
-
-static Bus* mpbus;
-static Bus* mpbuslast;
-static int mpisabus = -1;
-static int mpeisabus = -1;
-extern int i8259elcr; /* mask of level-triggered interrupts */
-static Apic mpapic[MaxAPICNO+1];
-static int machno2apicno[MaxAPICNO+1]; /* inverse map: machno -> APIC ID */
-static Lock mprdthilock;
-static int mprdthi;
-static Ref mpvnoref; /* unique vector assignment */
-static int mpmachno = 1;
-
-static char* buses[] = {
- "CBUSI ",
- "CBUSII",
- "EISA ",
- "FUTURE",
- "INTERN",
- "ISA ",
- "MBI ",
- "MBII ",
- "MCA ",
- "MPI ",
- "MPSA ",
- "NUBUS ",
- "PCI ",
- "PCMCIA",
- "TC ",
- "VL ",
- "VME ",
- "XPRESS",
- 0,
-};
-
-static Apic*
-mkprocessor(PCMPprocessor* p)
-{
- Apic *apic;
-
- if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO)
- return 0;
-
- apic = &mpapic[p->apicno];
- apic->type = PcmpPROCESSOR;
- apic->apicno = p->apicno;
- apic->flags = p->flags;
- apic->lintr[0] = ApicIMASK;
- apic->lintr[1] = ApicIMASK;
-
- if(p->flags & PcmpBP){
- machno2apicno[0] = p->apicno;
- apic->machno = 0;
- }
- else{
- machno2apicno[mpmachno] = p->apicno;
- apic->machno = mpmachno;
- mpmachno++;
- }
-
- return apic;
-}
-
-static Bus*
-mkbus(PCMPbus* p)
-{
- Bus *bus;
- int i;
-
- for(i = 0; buses[i]; i++){
- if(strncmp(buses[i], p->string, sizeof(p->string)) == 0)
- break;
- }
- if(buses[i] == 0)
- return 0;
-
- bus = xalloc(sizeof(Bus));
- if(mpbus)
- mpbuslast->next = bus;
- else
- mpbus = bus;
- mpbuslast = bus;
-
- bus->type = i;
- bus->busno = p->busno;
- if(bus->type == BusEISA){
- bus->po = PcmpLOW;
- bus->el = PcmpLEVEL;
- if(mpeisabus != -1)
- print("mkbus: more than one EISA bus\n");
- mpeisabus = bus->busno;
- }
- else if(bus->type == BusPCI){
- bus->po = PcmpLOW;
- bus->el = PcmpLEVEL;
- }
- else if(bus->type == BusISA){
- bus->po = PcmpHIGH;
- bus->el = PcmpEDGE;
- if(mpisabus != -1)
- print("mkbus: more than one ISA bus\n");
- mpisabus = bus->busno;
- }
- else{
- bus->po = PcmpHIGH;
- bus->el = PcmpEDGE;
- }
-
- return bus;
-}
-
-static Bus*
-mpgetbus(int busno)
-{
- Bus *bus;
-
- for(bus = mpbus; bus; bus = bus->next){
- if(bus->busno == busno)
- return bus;
- }
- print("mpgetbus: can't find bus %d\n", busno);
-
- return 0;
-}
-
-static Apic*
-mkioapic(PCMPioapic* p)
-{
- Apic *apic;
-
- if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO)
- return 0;
-
- /*
- * Map the I/O APIC.
- */
- if(mmukmap(p->addr, 0, 1024) == 0)
- return 0;
-
- apic = &mpapic[p->apicno];
- apic->type = PcmpIOAPIC;
- apic->apicno = p->apicno;
- apic->addr = KADDR(p->addr);
- apic->flags = p->flags;
-
- return apic;
-}
-
-static Aintr*
-mkiointr(PCMPintr* p)
-{
- Bus *bus;
- Aintr *aintr;
-
- /*
- * According to the MultiProcessor Specification, a destination
- * I/O APIC of 0xFF means the signal is routed to all I/O APICs.
- * It's unclear how that can possibly be correct so treat it as
- * an error for now.
- */
- if(p->apicno == 0xFF)
- return 0;
- if((bus = mpgetbus(p->busno)) == 0)
- return 0;
-
- aintr = xalloc(sizeof(Aintr));
- aintr->intr = p;
- aintr->apic = &mpapic[p->apicno];
- aintr->next = bus->aintr;
- bus->aintr = aintr;
-
- return aintr;
-}
-
-static int
-mpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/)
-{
- int el, po, v;
-
- /*
- * Parse an I/O or Local APIC interrupt table entry and
- * return the encoded vector.
- */
- v = vno;
-
- po = intr->flags & PcmpPOMASK;
- el = intr->flags & PcmpELMASK;
-
- switch(intr->intr){
-
- default: /* PcmpINT */
- v |= ApicLOWEST;
- break;
-
- case PcmpNMI:
- v |= ApicNMI;
- po = PcmpHIGH;
- el = PcmpEDGE;
- break;
-
- case PcmpSMI:
- v |= ApicSMI;
- break;
-
- case PcmpExtINT:
- v |= ApicExtINT;
- /*
- * The AMI Goliath doesn't boot successfully with it's LINTR0
- * entry which decodes to low+level. The PPro manual says ExtINT
- * should be level, whereas the Pentium is edge. Setting the
- * Goliath to edge+high seems to cure the problem. Other PPro
- * MP tables (e.g. ASUS P/I-P65UP5 have a entry which decodes
- * to edge+high, so who knows.
- * Perhaps it would be best just to not set an ExtINT entry at
- * all, it shouldn't be needed for SMP mode.
- */
- po = PcmpHIGH;
- el = PcmpEDGE;
- break;
- }
-
- /*
- */
- if(bus->type == BusEISA && !po && !el /*&& !(i8259elcr & (1<<irq))*/){
- po = PcmpHIGH;
- el = PcmpEDGE;
- }
- if(!po)
- po = bus->po;
- if(po == PcmpLOW)
- v |= ApicLOW;
- else if(po != PcmpHIGH){
- print("mpintrinit: bad polarity 0x%uX\n", po);
- return ApicIMASK;
- }
-
- if(!el)
- el = bus->el;
- if(el == PcmpLEVEL)
- v |= ApicLEVEL;
- else if(el != PcmpEDGE){
- print("mpintrinit: bad trigger 0x%uX\n", el);
- return ApicIMASK;
- }
-
- return v;
-}
-
-static int
-mklintr(PCMPintr* p)
-{
- Apic *apic;
- Bus *bus;
- int intin, v;
-
- /*
- * The offsets of vectors for LINT[01] are known to be
- * 0 and 1 from the local APIC vector space at VectorLAPIC.
- */
- if((bus = mpgetbus(p->busno)) == 0)
- return 0;
- intin = p->intin;
-
- /*
- * Pentium Pros have problems if LINT[01] are set to ExtINT
- * so just bag it, SMP mode shouldn't need ExtINT anyway.
- */
- if(p->intr == PcmpExtINT || p->intr == PcmpNMI)
- v = ApicIMASK;
- else
- v = mpintrinit(bus, p, VectorLAPIC+intin, p->irq);
-
- if(p->apicno == 0xFF){
- for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){
- if((apic->flags & PcmpEN)
- && apic->type == PcmpPROCESSOR)
- apic->lintr[intin] = v;
- }
- }
- else{
- apic = &mpapic[p->apicno];
- if((apic->flags & PcmpEN) && apic->type == PcmpPROCESSOR)
- apic->lintr[intin] = v;
- }
-
- return v;
-}
-
-static void
-checkmtrr(void)
-{
- int i, vcnt;
- Mach *mach0;
-
- /*
- * If there are MTRR registers, snarf them for validation.
- */
- if(!(m->cpuiddx & 0x1000))
- return;
-
- rdmsr(0x0FE, &m->mtrrcap);
- rdmsr(0x2FF, &m->mtrrdef);
- if(m->mtrrcap & 0x0100){
- rdmsr(0x250, &m->mtrrfix[0]);
- rdmsr(0x258, &m->mtrrfix[1]);
- rdmsr(0x259, &m->mtrrfix[2]);
- for(i = 0; i < 8; i++)
- rdmsr(0x268+i, &m->mtrrfix[(i+3)]);
- }
- vcnt = m->mtrrcap & 0x00FF;
- if(vcnt > nelem(m->mtrrvar))
- vcnt = nelem(m->mtrrvar);
- for(i = 0; i < vcnt; i++)
- rdmsr(0x200+i, &m->mtrrvar[i]);
-
- /*
- * If not the bootstrap processor, compare.
- */
- if(m->machno == 0)
- return;
-
- mach0 = MACHP(0);
- if(mach0->mtrrcap != m->mtrrcap)
- print("mtrrcap%d: %lluX %lluX\n",
- m->machno, mach0->mtrrcap, m->mtrrcap);
- if(mach0->mtrrdef != m->mtrrdef)
- print("mtrrdef%d: %lluX %lluX\n",
- m->machno, mach0->mtrrdef, m->mtrrdef);
- for(i = 0; i < 11; i++){
- if(mach0->mtrrfix[i] != m->mtrrfix[i])
- print("mtrrfix%d: i%d: %lluX %lluX\n",
- m->machno, i, mach0->mtrrfix[i], m->mtrrfix[i]);
- }
- for(i = 0; i < vcnt; i++){
- if(mach0->mtrrvar[i] != m->mtrrvar[i])
- print("mtrrvar%d: i%d: %lluX %lluX\n",
- m->machno, i, mach0->mtrrvar[i], m->mtrrvar[i]);
- }
-}
-
-static void
-squidboy(Apic* apic)
-{
-// iprint("Hello Squidboy\n");
-
- machinit();
- mmuinit();
-
- cpuidentify();
- cpuidprint();
- checkmtrr();
-
- lock(&mprdthilock);
- mprdthi |= (1<<apic->apicno)<<24;
- unlock(&mprdthilock);
-
- lapicinit(apic);
- lapiconline();
- syncclock();
- timersinit();
-
- fpoff();
-
- lock(&active);
- active.machs |= 1<<m->machno;
- unlock(&active);
-
- while(!active.thunderbirdsarego)
- microdelay(100);
-
- schedinit();
-}
-
-static void
-mpstartap(Apic* apic)
-{
- ulong *apbootp, *pdb, *pte;
- Mach *mach, *mach0;
- int i, machno;
- uchar *p;
-
- mach0 = MACHP(0);
-
- /*
- * Initialise the AP page-tables and Mach structure. The page-tables
- * are the same as for the bootstrap processor with the exception of
- * the PTE for the Mach structure.
- * Xspanalloc will panic if an allocation can't be made.
- */
- p = xspanalloc(4*BY2PG, BY2PG, 0);
- pdb = (ulong*)p;
- memmove(pdb, mach0->pdb, BY2PG);
- p += BY2PG;
-
- if((pte = mmuwalk(pdb, MACHADDR, 1, 0)) == nil)
- return;
- memmove(p, KADDR(PPN(*pte)), BY2PG);
- *pte = PADDR(p)|PTEWRITE|PTEVALID;
- if(mach0->havepge)
- *pte |= PTEGLOBAL;
- p += BY2PG;
-
- mach = (Mach*)p;
- if((pte = mmuwalk(pdb, MACHADDR, 2, 0)) == nil)
- return;
- *pte = PADDR(mach)|PTEWRITE|PTEVALID;
- if(mach0->havepge)
- *pte |= PTEGLOBAL;
- p += BY2PG;
-
- machno = apic->machno;
- MACHP(machno) = mach;
- mach->machno = machno;
- mach->pdb = pdb;
- mach->gdt = (Segdesc*)p; /* filled by mmuinit */
-
- /*
- * Tell the AP where its kernel vector and pdb are.
- * The offsets are known in the AP bootstrap code.
- */
- apbootp = (ulong*)(APBOOTSTRAP+0x08);
- *apbootp++ = (ulong)squidboy;
- *apbootp++ = PADDR(pdb);
- *apbootp = (ulong)apic;
-
- /*
- * Universal Startup Algorithm.
- */
- p = KADDR(0x467);
- *p++ = PADDR(APBOOTSTRAP);
- *p++ = PADDR(APBOOTSTRAP)>>8;
- i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
- *p++ = i;
- *p = i>>8;
-
- nvramwrite(0x0F, 0x0A);
- lapicstartap(apic, PADDR(APBOOTSTRAP));
- for(i = 0; i < 1000; i++){
- lock(&mprdthilock);
- if(mprdthi & ((1<<apic->apicno)<<24)){
- unlock(&mprdthilock);
- break;
- }
- unlock(&mprdthilock);
- delay(10);
- }
- nvramwrite(0x0F, 0x00);
-}
-
-void
-mpinit(void)
-{
- int ncpu;
- char *cp;
- PCMP *pcmp;
- uchar *e, *p;
- Apic *apic, *bpapic;
-
- i8259init();
- syncclock();
-
- if(_mp_ == 0)
- return;
- pcmp = KADDR(_mp_->physaddr);
-
- /*
- * Map the local APIC.
- */
- if(mmukmap(pcmp->lapicbase, 0, 1024) == 0)
- return;
-
- bpapic = nil;
-
- /*
- * Run through the table saving information needed for starting
- * application processors and initialising any I/O APICs. The table
- * is guaranteed to be in order such that only one pass is necessary.
- */
- p = ((uchar*)pcmp)+sizeof(PCMP);
- e = ((uchar*)pcmp)+pcmp->length;
- while(p < e) switch(*p){
-
- default:
- print("mpinit: unknown PCMP type 0x%uX (e-p 0x%luX)\n",
- *p, e-p);
- while(p < e){
- print("%uX ", *p);
- p++;
- }
- break;
-
- case PcmpPROCESSOR:
- if(apic = mkprocessor((PCMPprocessor*)p)){
- /*
- * Must take a note of bootstrap processor APIC
- * now as it will be needed in order to start the
- * application processors later and there's no
- * guarantee that the bootstrap processor appears
- * first in the table before the others.
- */
- apic->addr = KADDR(pcmp->lapicbase);
- if(apic->flags & PcmpBP)
- bpapic = apic;
- }
- p += sizeof(PCMPprocessor);
- continue;
-
- case PcmpBUS:
- mkbus((PCMPbus*)p);
- p += sizeof(PCMPbus);
- continue;
-
- case PcmpIOAPIC:
- if(apic = mkioapic((PCMPioapic*)p))
- ioapicinit(apic, ((PCMPioapic*)p)->apicno);
- p += sizeof(PCMPioapic);
- continue;
-
- case PcmpIOINTR:
- mkiointr((PCMPintr*)p);
- p += sizeof(PCMPintr);
- continue;
-
- case PcmpLINTR:
- mklintr((PCMPintr*)p);
- p += sizeof(PCMPintr);
- continue;
- }
-
- /*
- * No bootstrap processor, no need to go further.
- */
- if(bpapic == 0)
- return;
-
- lapicinit(bpapic);
- lock(&mprdthilock);
- mprdthi |= (1<<bpapic->apicno)<<24;
- unlock(&mprdthilock);
-
- /*
- * These interrupts are local to the processor
- * and do not appear in the I/O APIC so it is OK
- * to set them now.
- */
- intrenable(IrqTIMER, lapicclock, 0, BUSUNKNOWN, "clock");
- intrenable(IrqERROR, lapicerror, 0, BUSUNKNOWN, "lapicerror");
- intrenable(IrqSPURIOUS, lapicspurious, 0, BUSUNKNOWN, "lapicspurious");
- lapiconline();
-
- checkmtrr();
-
- /*
- * Initialise the application processors.
- */
- if(cp = getconf("*ncpu")){
- ncpu = strtol(cp, 0, 0);
- if(ncpu < 1)
- ncpu = 1;
- }
- else
- ncpu = MaxAPICNO;
- memmove((void*)APBOOTSTRAP, apbootstrap, sizeof(apbootstrap));
- for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){
- if(ncpu <= 1)
- break;
- if((apic->flags & (PcmpBP|PcmpEN)) == PcmpEN
- && apic->type == PcmpPROCESSOR){
- mpstartap(apic);
- conf.nmach++;
- ncpu--;
- }
- }
-
- /*
- * we don't really know the number of processors till
- * here.
- *
- * set conf.copymode here if nmach > 1.
- * Should look for an ExtINT line and enable it.
- */
- if(X86FAMILY(m->cpuidax) == 3 || conf.nmach > 1)
- conf.copymode = 1;
-}
-
-static int
-mpintrenablex(Vctl* v, int tbdf)
-{
- Bus *bus;
- Aintr *aintr;
- Apic *apic;
- Pcidev *pcidev;
- int bno, dno, irq, lo, n, type, vno;
-
- /*
- * Find the bus.
- */
- type = BUSTYPE(tbdf);
- bno = BUSBNO(tbdf);
- dno = BUSDNO(tbdf);
- n = 0;
- for(bus = mpbus; bus != nil; bus = bus->next){
- if(bus->type != type)
- continue;
- if(n == bno)
- break;
- n++;
- }
- if(bus == nil){
- print("ioapicirq: can't find bus type %d\n", type);
- return -1;
- }
-
- /*
- * For PCI devices the interrupt pin (INT[ABCD]) and device
- * number are encoded into the entry irq field, so create something
- * to match on. The interrupt pin used by the device has to be
- * obtained from the PCI config space.
- */
- if(bus->type == BusPCI){
- pcidev = pcimatchtbdf(tbdf);
- if(pcidev != nil && (n = pcicfgr8(pcidev, PciINTP)) != 0)
- irq = (dno<<2)|(n-1);
- else
- irq = -1;
- //print("pcidev %uX: irq %uX v->irq %uX\n", tbdf, irq, v->irq);
- }
- else
- irq = v->irq;
-
- /*
- * Find a matching interrupt entry from the list of interrupts
- * attached to this bus.
- */
- for(aintr = bus->aintr; aintr; aintr = aintr->next){
- if(aintr->intr->irq != irq)
- continue;
-
- /*
- * Check if already enabled. Multifunction devices may share
- * INT[A-D]# so, if already enabled, check the polarity matches
- * and the trigger is level.
- *
- * Should check the devices differ only in the function number,
- * but that can wait for the planned enable/disable rewrite.
- * The RDT read here is safe for now as currently interrupts
- * are never disabled once enabled.
- */
- apic = aintr->apic;
- ioapicrdtr(apic, aintr->intr->intin, 0, &lo);
- if(!(lo & ApicIMASK)){
- vno = lo & 0xFF;
- n = mpintrinit(bus, aintr->intr, vno, v->irq);
- n |= ApicLOGICAL;
- if(n != lo || !(n & ApicLEVEL)){
- print("mpintrenable: multiple botch irq%d, tbdf %uX, lo %8.8uX, n %8.8uX\n",
- v->irq, tbdf, lo, n);
- return -1;
- }
-
- v->isr = lapicisr;
- v->eoi = lapiceoi;
-
- return vno;
- }
-
- /*
- * With the APIC a unique vector can be assigned to each
- * request to enable an interrupt. There are two reasons this
- * is a good idea:
- * 1) to prevent lost interrupts, no more than 2 interrupts
- * should be assigned per block of 16 vectors (there is an
- * in-service entry and a holding entry for each priority
- * level and there is one priority level per block of 16
- * interrupts).
- * 2) each input pin on the IOAPIC will receive a different
- * vector regardless of whether the devices on that pin use
- * the same IRQ as devices on another pin.
- */
- vno = VectorAPIC + (incref(&mpvnoref)-1)*8;
- if(vno > MaxVectorAPIC){
- print("mpintrenable: vno %d, irq %d, tbdf %uX\n",
- vno, v->irq, tbdf);
- return -1;
- }
- lo = mpintrinit(bus, aintr->intr, vno, v->irq);
- //print("lo 0x%uX: busno %d intr %d vno %d irq %d elcr 0x%uX\n",
- // lo, bus->busno, aintr->intr->irq, vno,
- // v->irq, i8259elcr);
- if(lo & ApicIMASK)
- return -1;
- lo |= ApicLOGICAL;
-
- if((apic->flags & PcmpEN) && apic->type == PcmpIOAPIC){
- lock(&mprdthilock);
- ioapicrdtw(apic, aintr->intr->intin, mprdthi, lo);
- unlock(&mprdthilock);
- }
- //else
- // print("lo not enabled 0x%uX %d\n",
- // apic->flags, apic->type);
-
- v->isr = lapicisr;
- v->eoi = lapiceoi;
-
- return vno;
- }
-
- return -1;
-}
-
-int
-mpintrenable(Vctl* v)
-{
- int irq, tbdf, vno;
-
- /*
- * If the bus is known, try it.
- * BUSUNKNOWN is given both by [E]ISA devices and by
- * interrupts local to the processor (local APIC, coprocessor
- * breakpoint and page-fault).
- */
- tbdf = v->tbdf;
- if(tbdf != BUSUNKNOWN && (vno = mpintrenablex(v, tbdf)) != -1)
- return vno;
-
- irq = v->irq;
- if(irq >= IrqLINT0 && irq <= MaxIrqLAPIC){
- if(irq != IrqSPURIOUS)
- v->isr = lapiceoi;
- return VectorPIC+irq;
- }
- if(irq < 0 || irq > MaxIrqPIC){
- print("mpintrenable: irq %d out of range\n", irq);
- return -1;
- }
-
- /*
- * Either didn't find it or have to try the default buses
- * (ISA and EISA). This hack is due to either over-zealousness
- * or laziness on the part of some manufacturers.
- *
- * The MP configuration table on some older systems
- * (e.g. ASUS PCI/E-P54NP4) has an entry for the EISA bus
- * but none for ISA. It also has the interrupt type and
- * polarity set to 'default for this bus' which wouldn't
- * be compatible with ISA.
- */
- if(mpeisabus != -1){
- vno = mpintrenablex(v, MKBUS(BusEISA, 0, 0, 0));
- if(vno != -1)
- return vno;
- }
- if(mpisabus != -1){
- vno = mpintrenablex(v, MKBUS(BusISA, 0, 0, 0));
- if(vno != -1)
- return vno;
- }
-
- return -1;
-}
-
-static Lock mpshutdownlock;
-
-void
-mpshutdown(void)
-{
- /*
- * To be done...
- */
- if(!canlock(&mpshutdownlock)){
- /*
- * If this processor received the CTRL-ALT-DEL from
- * the keyboard, acknowledge it. Send an INIT to self.
- */
-#ifdef FIXTHIS
- if(lapicisr(VectorKBD))
- lapiceoi(VectorKBD);
-#endif /* FIX THIS */
- idle();
- }
-
- print("apshutdown: active = 0x%2.2uX\n", active.machs);
- delay(1000);
- splhi();
-
- /*
- * INIT all excluding self.
- */
- lapicicrw(0, 0x000C0000|ApicINIT);
-
-#ifdef notdef
- /*
- * Often the BIOS hangs during restart if a conventional 8042
- * warm-boot sequence is tried. The following is Intel specific and
- * seems to perform a cold-boot, but at least it comes back.
- */
- *(ushort*)KADDR(0x472) = 0x1234; /* BIOS warm-boot flag */
- outb(0xCF9, 0x02);
- outb(0xCF9, 0x06);
-#else
- pcireset();
- i8042reset();
-#endif /* notdef */
-}
diff --git a/os/pc/mp.h b/os/pc/mp.h
deleted file mode 100644
index 9195c9e9..00000000
--- a/os/pc/mp.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * MultiProcessor Specification Version 1.[14].
- */
-typedef struct { /* floating pointer */
- uchar signature[4]; /* "_MP_" */
- long physaddr; /* physical address of MP configuration table */
- uchar length; /* 1 */
- uchar specrev; /* [14] */
- uchar checksum; /* all bytes must add up to 0 */
- uchar type; /* MP system configuration type */
- uchar imcrp;
- uchar reserved[3];
-} _MP_;
-
-typedef struct { /* configuration table header */
- uchar signature[4]; /* "PCMP" */
- ushort length; /* total table length */
- uchar version; /* [14] */
- uchar checksum; /* all bytes must add up to 0 */
- uchar product[20]; /* product id */
- ulong oemtable; /* OEM table pointer */
- ushort oemlength; /* OEM table length */
- ushort entry; /* entry count */
- ulong lapicbase; /* address of local APIC */
- ushort xlength; /* extended table length */
- uchar xchecksum; /* extended table checksum */
- uchar reserved;
-} PCMP;
-
-typedef struct { /* processor table entry */
- uchar type; /* entry type (0) */
- uchar apicno; /* local APIC id */
- uchar version; /* local APIC verison */
- uchar flags; /* CPU flags */
- uchar signature[4]; /* CPU signature */
- ulong feature; /* feature flags from CPUID instruction */
- uchar reserved[8];
-} PCMPprocessor;
-
-typedef struct { /* bus table entry */
- uchar type; /* entry type (1) */
- uchar busno; /* bus id */
- char string[6]; /* bus type string */
-} PCMPbus;
-
-typedef struct { /* I/O APIC table entry */
- uchar type; /* entry type (2) */
- uchar apicno; /* I/O APIC id */
- uchar version; /* I/O APIC version */
- uchar flags; /* I/O APIC flags */
- ulong addr; /* I/O APIC address */
-} PCMPioapic;
-
-typedef struct { /* interrupt table entry */
- uchar type; /* entry type ([34]) */
- uchar intr; /* interrupt type */
- ushort flags; /* interrupt flag */
- uchar busno; /* source bus id */
- uchar irq; /* source bus irq */
- uchar apicno; /* destination APIC id */
- uchar intin; /* destination APIC [L]INTIN# */
-} PCMPintr;
-
-typedef struct { /* system address space mapping entry */
- uchar type; /* entry type (128) */
- uchar length; /* of this entry (20) */
- uchar busno; /* bus id */
- uchar addrtype;
- ulong addrbase[2];
- ulong addrlength[2];
-} PCMPsasm;
-
-typedef struct { /* bus hierarchy descriptor entry */
- uchar type; /* entry type (129) */
- uchar length; /* of this entry (8) */
- uchar busno; /* bus id */
- uchar info; /* bus info */
- uchar parent; /* parent bus */
- uchar reserved[3];
-} PCMPhierarchy;
-
-typedef struct { /* compatibility bus address space modifier entry */
- uchar type; /* entry type (130) */
- uchar length; /* of this entry (8) */
- uchar busno; /* bus id */
- uchar modifier; /* address modifier */
- ulong range; /* predefined range list */
-} PCMPcbasm;
-
-enum { /* table entry types */
- PcmpPROCESSOR = 0x00, /* one entry per processor */
- PcmpBUS = 0x01, /* one entry per bus */
- PcmpIOAPIC = 0x02, /* one entry per I/O APIC */
- PcmpIOINTR = 0x03, /* one entry per bus interrupt source */
- PcmpLINTR = 0x04, /* one entry per system interrupt source */
-
- PcmpSASM = 0x80,
- PcmpHIERARCHY = 0x81,
- PcmpCBASM = 0x82,
-
- /* PCMPprocessor and PCMPioapic flags */
- PcmpEN = 0x01, /* enabled */
- PcmpBP = 0x02, /* bootstrap processor */
-
- /* PCMPiointr and PCMPlintr flags */
- PcmpPOMASK = 0x03, /* polarity conforms to specifications of bus */
- PcmpHIGH = 0x01, /* active high */
- PcmpLOW = 0x03, /* active low */
- PcmpELMASK = 0x0C, /* trigger mode of APIC input signals */
- PcmpEDGE = 0x04, /* edge-triggered */
- PcmpLEVEL = 0x0C, /* level-triggered */
-
- /* PCMPiointr and PCMPlintr interrupt type */
- PcmpINT = 0x00, /* vectored interrupt from APIC Rdt */
- PcmpNMI = 0x01, /* non-maskable interrupt */
- PcmpSMI = 0x02, /* system management interrupt */
- PcmpExtINT = 0x03, /* vectored interrupt from external PIC */
-
- /* PCMPsasm addrtype */
- PcmpIOADDR = 0x00, /* I/O address */
- PcmpMADDR = 0x01, /* memory address */
- PcmpPADDR = 0x02, /* prefetch address */
-
- /* PCMPhierarchy info */
- PcmpSD = 0x01, /* subtractive decode bus */
-
- /* PCMPcbasm modifier */
- PcmpPR = 0x01, /* predefined range list */
-};
-
-/*
- * Condensed form of the MP Configuration Table.
- * This is created during a single pass through the MP Configuration
- * table.
- */
-typedef struct Aintr Aintr;
-typedef struct Bus Bus;
-typedef struct Apic Apic;
-
-typedef struct Bus {
- uchar type;
- uchar busno;
- uchar po;
- uchar el;
-
- Aintr* aintr; /* interrupts tied to this bus */
- Bus* next;
-} Bus;
-
-typedef struct Aintr {
- PCMPintr* intr;
- Apic* apic;
- Aintr* next;
-};
-
-typedef struct Apic {
- int type;
- int apicno;
- ulong* addr; /* register base address */
- int flags; /* PcmpBP|PcmpEN */
-
- Lock; /* I/O APIC: register access */
- int mre; /* I/O APIC: maximum redirection entry */
-
- int lintr[2]; /* Local APIC */
- int machno;
-} Apic;
-
-enum {
- MaxAPICNO = 31,
-};
-
-enum { /* I/O APIC registers */
- IoapicID = 0x00, /* ID */
- IoapicVER = 0x01, /* version */
- IoapicARB = 0x02, /* arbitration ID */
- IoapicRDT = 0x10, /* redirection table */
-};
-
-/*
- * Common bits for
- * I/O APIC Redirection Table Entry;
- * Local APIC Local Interrupt Vector Table;
- * Local APIC Inter-Processor Interrupt;
- * Local APIC Timer Vector Table.
- */
-enum {
- ApicFIXED = 0x00000000, /* [10:8] Delivery Mode */
- ApicLOWEST = 0x00000100, /* Lowest priority */
- ApicSMI = 0x00000200, /* System Management Interrupt */
- ApicRR = 0x00000300, /* Remote Read */
- ApicNMI = 0x00000400,
- ApicINIT = 0x00000500, /* INIT/RESET */
- ApicSTARTUP = 0x00000600, /* Startup IPI */
- ApicExtINT = 0x00000700,
-
- ApicPHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */
- ApicLOGICAL = 0x00000800,
-
- ApicDELIVS = 0x00001000, /* [12] Delivery Status (RO) */
- ApicHIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */
- ApicLOW = 0x00002000,
- ApicRemoteIRR = 0x00004000, /* [14] Remote IRR (RO) */
- ApicEDGE = 0x00000000, /* [15] Trigger Mode (RW) */
- ApicLEVEL = 0x00008000,
- ApicIMASK = 0x00010000, /* [16] Interrupt Mask */
-};
-
-extern void ioapicrdtr(Apic*, int, int*, int*);
-extern void ioapicrdtw(Apic*, int, int, int);
-extern void ioapicinit(Apic*, int);
-extern void lapiconline(void);
-extern void lapicinit(Apic*);
-extern void lapicstartap(Apic*, int);
-extern void lapicerror(Ureg*, void*);
-extern void lapicspurious(Ureg*, void*);
-extern int lapicisr(int);
-extern int lapiceoi(int);
-extern void lapicicrw(int, int);
-
-extern void mpinit(void);
-extern void mpshutdown(void);
-extern int mpintrenable(Vctl*);
-
-extern _MP_ *_mp_;
diff --git a/os/pc/pc b/os/pc/pc
deleted file mode 100644
index 56d82a89..00000000
--- a/os/pc/pc
+++ /dev/null
@@ -1,139 +0,0 @@
-dev
- root
- cons
- arch
- env
- mnt
- pipe
- prog
- rtc
- srv
- dup
- ssl
- cap
-
- draw screen vga vgax cga
- pointer
- vga
-
- ip bootp ip ipv6 ipaux iproute arp netlog ptclbsum386 iprouter plan9 nullmedium pktmedium
- ether netif netaux ethermedium
-
-# ata
- audio dma
- uart
-# floppy dma
- tinyfs
-# mouse
-# dbg x86break
-ip
- tcp
- udp
-# rudp
-# igmp
- ipifc
- icmp
- icmp6
- ipmux
-lib
- interp
- keyring
- draw
- memlayer
- memdraw
- tk
- sec
- mp
- math
- kern
-
-link
- ether2114x pci
-# ether82557 pci
- ether83815 pci
- etherelnk3 pci
- ps2mouse
- ethermedium
-# pppmedium ppp compress
-
-misc
- vgas3 +cur vgasavage
- vgamach64xx
- cga
- uarti8250
-
-mod
- sys
- draw
- tk
- keyring
- math
-
-init
- wminit
-
-code
- int kernel_pool_pcnt = 10;
- int main_pool_pcnt = 40;
- int heap_pool_pcnt = 20;
- int image_pool_pcnt = 40;
- int cflag=0;
- int swcursor=0;
- int consoleprint=0;
-
-port
- alarm
- alloc
- allocb
- chan
- dev
- dial
- dis
- discall
- exception
- exportfs
- inferno
- latin1
- nocache
- nodynld
- parse
- pgrp
- print
- proc
- qio
- qlock
- random
- sysfile
- taslock
- xalloc
-
-root
- /chan /
- /dev /
- /dis
- /env /
- /fd /
- /n
- /n/remote
- /net /
- /nvfs /
- /prog /
- /dis/lib
- /dis/svc
- /dis/wm
- /osinit.dis
- /dis/sh.dis
- /dis/ls.dis
- /dis/cat.dis
- /dis/bind.dis
- /dis/mount.dis
- /dis/pwd.dis
- /dis/echo.dis
- /dis/cd.dis
- /dis/lib/bufio.dis
- /dis/lib/string.dis
- /dis/lib/readdir.dis
- /dis/lib/workdir.dis
- /dis/lib/daytime.dis
- /dis/lib/auth.dis
- /dis/lib/ssl.dis
diff --git a/os/pc/pc4e b/os/pc/pc4e
deleted file mode 100644
index 3bb235e4..00000000
--- a/os/pc/pc4e
+++ /dev/null
@@ -1,148 +0,0 @@
-dev
- root
- cons
- arch
- pnp pci
- env
- mnt
- pipe
- prog
- rtc
- srv
- dup
- ssl
- cap
- draw
- ip bootp ip ipv6 ipaux iproute arp netlog ptclbsum386 iprouter plan9 nullmedium pktmedium netaux
- ether netif netaux ethermedium
-
-# ata
-# audio
- uart
- floppy dma
-# tinyfs
-# mouse
-# dbg x86break
-ip
- tcp
- udp
-# rudp
-# igmp
- ipifc
- icmp
- icmp6
- ipmux
-lib
- interp
- keyring
- draw
- memlayer
- memdraw
- tk
- sec
- mp
- math
- kern
-
-link
-# ether2114x pci
-# ether82557 pci
- ether83815 pci
- etherelnk3 pci
-# ps2mouse
-# pppmedium ppp compress
- ethermedium
-
-misc
- cgamemscr
-# vgaclgd542x
-# vgas3
-# vgamach64ct
- uarti8250
-
-mod
- sys
- draw
- tk
- keyring
- crypt
- ipints
-
- math
-
-init
- i4e
-
-code
- int kernel_pool_pcnt = 10;
- int main_pool_pcnt = 40;
- int heap_pool_pcnt = 20;
- int image_pool_pcnt = 40;
- int cflag=0;
- int swcursor=0;
- int consoleprint=1;
-
-port
- alarm
- alloc
- allocb
- chan
- dev
- dial
- dis
- discall
- exception
- exportfs
- inferno
- latin1
- nocache
- nodynld
- parse
- pgrp
- print
- proc
- qio
- qlock
- random
- sysfile
- taslock
- xalloc
-
-root
- /chan /
- /dev /
- /dis /
- /env /
- /fd /
- /n
- /n/remote
- /net /
- /net.alt /
- /nvfs /
- /prog /
- /dis/lib
- /dis/svc
- /dis/wm
- /osinit.dis
- /dis/sh.dis
- /dis/ls.dis
- /dis/cat.dis
- /dis/bind.dis
- /dis/mount.dis
- /dis/pwd.dis
- /dis/echo.dis
- /dis/cd.dis
- /dis/lib/arg.dis
- /dis/lib/bufio.dis
- /dis/lib/dhcpclient.dis
- /dis/lib/filepat.dis
- /dis/lib/ip.dis
- /dis/lib/string.dis
- /dis/lib/readdir.dis
- /dis/lib/workdir.dis
- /dis/lib/daytime.dis
- /dis/lib/auth.dis
- /dis/lib/ssl.dis
- /keydb /
- /keydb/mutual /usr/i4e/keyring/mutual
- /keydb/spree /usr/i4e/keyring/spree
diff --git a/os/pc/pcdisk b/os/pc/pcdisk
deleted file mode 100644
index 743286b3..00000000
--- a/os/pc/pcdisk
+++ /dev/null
@@ -1,157 +0,0 @@
-dev
- root
- cons
- arch
- env
- mnt
- pipe
- prog
- rtc
- srv
- dup
- ssl
- cap
-
- ip bootp ip ipv6 ipaux iproute arp netlog ptclbsum386 iprouter plan9 nullmedium pktmedium
- ether netif netaux ethermedium
-
- draw screen vga vgax cga
- pointer
- vga
-
- sd
- ds
- floppy dma
-
-# audio
- uart
- tinyfs
-
-# dbg x86break
-
-ip
- tcp
- udp
-# rudp
-# igmp
- ipifc
- icmp
- icmp6
- ipmux
-lib
- interp
- keyring
- sec
- mp
- draw
- memlayer
- memdraw
- tk
- math
- kern
-
-link
- ether2114x pci
-# ether82557 pci
- ether83815 pci
- etherelnk3 pci
- ps2mouse
- ethermedium
-# pppmedium ppp compress
-
-misc
- vgas3 +cur vgasavage
- vgamach64xx
- cga
-
- sdata pci sdscsi
- sd53c8xx pci sdscsi
-
- uarti8250
-
-mod
- sys
- draw
- tk
- keyring
- crypt
- ipints
-
- math
-
-init
- wminit
-
-code
- int kernel_pool_pcnt = 10;
- int main_pool_pcnt = 40;
- int heap_pool_pcnt = 20;
- int image_pool_pcnt = 40;
- int cflag=0;
- int swcursor=0;
- int consoleprint=0;
- int novgascreen=1;
-
-port
- alarm
- alloc
- allocb
- chan
- dev
- dial
- dis
- discall
- exception
- exportfs
- inferno
- latin1
- nocache
- nodynld
- parse
- pgrp
- print
- proc
- qio
- qlock
- random
- sysfile
- taslock
- xalloc
-
-root
- /chan
- /dev
- /dis
- /env
- /fd /
- /n
- /n/remote
- /net
- /nvfs
- /prog
- /dis/lib
- /dis/svc
- /dis/wm
- /osinit.dis
- /dis/sh.dis
- /dis/ls.dis
- /dis/cat.dis
- /dis/bind.dis
- /dis/mount.dis
- /dis/pwd.dis
- /dis/echo.dis
- /dis/cd.dis
- /dis/lib/bufio.dis
- /dis/lib/string.dis
- /dis/lib/readdir.dis
- /dis/lib/workdir.dis
- /dis/lib/daytime.dis
- /dis/lib/auth.dis
- /dis/lib/ssl.dis
-
-# kfs
- /dis/disk/kfs.dis
- /dis/lib/arg.dis
- /dis/lib/daytime.dis
- /dis/lib/string.dis
- /dis/lib/styx.dis
diff --git a/os/pc/pci.acid b/os/pc/pci.acid
deleted file mode 100644
index 46da501e..00000000
--- a/os/pc/pci.acid
+++ /dev/null
@@ -1,252 +0,0 @@
-// ACID PCI support
-
-pciclassdb = {
- {0x0000, "Unclassified device", {
- {0x0000,"Non-VGA unclassified device"},
- {0x0001,"VGA compatible unclassified device"},
- }},
- {0x0001, "Mass storage controller", {
- {0x0000,"SCSI storage controller"},
- {0x0001,"IDE interface"},
- {0x0002,"Floppy disk controller"},
- {0x0003,"IPI bus controller"},
- {0x0004,"RAID bus controller"},
- {0x0080,"Unknown mass storage controller"},
- }},
- {0x0002, "Network controller", {
- {0x0000,"Ethernet controller"},
- {0x0001,"Token ring network controller"},
- {0x0002,"FDDI network controller"},
- {0x0003,"ATM network controller"},
- {0x0080,"Network controller"},
- }},
- {0x0003, "Display controller", {
- {0x0000,"VGA compatible controller"},
- {0x0001,"XGA compatible controller"},
- {0x0080,"Display controller"},
- }},
- {0x0004, "Multimedia controller", {
- {0x0000,"Multimedia video controller"},
- {0x0001,"Multimedia audio controller"},
- {0x0080,"Multimedia controller"},
- }},
- {0x0005, "Memory controller", {
- {0x0000,"RAM memory"},
- {0x0001,"FLASH memory"},
- {0x0080,"Memory"},
- }},
- {0x0006, "Bridge", {
- {0x0000,"Host bridge"},
- {0x0001,"ISA bridge"},
- {0x0002,"EISA bridge"},
- {0x0003,"MicroChannel bridge"},
- {0x0004,"PCI bridge"},
- {0x0005,"PCMCIA bridge"},
- {0x0006,"NuBus bridge"},
- {0x0007,"CardBus bridge"},
- {0x0080,"Bridge"},
- }},
- {0x0007, "Communication controller", {
- {0x0000,"Serial controller"},
- {0x0001,"Parallel controller"},
- {0x0080,"Communication controller"},
- }},
- {0x0008, "Generic system peripheral", {
- {0x0000,"PIC"},
- {0x0001,"DMA controller"},
- {0x0002,"Timer"},
- {0x0003,"RTC"},
- {0x0080,"System peripheral"},
- }},
- {0x0009, "Input device controller", {
- {0x0000,"Keyboard controller"},
- {0x0001,"Digitizer Pen"},
- {0x0002,"Mouse controller"},
- {0x0080,"Input device controller"},
- }},
- {0x000A, "Docking station", {
- {0x0000,"Generic Docking Station"},
- {0x0080,"Docking Station"},
- }},
- {0x000B, "Processor", {
- {0x0000,"386"},
- {0x0001,"486"},
- {0x0002,"Pentium"},
- {0x0010,"Alpha"},
- {0x0020,"Power PC"},
- {0x0040,"Co-processor"},
- }},
- {0x000C, "Serial bus controller", {
- {0x0000,"FireWire (IEEE 1394)"},
- {0x0001,"ACCESS Bus"},
- {0x0002,"SSA"},
- {0x0003,"USB Controller"},
- {0x0004,"Fiber Channel"},
- }},
-};
-
-//
-// Include the vendor and device id database
-//
-
-include( "pcidb.acid" );
-
-defn test(thingy)
-{
- return thingy;
-}
-
-defn BUSFNO(tbdf)
-{
- return (((tbdf\X)>>8)&0x07);
-}
-
-defn BUSDNO(tbdf)
-{
- return (((tbdf\X)>>11)&0x1F);
-}
-
-defn BUSBNO(tbdf)
-{
- return (((tbdf\X)>>16)&0xFF);
-}
-
-defn lookup( key, dictionary )
-{
- local d, e;
-
- d = dictionary;
- while(d != {}) do {
- e = head d;
- if e[0] == key then
- return e;
- d = tail d;
- }
- return {};
-}
-
-defn pciclass( ccru )
-{
- local c, sc;
- local class, subclass;
- c = ccru >> 8;
- sc = ccru & 0xff;
-
- class = lookup( c, pciclassdb );
- subclass = lookup( sc, class[2] );
-
- if (subclass != {}) then {
- print(" ",subclass[1]);
- return 1;
- }
- if (class != {}) then {
- print(" ",class[1]);
- return 1;
- }
-
- print(" type=",ccru\x);
- return 0;
-}
-
-defn pcivendor( vid )
-{
- local v;
- v = lookup( vid, pcivendordb );
- if (v != {}) then {
- print(" ",v[1]);
- } else {
- print(" VendorID=",vid\x,":");
- }
-}
-
-defn pcidev( vid, did )
-{
- local v;
- local d;
- v = lookup( vid, pcivendordb );
- if (v != {}) then {
- d = lookup( did, v[2] );
- if (d != {}) then {
- print(" ",d[1]);
- return 1;
- }
- }
- print(" DeviceID=",did\x);
- return 0;
-}
-
-//
-// Dump PCI Info (short form)
-//
-
-defn pciinfo( r )
-{
- local t;
- local pcicount;
- t = r;
- pcicount = 0\d;
- while t != 0 do {
- print(pcicount\d,":","Bus:",BUSBNO(t.tbdf)\u," dev:",BUSDNO(t.tbdf)\u," fn:",BUSFNO(t.tbdf)\u,":");
- pciclass(t.ccru);
- print(":");
- pcivendor(t.vid);
- pcidev(t.vid, t.did);
- print("\n");
- pcicount = pcicount+1 ;
- t = t.link;
- }
- t = r;
- while t!= 0 do {
- if (t.bridge !=0) then
- pciinfo(t.bridge);
- t = t.link;
- }
-}
-
-defn lspci()
-{
- pciinfo( *pciroot );
-}
-
-//
-// Dump PCI Info (long form - includes interrupt lines & memory segments)
-//
-
-defn pcidumper( r )
-{
- local t;
- local m;
- t = r;
- while t != 0 do {
- print("Bus\t",BUSBNO(t.tbdf)\u);
- print(", device\t",BUSDNO(t.tbdf)\u);
- print(", function\t",BUSFNO(t.tbdf)\u,":\n");
- print(" ");
- pciclass(t.ccru);
- print(":");
- pcivendor(t.vid);
- pcidev(t.vid, t.did);
- print("\n");
- print(" Interrupt Line: ",t.intl\u,"\n");
- m =0\d;
- loop 0,5 do {
- if t.mem[m] != 0 then
- print("\t",(m/2)\d,":",t.mem[m]\X," ",t.mem[m+1]\X,"\n");
- m = m + 2;
- }
- t = t.link;
- }
- t = r;
- while t!= 0 do {
- if (t.bridge !=0) then
- pcidumper(t.bridge);
- t = t.link;
- }
-}
-
-defn pcidump()
-{
- pcidumper( *pciroot );
-}
-
-print("/os/pc/pci");
diff --git a/os/pc/pci.c b/os/pc/pci.c
deleted file mode 100644
index d35a306a..00000000
--- a/os/pc/pci.c
+++ /dev/null
@@ -1,1340 +0,0 @@
-/*
- * PCI support code.
- * Needs a massive rewrite.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define DBG if(0) pcilog
-
-struct
-{
- char output[16384];
- int ptr;
-}PCICONS;
-
-int
-pcilog(char *fmt, ...)
-{
- int n;
- va_list arg;
- char buf[PRINTSIZE];
-
- va_start(arg, fmt);
- n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
- va_end(arg);
-
- memmove(PCICONS.output+PCICONS.ptr, buf, n);
- PCICONS.ptr += n;
- return n;
-}
-
-enum
-{ /* configuration mechanism #1 */
- PciADDR = 0xCF8, /* CONFIG_ADDRESS */
- PciDATA = 0xCFC, /* CONFIG_DATA */
-
- /* configuration mechanism #2 */
- PciCSE = 0xCF8, /* configuration space enable */
- PciFORWARD = 0xCFA, /* which bus */
-
- MaxFNO = 7,
- MaxUBN = 255,
-};
-
-enum
-{ /* command register */
- IOen = (1<<0),
- MEMen = (1<<1),
- MASen = (1<<2),
- MemWrInv = (1<<4),
- PErrEn = (1<<6),
- SErrEn = (1<<8),
-};
-
-static Lock pcicfglock;
-static Lock pcicfginitlock;
-static int pcicfgmode = -1;
-static int pcimaxbno = 7;
-static int pcimaxdno;
-static Pcidev* pciroot;
-static Pcidev* pcilist;
-static Pcidev* pcitail;
-static int nobios, nopcirouting;
-
-static int pcicfgrw32(int, int, int, int);
-static int pcicfgrw16(int, int, int, int);
-static int pcicfgrw8(int, int, int, int);
-
-static char* bustypes[] = {
- "CBUSI",
- "CBUSII",
- "EISA",
- "FUTURE",
- "INTERN",
- "ISA",
- "MBI",
- "MBII",
- "MCA",
- "MPI",
- "MPSA",
- "NUBUS",
- "PCI",
- "PCMCIA",
- "TC",
- "VL",
- "VME",
- "XPRESS",
-};
-
-#pragma varargck type "T" int
-
-static int
-tbdffmt(Fmt* fmt)
-{
- char *p;
- int l, r, type, tbdf;
-
- if((p = malloc(READSTR)) == nil)
- return fmtstrcpy(fmt, "(tbdfconv)");
-
- switch(fmt->r){
- case 'T':
- tbdf = va_arg(fmt->args, int);
- type = BUSTYPE(tbdf);
- if(type < nelem(bustypes))
- l = snprint(p, READSTR, bustypes[type]);
- else
- l = snprint(p, READSTR, "%d", type);
- snprint(p+l, READSTR-l, ".%d.%d.%d",
- BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
- break;
-
- default:
- snprint(p, READSTR, "(tbdfconv)");
- break;
- }
- r = fmtstrcpy(fmt, p);
- free(p);
-
- return r;
-}
-
-ulong
-pcibarsize(Pcidev *p, int rno)
-{
- ulong v, size;
-
- v = pcicfgrw32(p->tbdf, rno, 0, 1);
- pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0);
- size = pcicfgrw32(p->tbdf, rno, 0, 1);
- if(v & 1)
- size |= 0xFFFF0000;
- pcicfgrw32(p->tbdf, rno, v, 0);
-
- return -(size & ~0x0F);
-}
-
-static int
-pcisizcmp(void *a, void *b)
-{
- Pcisiz *aa, *bb;
-
- aa = a;
- bb = b;
- return aa->siz - bb->siz;
-}
-
-static ulong
-pcimask(ulong v)
-{
- ulong m;
-
- m = BI2BY*sizeof(v);
- for(m = 1<<(m-1); m != 0; m >>= 1) {
- if(m & v)
- break;
- }
-
- m--;
- if((v & m) == 0)
- return v;
-
- v |= m;
- return v+1;
-}
-
-static void
-pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg)
-{
- Pcidev *p;
- int ntb, i, size, rno, hole;
- ulong v, mema, ioa, sioa, smema, base, limit;
- Pcisiz *table, *tptr, *mtb, *itb;
-
- if(!nobios)
- return;
-
- ioa = *pioa;
- mema = *pmema;
-
- DBG("pcibusmap wr=%d %T mem=%luX io=%luX\n",
- wrreg, root->tbdf, mema, ioa);
-
- ntb = 0;
- for(p = root; p != nil; p = p->link)
- ntb++;
-
- ntb *= (PciCIS-PciBAR0)/4;
- table = malloc(2*ntb*sizeof(Pcisiz));
- itb = table;
- mtb = table+ntb;
-
- /*
- * Build a table of sizes
- */
- for(p = root; p != nil; p = p->link) {
- if(p->ccrb == 0x06) {
- if(p->ccru != 0x04 || p->bridge == nil) {
-// DBG("pci: ignored bridge %T\n", p->tbdf);
- continue;
- }
-
- sioa = ioa;
- smema = mema;
- pcibusmap(p->bridge, &smema, &sioa, 0);
-
- hole = pcimask(smema-mema);
- if(hole < (1<<20))
- hole = 1<<20;
- p->mema.size = hole;
-
- hole = pcimask(sioa-ioa);
- if(hole < (1<<12))
- hole = 1<<12;
-
- p->ioa.size = hole;
-
- itb->dev = p;
- itb->bar = -1;
- itb->siz = p->ioa.size;
- itb++;
-
- mtb->dev = p;
- mtb->bar = -1;
- mtb->siz = p->mema.size;
- mtb++;
- continue;
- }
-
- for(i = 0; i <= 5; i++) {
- rno = PciBAR0 + i*4;
- v = pcicfgrw32(p->tbdf, rno, 0, 1);
- size = pcibarsize(p, rno);
- if(size == 0)
- continue;
-
- if(v & 1) {
- itb->dev = p;
- itb->bar = i;
- itb->siz = size;
- itb++;
- }
- else {
- mtb->dev = p;
- mtb->bar = i;
- mtb->siz = size;
- mtb++;
- }
-
- p->mem[i].size = size;
- }
- }
-
- /*
- * Sort both tables IO smallest first, Memory largest
- */
- qsort(table, itb-table, sizeof(Pcisiz), pcisizcmp);
- tptr = table+ntb;
- qsort(tptr, mtb-tptr, sizeof(Pcisiz), pcisizcmp);
-
- /*
- * Allocate IO address space on this bus
- */
- for(tptr = table; tptr < itb; tptr++) {
- hole = tptr->siz;
- if(tptr->bar == -1)
- hole = 1<<12;
- ioa = (ioa+hole-1) & ~(hole-1);
-
- p = tptr->dev;
- if(tptr->bar == -1)
- p->ioa.bar = ioa;
- else {
- p->pcr |= IOen;
- p->mem[tptr->bar].bar = ioa|1;
- if(wrreg)
- pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), ioa|1, 0);
- }
-
- ioa += tptr->siz;
- }
-
- /*
- * Allocate Memory address space on this bus
- */
- for(tptr = table+ntb; tptr < mtb; tptr++) {
- hole = tptr->siz;
- if(tptr->bar == -1)
- hole = 1<<20;
- mema = (mema+hole-1) & ~(hole-1);
-
- p = tptr->dev;
- if(tptr->bar == -1)
- p->mema.bar = mema;
- else {
- p->pcr |= MEMen;
- p->mem[tptr->bar].bar = mema;
- if(wrreg)
- pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), mema, 0);
- }
- mema += tptr->siz;
- }
-
- *pmema = mema;
- *pioa = ioa;
- free(table);
-
- if(wrreg == 0)
- return;
-
- /*
- * Finally set all the bridge addresses & registers
- */
- for(p = root; p != nil; p = p->link) {
- if(p->bridge == nil) {
- pcicfgrw8(p->tbdf, PciLTR, 64, 0);
-
- p->pcr |= MASen;
- pcicfgrw16(p->tbdf, PciPCR, p->pcr, 0);
- continue;
- }
-
- base = p->ioa.bar;
- limit = base+p->ioa.size-1;
- v = pcicfgrw32(p->tbdf, PciIBR, 0, 1);
- v = (v&0xFFFF0000)|(limit & 0xF000)|((base & 0xF000)>>8);
- pcicfgrw32(p->tbdf, PciIBR, v, 0);
- v = (limit & 0xFFFF0000)|(base>>16);
- pcicfgrw32(p->tbdf, PciIUBR, v, 0);
-
- base = p->mema.bar;
- limit = base+p->mema.size-1;
- v = (limit & 0xFFF00000)|((base & 0xFFF00000)>>16);
- pcicfgrw32(p->tbdf, PciMBR, v, 0);
-
- /*
- * Disable memory prefetch
- */
- pcicfgrw32(p->tbdf, PciPMBR, 0x0000FFFF, 0);
- pcicfgrw8(p->tbdf, PciLTR, 64, 0);
-
- /*
- * Enable the bridge
- */
- p->pcr |= IOen|MEMen|MASen;
- pcicfgrw32(p->tbdf, PciPCR, 0xFFFF0000|p->pcr , 0);
-
- sioa = p->ioa.bar;
- smema = p->mema.bar;
- pcibusmap(p->bridge, &smema, &sioa, 1);
- }
-}
-
-static int
-pcilscan(int bno, Pcidev** list)
-{
- Pcidev *p, *head, *tail;
- int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
-
- maxubn = bno;
- head = nil;
- tail = nil;
- for(dno = 0; dno <= pcimaxdno; dno++){
- maxfno = 0;
- for(fno = 0; fno <= maxfno; fno++){
- /*
- * For this possible device, form the
- * bus+device+function triplet needed to address it
- * and try to read the vendor and device ID.
- * If successful, allocate a device struct and
- * start to fill it in with some useful information
- * from the device's configuration space.
- */
- tbdf = MKBUS(BusPCI, bno, dno, fno);
- l = pcicfgrw32(tbdf, PciVID, 0, 1);
- if(l == 0xFFFFFFFF || l == 0)
- continue;
- p = malloc(sizeof(*p));
- p->tbdf = tbdf;
- p->vid = l;
- p->did = l>>16;
-
- if(pcilist != nil)
- pcitail->list = p;
- else
- pcilist = p;
- pcitail = p;
-
- p->pcr = pcicfgr16(p, PciPCR);
- p->rid = pcicfgr8(p, PciRID);
- p->ccrp = pcicfgr8(p, PciCCRp);
- p->ccru = pcicfgr8(p, PciCCRu);
- p->ccrb = pcicfgr8(p, PciCCRb);
- p->cls = pcicfgr8(p, PciCLS);
- p->ltr = pcicfgr8(p, PciLTR);
-
- p->intl = pcicfgr8(p, PciINTL);
-
- /*
- * If the device is a multi-function device adjust the
- * loop count so all possible functions are checked.
- */
- hdt = pcicfgr8(p, PciHDT);
- if(hdt & 0x80)
- maxfno = MaxFNO;
-
- /*
- * If appropriate, read the base address registers
- * and work out the sizes.
- */
- switch(p->ccrb) {
- case 0x01: /* mass storage controller */
- case 0x02: /* network controller */
- case 0x03: /* display controller */
- case 0x04: /* multimedia device */
- case 0x07: /* simple comm. controllers */
- case 0x08: /* base system peripherals */
- case 0x09: /* input devices */
- case 0x0A: /* docking stations */
- case 0x0B: /* processors */
- case 0x0C: /* serial bus controllers */
- if((hdt & 0x7F) != 0)
- break;
- rno = PciBAR0 - 4;
- for(i = 0; i < nelem(p->mem); i++) {
- rno += 4;
- p->mem[i].bar = pcicfgr32(p, rno);
- p->mem[i].size = pcibarsize(p, rno);
- }
- break;
-
- case 0x00:
- case 0x05: /* memory controller */
- case 0x06: /* bridge device */
- default:
- break;
- }
-
- if(head != nil)
- tail->link = p;
- else
- head = p;
- tail = p;
- }
- }
-
- *list = head;
- for(p = head; p != nil; p = p->link){
- /*
- * Find PCI-PCI bridges and recursively descend the tree.
- */
- if(p->ccrb != 0x06 || p->ccru != 0x04)
- continue;
-
- /*
- * If the secondary or subordinate bus number is not
- * initialised try to do what the PCI BIOS should have
- * done and fill in the numbers as the tree is descended.
- * On the way down the subordinate bus number is set to
- * the maximum as it's not known how many buses are behind
- * this one; the final value is set on the way back up.
- */
- sbn = pcicfgr8(p, PciSBN);
- ubn = pcicfgr8(p, PciUBN);
-
- if(sbn == 0 || ubn == 0 || nobios) {
- sbn = maxubn+1;
- /*
- * Make sure memory, I/O and master enables are
- * off, set the primary, secondary and subordinate
- * bus numbers and clear the secondary status before
- * attempting to scan the secondary bus.
- *
- * Initialisation of the bridge should be done here.
- */
- pcicfgw32(p, PciPCR, 0xFFFF0000);
- l = (MaxUBN<<16)|(sbn<<8)|bno;
- pcicfgw32(p, PciPBN, l);
- pcicfgw16(p, PciSPSR, 0xFFFF);
- maxubn = pcilscan(sbn, &p->bridge);
- l = (maxubn<<16)|(sbn<<8)|bno;
-
- pcicfgw32(p, PciPBN, l);
- }
- else {
- if(ubn > maxubn)
- maxubn = ubn;
- pcilscan(sbn, &p->bridge);
- }
- }
-
- return maxubn;
-}
-
-int
-pciscan(int bno, Pcidev **list)
-{
- int ubn;
-
- lock(&pcicfginitlock);
- ubn = pcilscan(bno, list);
- unlock(&pcicfginitlock);
- return ubn;
-}
-
-static uchar
-pIIxget(Pcidev *router, uchar link)
-{
- uchar pirq;
-
- /* link should be 0x60, 0x61, 0x62, 0x63 */
- pirq = pcicfgr8(router, link);
- return (pirq < 16)? pirq: 0;
-}
-
-static void
-pIIxset(Pcidev *router, uchar link, uchar irq)
-{
- pcicfgw8(router, link, irq);
-}
-
-static uchar
-viaget(Pcidev *router, uchar link)
-{
- uchar pirq;
-
- /* link should be 1, 2, 3, 5 */
- pirq = (link < 6)? pcicfgr8(router, 0x55 + (link>>1)): 0;
-
- return (link & 1)? (pirq >> 4): (pirq & 15);
-}
-
-static void
-viaset(Pcidev *router, uchar link, uchar irq)
-{
- uchar pirq;
-
- pirq = pcicfgr8(router, 0x55 + (link >> 1));
- pirq &= (link & 1)? 0x0f: 0xf0;
- pirq |= (link & 1)? (irq << 4): (irq & 15);
- pcicfgw8(router, 0x55 + (link>>1), pirq);
-}
-
-static uchar
-optiget(Pcidev *router, uchar link)
-{
- uchar pirq = 0;
-
- /* link should be 0x02, 0x12, 0x22, 0x32 */
- if ((link & 0xcf) == 0x02)
- pirq = pcicfgr8(router, 0xb8 + (link >> 5));
- return (link & 0x10)? (pirq >> 4): (pirq & 15);
-}
-
-static void
-optiset(Pcidev *router, uchar link, uchar irq)
-{
- uchar pirq;
-
- pirq = pcicfgr8(router, 0xb8 + (link >> 5));
- pirq &= (link & 0x10)? 0x0f : 0xf0;
- pirq |= (link & 0x10)? (irq << 4): (irq & 15);
- pcicfgw8(router, 0xb8 + (link >> 5), pirq);
-}
-
-static uchar
-aliget(Pcidev *router, uchar link)
-{
- /* No, you're not dreaming */
- static const uchar map[] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
- uchar pirq;
-
- /* link should be 0x01..0x08 */
- pirq = pcicfgr8(router, 0x48 + ((link-1)>>1));
- return (link & 1)? map[pirq&15]: map[pirq>>4];
-}
-
-static void
-aliset(Pcidev *router, uchar link, uchar irq)
-{
- /* Inverse of map in aliget */
- static const uchar map[] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
- uchar pirq;
-
- pirq = pcicfgr8(router, 0x48 + ((link-1)>>1));
- pirq &= (link & 1)? 0x0f: 0xf0;
- pirq |= (link & 1)? (map[irq] << 4): (map[irq] & 15);
- pcicfgw8(router, 0x48 + ((link-1)>>1), pirq);
-}
-
-static uchar
-cyrixget(Pcidev *router, uchar link)
-{
- uchar pirq;
-
- /* link should be 1, 2, 3, 4 */
- pirq = pcicfgr8(router, 0x5c + ((link-1)>>1));
- return ((link & 1)? pirq >> 4: pirq & 15);
-}
-
-static void
-cyrixset(Pcidev *router, uchar link, uchar irq)
-{
- uchar pirq;
-
- pirq = pcicfgr8(router, 0x5c + (link>>1));
- pirq &= (link & 1)? 0x0f: 0xf0;
- pirq |= (link & 1)? (irq << 4): (irq & 15);
- pcicfgw8(router, 0x5c + (link>>1), pirq);
-}
-
-typedef struct Bridge Bridge;
-struct Bridge
-{
- ushort vid;
- ushort did;
- uchar (*get)(Pcidev *, uchar);
- void (*set)(Pcidev *, uchar, uchar);
-};
-
-static Bridge southbridges[] = {
- { 0x8086, 0x122e, pIIxget, pIIxset }, // Intel 82371FB
- { 0x8086, 0x1234, pIIxget, pIIxset }, // Intel 82371MX
- { 0x8086, 0x7000, pIIxget, pIIxset }, // Intel 82371SB
- { 0x8086, 0x7110, pIIxget, pIIxset }, // Intel 82371AB
- { 0x8086, 0x7198, pIIxget, pIIxset }, // Intel 82443MX (fn 1)
- { 0x8086, 0x2410, pIIxget, pIIxset }, // Intel 82801AA
- { 0x8086, 0x2420, pIIxget, pIIxset }, // Intel 82801AB
- { 0x8086, 0x2440, pIIxget, pIIxset }, // Intel 82801BA
- { 0x8086, 0x244c, pIIxget, pIIxset }, // Intel 82801BAM
- { 0x8086, 0x248c, pIIxget, pIIxset }, // Intel 82801CAM
- { 0x8086, 0x24cc, pIIxget, pIIxset }, // Intel 82801DBM
- { 0x8086, 0x24d0, pIIxget, pIIxset }, // Intel 82801EB
- { 0x8086, 0x2640, pIIxget, pIIxset }, // Intel 82801FB
- { 0x1106, 0x0586, viaget, viaset }, // Viatech 82C586
- { 0x1106, 0x0596, viaget, viaset }, // Viatech 82C596
- { 0x1106, 0x0686, viaget, viaset }, // Viatech 82C686
- { 0x1106, 0x3227, viaget, viaset }, // Viatech VT8237
- { 0x1045, 0xc700, optiget, optiset }, // Opti 82C700
- { 0x10b9, 0x1533, aliget, aliset }, // Al M1533
- { 0x1039, 0x0008, pIIxget, pIIxset }, // SI 503
- { 0x1039, 0x0496, pIIxget, pIIxset }, // SI 496
- { 0x1078, 0x0100, cyrixget, cyrixset }, // Cyrix 5530 Legacy
-
- { 0x1022, 0x746B, nil, nil }, // AMD 8111
- { 0x10DE, 0x00D1, nil, nil }, // NVIDIA nForce 3
- { 0x1166, 0x0200, nil, nil }, // ServerWorks ServerSet III LE
-};
-
-typedef struct Slot Slot;
-struct Slot {
- uchar bus; // Pci bus number
- uchar dev; // Pci device number
- uchar maps[12]; // Avoid structs! Link and mask.
- uchar slot; // Add-in/built-in slot
- uchar reserved;
-};
-
-typedef struct Router Router;
-struct Router {
- uchar signature[4]; // Routing table signature
- uchar version[2]; // Version number
- uchar size[2]; // Total table size
- uchar bus; // Interrupt router bus number
- uchar devfn; // Router's devfunc
- uchar pciirqs[2]; // Exclusive PCI irqs
- uchar compat[4]; // Compatible PCI interrupt router
- uchar miniport[4]; // Miniport data
- uchar reserved[11];
- uchar checksum;
-};
-
-static ushort pciirqs; // Exclusive PCI irqs
-static Bridge *southbridge; // Which southbridge to use.
-
-static void
-pcirouting(void)
-{
- Slot *e;
- Router *r;
- int size, i, fn, tbdf;
- Pcidev *sbpci, *pci;
- uchar *p, pin, irq, link, *map;
-
- // Search for PCI interrupt routing table in BIOS
- for(p = (uchar *)KADDR(0xf0000); p < (uchar *)KADDR(0xfffff); p += 16)
- if(p[0] == '$' && p[1] == 'P' && p[2] == 'I' && p[3] == 'R')
- break;
-
- if(p >= (uchar *)KADDR(0xfffff))
- return;
-
- r = (Router *)p;
-
- // print("PCI interrupt routing table version %d.%d at %.6uX\n",
- // r->version[0], r->version[1], (ulong)r & 0xfffff);
-
- tbdf = (BusPCI << 24)|(r->bus << 16)|(r->devfn << 8);
- sbpci = pcimatchtbdf(tbdf);
- if(sbpci == nil) {
- print("pcirouting: Cannot find south bridge %T\n", tbdf);
- return;
- }
-
- for(i = 0; i != nelem(southbridges); i++)
- if(sbpci->vid == southbridges[i].vid && sbpci->did == southbridges[i].did)
- break;
-
- if(i == nelem(southbridges)) {
- print("pcirouting: ignoring south bridge %T %.4uX/%.4uX\n", tbdf, sbpci->vid, sbpci->did);
- return;
- }
- southbridge = &southbridges[i];
- if(southbridge->get == nil || southbridge->set == nil)
- return;
-
- pciirqs = (r->pciirqs[1] << 8)|r->pciirqs[0];
-
- size = (r->size[1] << 8)|r->size[0];
- for(e = (Slot *)&r[1]; (uchar *)e < p + size; e++) {
- // print("%.2uX/%.2uX %.2uX: ", e->bus, e->dev, e->slot);
- // for (i = 0; i != 4; i++) {
- // uchar *m = &e->maps[i * 3];
- // print("[%d] %.2uX %.4uX ",
- // i, m[0], (m[2] << 8)|m[1]);
- // }
- // print("\n");
-
- for(fn = 0; fn != 8; fn++) {
- tbdf = (BusPCI << 24)|(e->bus << 16)|((e->dev | fn) << 8);
- pci = pcimatchtbdf(tbdf);
- if(pci == nil)
- continue;
- pin = pcicfgr8(pci, PciINTP);
- if(pin == 0 || pin == 0xff)
- continue;
-
- map = &e->maps[(pin - 1) * 3];
- link = map[0];
- irq = southbridge->get(sbpci, link);
- if(irq == 0 || irq == pci->intl)
- continue;
- if(pci->intl != 0 && pci->intl != 0xFF) {
- print("pcirouting: BIOS workaround: %T at pin %d link %d irq %d -> %d\n",
- tbdf, pin, link, irq, pci->intl);
- southbridge->set(sbpci, link, pci->intl);
- continue;
- }
- print("pcirouting: %T at pin %d link %d irq %d\n", tbdf, pin, link, irq);
- pcicfgw8(pci, PciINTL, irq);
- pci->intl = irq;
- }
- }
-}
-
-static void
-pcicfginit(void)
-{
- char *p;
- Pcidev **list;
- ulong mema, ioa;
- int bno, n, pcibios;
-
- lock(&pcicfginitlock);
- if(pcicfgmode != -1)
- goto out;
-
- pcibios = 0;
- if(getconf("*nobios"))
- nobios = 1;
- else if(getconf("*pcibios"))
- pcibios = 1;
- if(getconf("*nopcirouting"))
- nopcirouting = 1;
-
- /*
- * Try to determine which PCI configuration mode is implemented.
- * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses
- * a DWORD at 0xCF8 and another at 0xCFC and will pass through
- * any non-DWORD accesses as normal I/O cycles. There shouldn't be
- * a device behind these addresses so if Mode1 accesses fail try
- * for Mode2 (Mode2 is deprecated).
- */
- if(!pcibios){
- /*
- * Bits [30:24] of PciADDR must be 0,
- * according to the spec.
- */
- n = inl(PciADDR);
- if(!(n & 0x7FF00000)){
- outl(PciADDR, 0x80000000);
- outb(PciADDR+3, 0);
- if(inl(PciADDR) & 0x80000000){
- pcicfgmode = 1;
- pcimaxdno = 31;
- }
- }
- outl(PciADDR, n);
-
- if(pcicfgmode < 0){
- /*
- * The 'key' part of PciCSE should be 0.
- */
- n = inb(PciCSE);
- if(!(n & 0xF0)){
- outb(PciCSE, 0x0E);
- if(inb(PciCSE) == 0x0E){
- pcicfgmode = 2;
- pcimaxdno = 15;
- }
- }
- outb(PciCSE, n);
- }
- }
-
- if(pcicfgmode < 0)
- goto out;
-
- fmtinstall('T', tbdffmt);
-
- if(p = getconf("*pcimaxbno")){
- n = strtoul(p, 0, 0);
- if(n < pcimaxbno)
- pcimaxbno = n;
- }
- if(p = getconf("*pcimaxdno")){
- n = strtoul(p, 0, 0);
- if(n < pcimaxdno)
- pcimaxdno = n;
- }
-
- list = &pciroot;
- for(bno = 0; bno <= pcimaxbno; bno++) {
- int sbno = bno;
- bno = pcilscan(bno, list);
-
- while(*list)
- list = &(*list)->link;
-
- if (sbno == 0) {
- Pcidev *pci;
-
- /*
- * If we have found a PCI-to-Cardbus bridge, make sure
- * it has no valid mappings anymore.
- */
- pci = pciroot;
- while (pci) {
- if (pci->ccrb == 6 && pci->ccru == 7) {
- ushort bcr;
-
- /* reset the cardbus */
- bcr = pcicfgr16(pci, PciBCR);
- pcicfgw16(pci, PciBCR, 0x40 | bcr);
- delay(50);
- }
- pci = pci->link;
- }
- }
- }
-
- if(pciroot == nil)
- goto out;
-
- if(nobios) {
- /*
- * Work out how big the top bus is
- */
- mema = 0;
- ioa = 0;
- pcibusmap(pciroot, &mema, &ioa, 0);
-
- DBG("Sizes: mem=%8.8lux size=%8.8lux io=%8.8lux\n",
- mema, pcimask(mema), ioa);
-
- /*
- * Align the windows and map it
- */
- ioa = 0x1000;
- mema = 0x90000000;
-
- pcilog("Mask sizes: mem=%lux io=%lux\n", mema, ioa);
-
- pcibusmap(pciroot, &mema, &ioa, 1);
- DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa);
-
- unlock(&pcicfginitlock);
- return;
- }
-
- if (!nopcirouting)
- pcirouting();
-
-out:
- unlock(&pcicfginitlock);
-
- if(getconf("*pcihinv"))
- pcihinv(nil);
-}
-
-static int
-pcicfgrw8(int tbdf, int rno, int data, int read)
-{
- int o, type, x;
-
- if(pcicfgmode == -1)
- pcicfginit();
-
- if(BUSBNO(tbdf))
- type = 0x01;
- else
- type = 0x00;
- x = -1;
- if(BUSDNO(tbdf) > pcimaxdno)
- return x;
-
- lock(&pcicfglock);
- switch(pcicfgmode){
-
- case 1:
- o = rno & 0x03;
- rno &= ~0x03;
- outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
- if(read)
- x = inb(PciDATA+o);
- else
- outb(PciDATA+o, data);
- outl(PciADDR, 0);
- break;
-
- case 2:
- outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
- outb(PciFORWARD, BUSBNO(tbdf));
- if(read)
- x = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno);
- else
- outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
- outb(PciCSE, 0);
- break;
- }
- unlock(&pcicfglock);
-
- return x;
-}
-
-int
-pcicfgr8(Pcidev* pcidev, int rno)
-{
- return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
-}
-
-void
-pcicfgw8(Pcidev* pcidev, int rno, int data)
-{
- pcicfgrw8(pcidev->tbdf, rno, data, 0);
-}
-
-static int
-pcicfgrw16(int tbdf, int rno, int data, int read)
-{
- int o, type, x;
-
- if(pcicfgmode == -1)
- pcicfginit();
-
- if(BUSBNO(tbdf))
- type = 0x01;
- else
- type = 0x00;
- x = -1;
- if(BUSDNO(tbdf) > pcimaxdno)
- return x;
-
- lock(&pcicfglock);
- switch(pcicfgmode){
-
- case 1:
- o = rno & 0x02;
- rno &= ~0x03;
- outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
- if(read)
- x = ins(PciDATA+o);
- else
- outs(PciDATA+o, data);
- outl(PciADDR, 0);
- break;
-
- case 2:
- outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
- outb(PciFORWARD, BUSBNO(tbdf));
- if(read)
- x = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno);
- else
- outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
- outb(PciCSE, 0);
- break;
- }
- unlock(&pcicfglock);
-
- return x;
-}
-
-int
-pcicfgr16(Pcidev* pcidev, int rno)
-{
- return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
-}
-
-void
-pcicfgw16(Pcidev* pcidev, int rno, int data)
-{
- pcicfgrw16(pcidev->tbdf, rno, data, 0);
-}
-
-static int
-pcicfgrw32(int tbdf, int rno, int data, int read)
-{
- int type, x;
-
- if(pcicfgmode == -1)
- pcicfginit();
-
- if(BUSBNO(tbdf))
- type = 0x01;
- else
- type = 0x00;
- x = -1;
- if(BUSDNO(tbdf) > pcimaxdno)
- return x;
-
- lock(&pcicfglock);
- switch(pcicfgmode){
-
- case 1:
- rno &= ~0x03;
- outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
- if(read)
- x = inl(PciDATA);
- else
- outl(PciDATA, data);
- outl(PciADDR, 0);
- break;
-
- case 2:
- outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
- outb(PciFORWARD, BUSBNO(tbdf));
- if(read)
- x = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno);
- else
- outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
- outb(PciCSE, 0);
- break;
- }
- unlock(&pcicfglock);
-
- return x;
-}
-
-int
-pcicfgr32(Pcidev* pcidev, int rno)
-{
- return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
-}
-
-void
-pcicfgw32(Pcidev* pcidev, int rno, int data)
-{
- pcicfgrw32(pcidev->tbdf, rno, data, 0);
-}
-
-Pcidev*
-pcimatch(Pcidev* prev, int vid, int did)
-{
- if(pcicfgmode == -1)
- pcicfginit();
-
- if(prev == nil)
- prev = pcilist;
- else
- prev = prev->list;
-
- while(prev != nil){
- if((vid == 0 || prev->vid == vid)
- && (did == 0 || prev->did == did))
- break;
- prev = prev->list;
- }
- return prev;
-}
-
-Pcidev*
-pcimatchtbdf(int tbdf)
-{
- Pcidev *pcidev;
-
- if(pcicfgmode == -1)
- pcicfginit();
-
- for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) {
- if(pcidev->tbdf == tbdf)
- break;
- }
- return pcidev;
-}
-
-uchar
-pciipin(Pcidev *pci, uchar pin)
-{
- if (pci == nil)
- pci = pcilist;
-
- while (pci) {
- uchar intl;
-
- if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff)
- return pci->intl;
-
- if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0)
- return intl;
-
- pci = pci->list;
- }
- return 0;
-}
-
-static void
-pcilhinv(Pcidev* p)
-{
- int i;
- Pcidev *t;
-
- if(p == nil) {
- putstrn(PCICONS.output, PCICONS.ptr);
- p = pciroot;
- print("bus dev type vid did intl memory\n");
- }
- for(t = p; t != nil; t = t->link) {
- print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ",
- BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf),
- t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl);
-
- for(i = 0; i < nelem(p->mem); i++) {
- if(t->mem[i].size == 0)
- continue;
- print("%d:%.8lux %d ", i,
- t->mem[i].bar, t->mem[i].size);
- }
- if(t->ioa.bar || t->ioa.size)
- print("ioa:%.8lux %d ", t->ioa.bar, t->ioa.size);
- if(t->mema.bar || t->mema.size)
- print("mema:%.8lux %d ", t->mema.bar, t->mema.size);
- if(t->bridge)
- print("->%d", BUSBNO(t->bridge->tbdf));
- print("\n");
- }
- while(p != nil) {
- if(p->bridge != nil)
- pcilhinv(p->bridge);
- p = p->link;
- }
-}
-
-void
-pcihinv(Pcidev* p)
-{
- if(pcicfgmode == -1)
- pcicfginit();
- lock(&pcicfginitlock);
- pcilhinv(p);
- unlock(&pcicfginitlock);
-}
-
-void
-pcireset(void)
-{
- Pcidev *p;
-
- if(pcicfgmode == -1)
- pcicfginit();
-
- for(p = pcilist; p != nil; p = p->list) {
- /* don't mess with the bridges */
- if(p->ccrb == 0x06)
- continue;
- pciclrbme(p);
- }
-}
-
-void
-pcisetioe(Pcidev* p)
-{
- p->pcr |= IOen;
- pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pciclrioe(Pcidev* p)
-{
- p->pcr &= ~IOen;
- pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pcisetbme(Pcidev* p)
-{
- p->pcr |= MASen;
- pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pciclrbme(Pcidev* p)
-{
- p->pcr &= ~MASen;
- pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pcisetmwi(Pcidev* p)
-{
- p->pcr |= MemWrInv;
- pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pciclrmwi(Pcidev* p)
-{
- p->pcr &= ~MemWrInv;
- pcicfgw16(p, PciPCR, p->pcr);
-}
-
-static int
-pcigetpmrb(Pcidev* p)
-{
- int ptr;
-
- if(p->pmrb != 0)
- return p->pmrb;
- p->pmrb = -1;
-
- /*
- * If there are no extended capabilities implemented,
- * (bit 4 in the status register) assume there's no standard
- * power management method.
- * Find the capabilities pointer based on PCI header type.
- */
- if(!(p->pcr & 0x0010))
- return -1;
- switch(pcicfgr8(p, PciHDT)){
- default:
- return -1;
- case 0: /* all other */
- case 1: /* PCI to PCI bridge */
- ptr = 0x34;
- break;
- case 2: /* CardBus bridge */
- ptr = 0x14;
- break;
- }
- ptr = pcicfgr32(p, ptr);
-
- while(ptr != 0){
- /*
- * Check for validity.
- * Can't be in standard header and must be double
- * word aligned.
- */
- if(ptr < 0x40 || (ptr & ~0xFC))
- return -1;
- if(pcicfgr8(p, ptr) == 0x01){
- p->pmrb = ptr;
- return ptr;
- }
-
- ptr = pcicfgr8(p, ptr+1);
- }
-
- return -1;
-}
-
-int
-pcigetpms(Pcidev* p)
-{
- int pmcsr, ptr;
-
- if((ptr = pcigetpmrb(p)) == -1)
- return -1;
-
- /*
- * Power Management Register Block:
- * offset 0: Capability ID
- * 1: next item pointer
- * 2: capabilities
- * 4: control/status
- * 6: bridge support extensions
- * 7: data
- */
- pmcsr = pcicfgr16(p, ptr+4);
-
- return pmcsr & 0x0003;
-}
-
-int
-pcisetpms(Pcidev* p, int state)
-{
- int ostate, pmc, pmcsr, ptr;
-
- if((ptr = pcigetpmrb(p)) == -1)
- return -1;
-
- pmc = pcicfgr16(p, ptr+2);
- pmcsr = pcicfgr16(p, ptr+4);
- ostate = pmcsr & 0x0003;
- pmcsr &= ~0x0003;
-
- switch(state){
- default:
- return -1;
- case 0:
- break;
- case 1:
- if(!(pmc & 0x0200))
- return -1;
- break;
- case 2:
- if(!(pmc & 0x0400))
- return -1;
- break;
- case 3:
- break;
- }
- pmcsr |= state;
- pcicfgw16(p, ptr+4, pmcsr);
-
- return ostate;
-}
diff --git a/os/pc/pcidb.acid b/os/pc/pcidb.acid
deleted file mode 100644
index 0ab443d5..00000000
--- a/os/pc/pcidb.acid
+++ /dev/null
@@ -1,2848 +0,0 @@
-pcivendordb = {
- {0x0000, "Gammagraphx, Inc.", {
- }},
- {0x001a, "Ascend Communications, Inc.", {
- }},
- {0x003d, "Lockheed Martin-Marietta Corp", {
- }},
- {0x0e11, "Compaq Computer Corporation", {
- {0x3032,"QVision 1280/p Rev 0"},
- {0x3033,"QVision 1280/p Rev 1"},
- {0x3034,"QVision 1280/p Rev 2"},
- {0x4000,"4000 [Triflex]"},
- {0xae10,"Smart-2/P RAID Controller"},
- {0xae29,"MIS-L"},
- {0xae2a,"MPC"},
- {0xae2b,"MIS-E"},
- {0xae32,"Netelligent 10/100"},
- {0xae34,"Netelligent 10"},
- {0xae35,"Integrated NetFlex-3/P"},
- {0xae40,"Netelligent 10/100 Dual"},
- {0xae43,"ProLiant Integrated Netelligent 10/100"},
- {0xae69,"CETUS-L"},
- {0xae6c,"Northstar"},
- {0xb011,"Integrated Netelligent 10/100"},
- {0xb012,"Netelligent 10 T/2"},
- {0xf130,"NetFlex-3/P ThunderLAN 1.0"},
- {0xf150,"NetFlex-3/P ThunderLAN 2.3"},
- }},
- {0x1000, "Symbios Logic Inc. (formerly NCR)", {
- {0x0001,"53c810"},
- {0x0002,"53c820"},
- {0x0003,"53c825"},
- {0x0004,"53c815"},
- {0x0005,"53c810AP"},
- {0x0006,"53c860"},
- {0x000b,"53c896"},
- {0x000c,"53c895"},
- {0x000d,"53c885"},
- {0x000f,"53c875"},
- {0x008f,"53c875J"},
- {0x0901,"61C102"},
- {0x1000,"63C815"},
- }},
- {0x1002, "ATI Technologies Inc", {
- {0x4158,"68800AX [Mach32]"},
- {0x4354,"215CT [Mach64 CT]"},
- {0x4358,"210888CX [Mach64 CX]"},
- {0x4554,"210888ET [Mach64 ET]"},
- {0x4742,"215GB [Mach64 GB]"},
- {0x4744,"215GD [Mach64 GD]"},
- {0x4749,"215GI [Mach64 GI]"},
- {0x4750,"215GP [Mach64 GP]"},
- {0x4751,"215GQ [Mach64 GQ]"},
- {0x4754,"215GT [Mach64 GT]"},
- {0x4755,"215GTB [Mach64 GTB]"},
- {0x4756,"215IIC [Mach64 GT IIC]"},
- {0x4758,"210888GX [Mach64 GX]"},
- {0x4c47,"215LG [Mach64 LG]"},
- {0x4c54,"264LT [Mach64 LT]"},
- {0x5654,"264VT [Mach64 VT]"},
- {0x5655,"264VTB [Mach64 VTB]"},
- {0x5656,"264VT4 [Mach64 VT4]"},
- }},
- {0x1003, "ULSI Systems", {
- {0x0201,"US201"},
- }},
- {0x1004, "VLSI Technology Inc", {
- {0x0005,"82C592-FC1"},
- {0x0006,"82C593-FC1"},
- {0x0007,"82C594-AFC2"},
- {0x0008,"82C596/7 [Wildcat]"},
- {0x0009,"82C597-AFC2"},
- {0x000c,"82C541 [Lynx]"},
- {0x000d,"82C543 [Lynx]"},
- {0x0101,"82C532"},
- {0x0102,"82C534"},
- {0x0103,"82C538"},
- {0x0104,"82C535"},
- {0x0105,"82C147"},
- {0x0200,"82C975"},
- {0x0280,"82C925"},
- {0x0702,"VAS96011 [Golden Gate II]"},
- }},
- {0x1005, "Avance Logic, Inc.", {
- {0x2301,"ALG2301"},
- {0x2302,"ALG2302"},
- {0x2364,"ALG2364"},
- }},
- {0x1006, "Reply Group", {
- }},
- {0x1007, "NetFrame Systems Inc", {
- }},
- {0x1008, "Epson", {
- }},
- {0x100a, "Phoenix Technologies", {
- }},
- {0x100b, "National Semiconductor Corporation", {
- {0x0001,"DP83810"},
- {0x0002,"87415"},
- {0xd001,"87410"},
- }},
- {0x100c, "Tseng Labs Inc", {
- {0x3202,"ET4000/W32p rev A"},
- {0x3205,"ET4000/W32p rev B"},
- {0x3206,"ET4000/W32p rev C"},
- {0x3207,"ET4000/W32p rev D"},
- {0x3208,"ET6000"},
- }},
- {0x100d, "AST Research Inc", {
- }},
- {0x100e, "Weitek", {
- {0x9001,"P9000"},
- {0x9100,"P9100"},
- }},
- {0x1010, "Video Logic, Ltd.", {
- }},
- {0x1011, "Digital Equipment Corporation", {
- {0x0001,"DECchip 21050"},
- {0x0002,"DECchip 21040 [Tulip]"},
- {0x0004,"DECchip 21030 [TGA]"},
- {0x0007,"NVRAM [Zephyr NVRAM]"},
- {0x0008,"KZPSA [KZPSA]"},
- {0x0009,"DECchip 21140 [FasterNet]"},
- {0x000d,"PBXGB [TGA2]"},
- {0x000f,"DEFPA"},
- {0x0014,"DECchip 21041 [Tulip Pass 3]"},
- {0x0016,"DGLPB [OPPO]"},
- {0x0019,"DECchip 21142/43"},
- {0x0021,"DECchip 21052"},
- {0x0022,"DECchip 21150"},
- {0x0024,"DECchip 21152"},
- }},
- {0x1012, "Micronics Computers Inc", {
- }},
- {0x1013, "Cirrus Logic", {
- {0x0038,"GD 7548"},
- {0x00a0,"GD 5430/40 [Alpine]"},
- {0x00a4,"GD 5434-4 [Alpine]"},
- {0x00a8,"GD 5434-8 [Alpine]"},
- {0x00ac,"GD 5436 [Alpine]"},
- {0x00b8,"GD 5446"},
- {0x00bc,"GD 5480"},
- {0x00d0,"GD 5462"},
- {0x00d4,"GD 5464 [Laguna]"},
- {0x00d6,"GD 5465 [Laguna]"},
- {0x1100,"CL 6729"},
- {0x1110,"PD 6832"},
- {0x1200,"GD 7542 [Nordic]"},
- {0x1202,"GD 7543 [Viking]"},
- {0x1204,"GD 7541 [Nordic Light]"},
- }},
- {0x1014, "IBM", {
- {0x000a,"Fire Coral"},
- {0x0018,"TR"},
- {0x001b,"GXT-150P"},
- {0x001d,"82G2675"},
- {0x0020,"MCA"},
- {0x0022,"IBM27-82351"},
- {0x002e,"ServeRAID controller"},
- {0x0036,"Miami"},
- {0x003e,"TR_Wake"},
- {0x0046,"MPIC interrupt controller"},
- {0x007d,"3780IDSP [MWave]"},
- {0xffff,"MPIC-2 interrupt controller"},
- }},
- {0x1015, "LSI Logic Corp of Canada", {
- }},
- {0x1016, "ICL Personal Systems", {
- }},
- {0x1017, "SPEA Software AG", {
- }},
- {0x1018, "Unisys Systems", {
- }},
- {0x1019, "Elitegroup Computer Systems", {
- }},
- {0x101a, "AT&T GIS (NCR)", {
- }},
- {0x101b, "Vitesse Semiconductor", {
- }},
- {0x101c, "Western Digital", {
- {0x0193,"33C193A"},
- {0x0197,"33C197A"},
- {0x0296,"33C296A"},
- {0x3193,"7193"},
- {0x3197,"WD 7197"},
- {0x3296,"33C296A"},
- {0x4296,"34C296"},
- {0xc24a,"90C"},
- }},
- {0x101e, "American Megatrends Inc.", {
- {0x9010,"MegaRAID"},
- }},
- {0x101f, "PictureTel", {
- }},
- {0x1020, "Hitachi Computer Products", {
- }},
- {0x1021, "OKI Electric Industry Co. Ltd.", {
- }},
- {0x1022, "Advanced Micro Devices", {
- {0x2000,"79c970 [PCnet LANCE]"},
- {0x2020,"53c974 [PCscsi]"},
- {0x2040,"79c974"},
- }},
- {0x1023, "Trident Microsystems", {
- {0x9320,"TGUI 9320"},
- {0x9397,"Cyber9397"},
- {0x9420,"TGUI 9420"},
- {0x9430,"TGUI 9430"},
- {0x9440,"TGUI 9440"},
- {0x9660,"TGUI 9660/9680/9682"},
- {0x9750,"3DIm`age 975"},
- }},
- {0x1024, "Zenith Data Systems", {
- }},
- {0x1025, "Acer Incorporated", {
- {0x1435,"M1435"},
- {0x1445,"M1445"},
- {0x1449,"M1449"},
- {0x1451,"M1451"},
- {0x1461,"M1461"},
- {0x3141,"M3141"},
- {0x3143,"M3143"},
- {0x3145,"M3145"},
- {0x3147,"M3147"},
- {0x3149,"M3149"},
- {0x3151,"M3151"},
- }},
- {0x1028, "Dell Computer Corporation", {
- }},
- {0x1029, "Siemens Nixdorf IS", {
- }},
- {0x102a, "LSI Logic", {
- {0x0000,"HYDRA"},
- {0x0010,"ASPEN"},
- }},
- {0x102b, "Matrox Graphics, Inc.", {
- {0x0518,"2085PX [Atlas MGA-2]"},
- {0x0519,"MGA 2064W [Millennium]"},
- {0x051a,"MGA 1064SG [Mystique]"},
- {0x051b,"MGA 2164W [Millennium II]"},
- {0x051f,"MGA 2164W AGP [Millennium II AGP]"},
- {0x0d10,"MGA Ultima/Impression"},
- }},
- {0x102c, "Chips and Technologies", {
- {0x00b8,"64310"},
- {0x00d8,"65545"},
- {0x00dc,"65548"},
- {0x00e0,"65550"},
- {0x00e4,"65554"},
- {0x00e5,"65555"},
- }},
- {0x102d, "Wyse Technology Inc.", {
- }},
- {0x102e, "Olivetti Advanced Technology", {
- }},
- {0x102f, "Toshiba America", {
- }},
- {0x1030, "TMC Research", {
- }},
- {0x1031, "Miro Computer Products AG", {
- {0x5601,"DC20 ASIC"},
- }},
- {0x1033, "NEC Corporation", {
- {0x0035,"USB"},
- {0x0046,"PowerVR PCX2 [midas]"},
- }},
- {0x1034, "Framatome Connectors USA Inc.", {
- }},
- {0x1035, "Comp. & Comm. Research Lab", {
- }},
- {0x1036, "Future Domain Corp.", {
- {0x0000,"TMC-18C30 [36C70]"},
- }},
- {0x1037, "Hitachi Micro Systems", {
- }},
- {0x1038, "AMP, Inc", {
- }},
- {0x1039, "Silicon Integrated Systems", {
- {0x0001,"5591/5592 AGP"},
- {0x0002,"SG86C202"},
- {0x0008,"85C503"},
- {0x0009,"ACPI"},
- {0x0200,"5597/5598 VGA"},
- {0x0204,"82C204"},
- {0x0205,"SG86C205"},
- {0x0406,"85C501/2"},
- {0x0496,"85C496"},
- {0x0597,"5513C"},
- {0x0601,"85C601"},
- {0x5107,"5107"},
- {0x5511,"5511/5512"},
- {0x5513,"5513"},
- {0x5571,"5571"},
- {0x5591,"5591/5592 Host"},
- {0x5597,"5597 [SiS5582]"},
- {0x7001,"7001"},
- }},
- {0x103a, "Seiko Epson Corporation", {
- }},
- {0x103b, "Tatung Co. of America", {
- }},
- {0x103c, "Hewlett-Packard Company", {
- {0x1030,"J2585A"},
- {0x1031,"J2585B"},
- {0x2910,"E2910A"},
- {0x2925,"E2925A"},
- }},
- {0x103e, "Solliday Engineering", {
- }},
- {0x103f, "Synopsys/Logic Modeling Group", {
- }},
- {0x1040, "Accelgraphics Inc.", {
- }},
- {0x1041, "Computrend", {
- }},
- {0x1042, "Micron", {
- {0x1000,"FDC 37C665"},
- {0x1001,"37C922"},
- {0x3000,"Samurai_0"},
- {0x3010,"Samurai_1"},
- {0x3020,"Samurai_IDE"},
- }},
- {0x1043, "Asustek Computer, Inc.", {
- }},
- {0x1044, "Distributed Processing Technology", {
- {0xa400,"SmartCache/Raid III or IV"},
- }},
- {0x1045, "OPTi Inc.", {
- {0xc178,"92C178"},
- {0xc557,"82C557 [Viper-M]"},
- {0xc558,"82C558 [Viper-M ISA+IDE]"},
- {0xc621,"82C621"},
- {0xc700,"82C700"},
- {0xc701,"82C701 [FireStar Plus]"},
- {0xc814,"82C814 [Firebridge 1]"},
- {0xc822,"82C822"},
- {0xc824,"82C824"},
- {0xd568,"82C825 [Firebridge 2]"},
- }},
- {0x1046, "IPC Corporation, Ltd.", {
- }},
- {0x1047, "Genoa Systems Corp", {
- }},
- {0x1048, "Elsa AG", {
- }},
- {0x1049, "Fountain Technologies, Inc.", {
- }},
- {0x104a, "SGS Thomson Microelectronics", {
- {0x0008,"STG 2000X"},
- {0x0009,"STG 1764X"},
- }},
- {0x104b, "BusLogic", {
- {0x0140,"BT-946C (old) [multimaster 01]"},
- {0x1040,"BT-946C (BA80C30) [MultiMaster 10]"},
- {0x8130,"Flashpoint LT"},
- }},
- {0x104c, "Texas Instruments", {
- {0x3d04,"TVP4010 [Permedia]"},
- {0x3d07,"TVP4020 [Permedia 2]"},
- {0xa001,"TDC1570"},
- {0xa100,"TDC1561"},
- {0xac10,"PCI1050"},
- {0xac11,"PCI1053"},
- {0xac12,"PCI1130"},
- {0xac13,"PCI1031"},
- {0xac15,"PCI1131"},
- {0xac16,"PCI-1250"},
- {0xac17,"PCI-1220"},
- }},
- {0x104d, "Sony Corporation", {
- }},
- {0x104e, "Oak Technology, Inc", {
- {0x0107,"OTI107"},
- }},
- {0x104f, "Co-time Computer Ltd", {
- }},
- {0x1050, "Winbond Electronics Corp", {
- {0x0940,"89C940"},
- }},
- {0x1051, "Anigma, Inc.", {
- }},
- {0x1053, "Young Micro Systems", {
- }},
- {0x1054, "Hitachi, Ltd", {
- }},
- {0x1055, "EFAR Microsystems", {
- }},
- {0x1056, "ICL", {
- }},
- {0x1057, "Motorola Computer Group", {
- {0x0001,"MPC105 [Eagle]"},
- {0x0002,"MPC106 [Grackle]"},
- {0x4801,"Raven"},
- }},
- {0x1058, "Electronics & Telecommunications RSH", {
- }},
- {0x1059, "Teknor Industrial Computers Inc", {
- }},
- {0x105a, "Promise Technology, Inc.", {
- {0x4d33,"20246"},
- {0x5300,"DC5300"},
- }},
- {0x105b, "Foxconn International, Inc.", {
- }},
- {0x105c, "Wipro Infotech Limited", {
- }},
- {0x105d, "Number 9 Computer Company", {
- {0x2309,"Imagine 128"},
- {0x2339,"Imagine 128-II"},
- {0x493d,"Imagine 128 T2R [Ticket to Ride]"},
- }},
- {0x105e, "Vtech Computers Ltd", {
- }},
- {0x105f, "Infotronic America Inc", {
- }},
- {0x1060, "United Microelectronics", {
- {0x0001,"UM82C881"},
- {0x0002,"UM82C886"},
- {0x0101,"UM8673F"},
- {0x0881,"UM8881"},
- {0x0886,"UM8886F"},
- {0x0891,"UM8891A"},
- {0x1001,"UM886A"},
- {0x673a,"UM8886BF"},
- {0x8710,"UM8710"},
- {0x886a,"UM8886A"},
- {0x8881,"UM8881F"},
- {0x8886,"UM8886F"},
- {0x888a,"UM8886A"},
- {0x8891,"UM8891A"},
- {0x9017,"UM9017F"},
- {0xe881,"UM8881N"},
- {0xe886,"UM8886N"},
- {0xe891,"UM8891N"},
- }},
- {0x1061, "I.I.T.", {
- {0x0001,"AGX016"},
- {0x0002,"IIT3204/3501"},
- }},
- {0x1062, "Maspar Computer Corp", {
- }},
- {0x1063, "Ocean Office Automation", {
- }},
- {0x1064, "Alcatel CIT", {
- }},
- {0x1065, "Texas Microsystems", {
- }},
- {0x1066, "PicoPower Technology", {
- {0x0000,"PT80C826"},
- {0x0001,"PT86C52x [Vesuvius]"},
- {0x0002,"PT80C524 [Nile]"},
- }},
- {0x1067, "Mitsubishi Electronics", {
- }},
- {0x1068, "Diversified Technology", {
- }},
- {0x1069, "Mylex Corporation", {
- {0x0001,"DAC960P"},
- }},
- {0x106a, "Aten Research Inc", {
- }},
- {0x106b, "Apple Computer Inc.", {
- {0x0001,"Bandit PowerPC host bridge"},
- {0x0002,"Grand Central I/O"},
- {0x000e,"Hydra Mac I/O"},
- }},
- {0x106c, "Hyundai Electronics America", {
- }},
- {0x106d, "Sequent Computer Systems", {
- }},
- {0x106e, "DFI, Inc", {
- }},
- {0x106f, "City Gate Development Ltd", {
- }},
- {0x1070, "Daewoo Telecom Ltd", {
- }},
- {0x1071, "Mitac", {
- }},
- {0x1072, "GIT Co Ltd", {
- }},
- {0x1073, "Yamaha Corporation", {
- {0x0002,"YGV615 [RPA3 3D-Graphics Controller]"},
- }},
- {0x1074, "NexGen Microsystems", {
- {0x4e78,"82c501"},
- }},
- {0x1075, "Advanced Integrations Research", {
- }},
- {0x1076, "Chaintech Computer Co. Ltd", {
- }},
- {0x1077, "Q Logic", {
- {0x1020,"ISP1020"},
- {0x1022,"ISP1022"},
- }},
- {0x1078, "Cyrix Corporation", {
- {0x0000,"5510 [Grappa]"},
- {0x0001,"PCI_Master"},
- {0x0002,"5520 [Cognac]"},
- {0x0100,"5530_Legacy [Kahlua]"},
- {0x0101,"5530_SMI [Kahlua]"},
- {0x0102,"5530_IDE [Kahlua]"},
- {0x0103,"5530_Audio [Kahlua]"},
- {0x0104,"5530_Video [Kahlua]"},
- }},
- {0x1079, "I-Bus", {
- }},
- {0x107a, "NetWorth", {
- }},
- {0x107b, "Gateway 2000", {
- }},
- {0x107c, "Goldstar", {
- }},
- {0x107d, "LeadTek Research Inc.", {
- {0x0000,"P86C850"},
- }},
- {0x107e, "Interphase Corporation", {
- }},
- {0x107f, "Data Technology Corporation", {
- {0x0802,"SL82C105"},
- }},
- {0x1080, "Contaq Microsystems", {
- {0x0600,"82C599"},
- {0xc693,"82c693"},
- }},
- {0x1081, "Supermac Technology", {
- }},
- {0x1082, "EFA Corporation of America", {
- }},
- {0x1083, "Forex Computer Corporation", {
- {0x0001,"FR710"},
- }},
- {0x1084, "Parador", {
- }},
- {0x1085, "Tulip Computers Int.B.V.", {
- }},
- {0x1086, "J. Bond Computer Systems", {
- }},
- {0x1087, "Cache Computer", {
- }},
- {0x1088, "Microcomputer Systems (M) Son", {
- }},
- {0x1089, "Data General Corporation", {
- }},
- {0x108a, "Bit3 Computer Corp.", {
- }},
- {0x108c, "Oakleigh Systems Inc.", {
- }},
- {0x108d, "Olicom", {
- {0x0001,"OC-3136/3137"},
- {0x0011,"OC-2315"},
- {0x0012,"OC-2325"},
- {0x0013,"OC-2183/2185"},
- {0x0014,"OC-2326"},
- {0x0021,"OC-6151/6152 [RapidFire ATM PCI 155]"},
- }},
- {0x108e, "Sun Microsystems Computer Corp.", {
- {0x1000,"EBUS"},
- {0x1001,"Happy Meal"},
- {0x5000,"Advanced PCI Bridge"},
- {0x8000,"PCI Bus Module"},
- {0xa000,"Ultra IIi PCI"},
- }},
- {0x108f, "Systemsoft", {
- }},
- {0x1090, "Encore Computer Corporation", {
- }},
- {0x1091, "Intergraph Corporation", {
- }},
- {0x1092, "Diamond Multimedia Systems", {
- }},
- {0x1093, "National Instruments", {
- {0xc801,"PCI_GPIB"},
- }},
- {0x1094, "First International Computers", {
- }},
- {0x1095, "CMD Technology Inc", {
- {0x0640,"PCI0640"},
- {0x0643,"PCI0643"},
- {0x0646,"PCI0646"},
- {0x0650,"PBC0650A"},
- {0x0670,"670"},
- }},
- {0x1096, "Alacron", {
- }},
- {0x1097, "Appian Technology", {
- }},
- {0x1098, "Quantum Designs (H.K.) Ltd", {
- {0x0001,"QD-8500"},
- {0x0002,"QD-8580"},
- }},
- {0x1099, "Samsung Electronics Co., Ltd", {
- }},
- {0x109a, "Packard Bell", {
- }},
- {0x109b, "Gemlight Computer Ltd.", {
- }},
- {0x109c, "Megachips Corporation", {
- }},
- {0x109d, "Zida Technologies Ltd.", {
- }},
- {0x109e, "Brooktree Corporation", {
- {0x0350,"Bt848"},
- {0x0351,"Bt849A"},
- {0x8472,"Bt8472"},
- {0x8474,"Bt8474"},
- }},
- {0x109f, "Trigem Computer Inc.", {
- }},
- {0x10a0, "Meidensha Corporation", {
- }},
- {0x10a1, "Juko Electronics Ind. Co. Ltd", {
- }},
- {0x10a2, "Quantum Corporation", {
- }},
- {0x10a3, "Everex Systems Inc", {
- }},
- {0x10a4, "Globe Manufacturing Sales", {
- }},
- {0x10a5, "Racal Interlan", {
- }},
- {0x10a6, "Informtech Industrial Ltd.", {
- }},
- {0x10a7, "Benchmarq Microelectronics", {
- }},
- {0x10a8, "Sierra Semiconductor", {
- {0x0000,"STB Horizon 64"},
- }},
- {0x10a9, "Silicon Graphics", {
- }},
- {0x10aa, "ACC Microelectronics", {
- {0x0000,"ACCM 2188"},
- }},
- {0x10ab, "Digicom", {
- }},
- {0x10ac, "Honeywell IAC", {
- }},
- {0x10ad, "Symphony Labs", {
- {0x0001,"W83769F"},
- {0x0103,"SL82c103"},
- {0x0105,"SL82c105"},
- {0x0565,"W83C553"},
- }},
- {0x10ae, "Cornerstone Technology", {
- }},
- {0x10af, "Micro Computer Systems Inc", {
- }},
- {0x10b0, "CardExpert Technology", {
- }},
- {0x10b1, "Cabletron Systems Inc", {
- }},
- {0x10b2, "Raytheon Company", {
- }},
- {0x10b3, "Databook Inc", {
- {0x3106,"DB87144"},
- {0xb106,"DB87144"},
- }},
- {0x10b4, "STB Systems Inc", {
- }},
- {0x10b5, "PLX Technology, Inc.", {
- {0x9036,"9036"},
- {0x9060,"9060"},
- {0x906e,"9060ES"},
- {0x9080,"9080"},
- }},
- {0x10b6, "Madge Networks", {
- {0x0001,"Smart"},
- {0x0002,"Smart 16/4 BM Mk2 PCI Ringnode"},
- {0x1001,"Collage 155 Server"},
- }},
- {0x10b7, "3Com Corporation", {
- {0x0001,"3c985 1000BaseSX"},
- {0x3390,"Token Link Velocity"},
- {0x5900,"3c590 10BaseT [Vortex]"},
- {0x5950,"3c595 100BaseTX [Vortex]"},
- {0x5951,"3c595 100BaseT4 [Vortex]"},
- {0x5952,"3c595 100Base-MII [Vortex]"},
- {0x9000,"3c900 10BaseT [Boomerang]"},
- {0x9001,"3c900 Combo [Boomerang]"},
- {0x9050,"3c905 100BaseTX [Boomerang]"},
- {0x9051,"3c905 100BaseT4"},
- {0x9055,"3c905B 100BaseTX [Cyclone]"},
- }},
- {0x10b8, "Standard Microsystems", {
- {0x0005,"9432 TX"},
- {0x1000,"37c665"},
- {0x1001,"37C922"},
- }},
- {0x10b9, "Acer Laboratories Inc.", {
- {0x1435,"M1435"},
- {0x1445,"M1445"},
- {0x1449,"M1449"},
- {0x1451,"M1451"},
- {0x1461,"M1461"},
- {0x1489,"M1489"},
- {0x1511,"M1511"},
- {0x1513,"M1513"},
- {0x1521,"M1521"},
- {0x1523,"M1523"},
- {0x1531,"M1531"},
- {0x1533,"M1533"},
- {0x1541,"M1541"},
- {0x1543,"M1543"},
- {0x3141,"M3141"},
- {0x3143,"M3143"},
- {0x3145,"M3145"},
- {0x3147,"M3147"},
- {0x3149,"M3149"},
- {0x3151,"M3151"},
- {0x3307,"M3307"},
- {0x5215,"M4803"},
- {0x5217,"m5217h"},
- {0x5219,"M5219"},
- {0x5229,"M5229"},
- {0x5235,"m5225"},
- {0x5237,"M5237"},
- {0x7101,"M7101"},
- }},
- {0x10ba, "Mitsubishi Electric Corp.", {
- }},
- {0x10bb, "Dapha Electronics Corporation", {
- }},
- {0x10bc, "Advanced Logic Research", {
- }},
- {0x10bd, "Surecom Technology", {
- {0x0e34,"NE-34PCI LAN"},
- }},
- {0x10be, "Tseng Labs International Co.", {
- }},
- {0x10bf, "Most Inc", {
- }},
- {0x10c0, "Boca Research Inc.", {
- }},
- {0x10c1, "ICM Co., Ltd.", {
- }},
- {0x10c2, "Auspex Systems Inc.", {
- }},
- {0x10c3, "Samsung Semiconductors, Inc.", {
- }},
- {0x10c4, "Award Software International Inc.", {
- }},
- {0x10c5, "Xerox Corporation", {
- }},
- {0x10c6, "Rambus Inc.", {
- }},
- {0x10c7, "Media Vision", {
- }},
- {0x10c8, "Neomagic Corporation", {
- {0x0001,"NM2070 [MagicGraph NM2070]"},
- {0x0002,"NM2090 [MagicGraph 128V]"},
- {0x0003,"NM2093 [MagicGraph 128ZV]"},
- {0x0004,"NM2160 [MagicGraph 128XD]"},
- }},
- {0x10c9, "Dataexpert Corporation", {
- }},
- {0x10ca, "Fujitsu Microelectr., Inc.", {
- }},
- {0x10cb, "Omron Corporation", {
- }},
- {0x10cc, "Mentor ARC Inc", {
- }},
- {0x10cd, "Advanced System Products, Inc", {
- {0x1200,"ASC1200 [(abp940) Fast SCSI-II]"},
- {0x1300,"ABP940-U"},
- {0x2300,"ABP940-UW"},
- }},
- {0x10ce, "Radius", {
- }},
- {0x10cf, "Citicorp TTI", {
- {0x2001,"mb86605"},
- }},
- {0x10d0, "Fujitsu Limited", {
- }},
- {0x10d1, "FuturePlus Systems Corp.", {
- }},
- {0x10d2, "Molex Incorporated", {
- }},
- {0x10d3, "Jabil Circuit Inc", {
- }},
- {0x10d4, "Hualon Microelectronics", {
- }},
- {0x10d5, "Autologic Inc.", {
- }},
- {0x10d6, "Cetia", {
- }},
- {0x10d7, "BCM Advanced Research", {
- }},
- {0x10d8, "Advanced Peripherals Labs", {
- }},
- {0x10d9, "Macronix, Inc.", {
- {0x0512,"MX98713"},
- {0x0531,"MX987x5"},
- }},
- {0x10da, "Compaq IPG-Austin", {
- }},
- {0x10db, "Rohm LSI Systems, Inc.", {
- }},
- {0x10dc, "CERN/ECP/EDU", {
- {0x0001,"STAR/RD24 SCI-PCI (PMC)"},
- {0x0002,"TAR/RD24 SCI-PCI (PMC) [ATT 2C15-3 (FPGA) SCI bridge on PCI 5 Volt card]"},
- {0x0021,"HIPPI destination"},
- {0x0022,"HIPPI source"},
- }},
- {0x10dd, "Evans & Sutherland", {
- }},
- {0x10de, "Nvidia Corporation", {
- {0x0008,"NV1"},
- {0x0009,"DAC64"},
- }},
- {0x10df, "Emulex Corporation", {
- }},
- {0x10e0, "Integrated Micro Solutions Inc.", {
- {0x5026,"IMS5026/27/28"},
- {0x8849,"8849"},
- {0x9128,"IMS9129"},
- }},
- {0x10e1, "Tekram Technology Co.,Ltd.", {
- {0x690c,"690c"},
- {0xdc29,"DC290"},
- }},
- {0x10e2, "Aptix Corporation", {
- }},
- {0x10e3, "Tundra Semiconductor Corp.", {
- {0x0000,"CA91C042 [Universe]"},
- {0x0860,"CA91C860 [QSpan]"},
- }},
- {0x10e4, "Tandem Computers", {
- }},
- {0x10e5, "Micro Industries Corporation", {
- }},
- {0x10e6, "Gainbery Computer Products Inc.", {
- }},
- {0x10e7, "Vadem", {
- }},
- {0x10e8, "Applied Micro Circuits Corporation", {
- {0x5920,"S5920"},
- {0x8043,"LANai4.x [Myrinet LANai interface chip]"},
- {0x8062,"S5933_PARASTATION"},
- {0x807d,"S5933 [Matchmaker]"},
- {0x809c,"S5933_HEPC3"},
- }},
- {0x10e9, "Alps Electric Co., Ltd.", {
- }},
- {0x10ea, "Intergraphics Systems", {
- {0x1680,"IGA-1680"},
- {0x1682,"IGA-1682"},
- }},
- {0x10eb, "Artists Graphics", {
- {0x0101,"3GA"},
- }},
- {0x10ec, "Realtek Semiconductor Co., Ltd.", {
- {0x8029,"8029"},
- {0x8129,"8129"},
- {0x8139,"8139"},
- }},
- {0x10ed, "Ascii Corporation", {
- {0x7310,"V7310"},
- }},
- {0x10ee, "Xilinx, Inc.", {
- }},
- {0x10ef, "Racore Computer Products, Inc.", {
- }},
- {0x10f0, "Peritek Corporation", {
- }},
- {0x10f1, "Tyan Computer", {
- }},
- {0x10f2, "Achme Computer, Inc.", {
- }},
- {0x10f3, "Alaris, Inc.", {
- }},
- {0x10f4, "S-MOS Systems, Inc.", {
- }},
- {0x10f5, "NKK Corporation", {
- {0xa001,"NDR4000 [NR4600 Bridge]"},
- }},
- {0x10f6, "Creative Electronic Systems SA", {
- }},
- {0x10f7, "Matsushita Electric Industrial Co., Ltd.", {
- }},
- {0x10f8, "Altos India Ltd", {
- }},
- {0x10f9, "PC Direct", {
- }},
- {0x10fa, "Truevision", {
- {0x000c,"TARGA 1000"},
- }},
- {0x10fb, "Thesys Gesellschaft f€r Mikroelektronik mbH", {
- }},
- {0x10fc, "I-O Data Device, Inc.", {
- }},
- {0x10fd, "Soyo Computer, Inc", {
- }},
- {0x10fe, "Fast Multimedia AG", {
- }},
- {0x10ff, "NCube", {
- }},
- {0x1100, "Jazz Multimedia", {
- }},
- {0x1101, "Initio Corporation", {
- {0x9100,"320 P"},
- {0x9500,"360P"},
- }},
- {0x1102, "Creative Labs", {
- }},
- {0x1103, "Triones Technologies, Inc.", {
- }},
- {0x1104, "RasterOps Corp.", {
- }},
- {0x1105, "Sigma Designs, Inc.", {
- }},
- {0x1106, "VIA Technologies, Inc.", {
- {0x0505,"VT 82C505"},
- {0x0561,"VT 82C561"},
- {0x0571,"VT82C586 IDE [Apollo]"},
- {0x0576,"VT 82C576 3V [Apollo Master]"},
- {0x0585,"VT82C585VP [Apollo VP1/VPX]"},
- {0x0586,"VT82C586 ISA [Apollo VP]"},
- {0x0595,"VT82C595 [Apollo VP2]"},
- {0x0597,"VT82C597 [Apollo VP3]"},
- {0x0926,"VT82C926 [Amazon]"},
- {0x1000,"82C570MV"},
- {0x1106,"82C570MV"},
- {0x1571,"VT 82C416MV"},
- {0x1595,"VT82C595/97 [Apollo VP2/97]"},
- {0x3038,"VT82C586B USB"},
- {0x3040,"VT82C586B ACPI"},
- {0x6100,"VT85C100A [Rhine II]"},
- {0x8597,"VT82C597 [Apollo VP3 AGP]"},
- }},
- {0x1107, "Stratus Computers", {
- }},
- {0x1108, "Proteon, Inc.", {
- {0x0100,"p1690plus_AA"},
- {0x0101,"p1690plus_AB"},
- }},
- {0x1109, "Cogent Data Technologies, Inc.", {
- {0x1400,"EM110TX [EX110TX PCI Fast Ethernet Adapter]"},
- }},
- {0x110a, "Siemens Nixdorf AG", {
- {0x6120,"SZB6120"},
- }},
- {0x110b, "Chromatic Research Inc.", {
- }},
- {0x110c, "Mini-Max Technology, Inc.", {
- }},
- {0x110d, "Znyx Advanced Systems", {
- }},
- {0x110e, "CPU Technology", {
- }},
- {0x110f, "Ross Technology", {
- }},
- {0x1110, "Powerhouse Systems", {
- }},
- {0x1111, "Santa Cruz Operation", {
- }},
- {0x1112, "RNS - Div. of Meret Communications Inc", {
- }},
- {0x1113, "Accton Technology Corporation", {
- }},
- {0x1114, "Atmel Corporation", {
- }},
- {0x1115, "3D Labs", {
- }},
- {0x1116, "Data Translation", {
- }},
- {0x1117, "Datacube, Inc", {
- }},
- {0x1118, "Berg Electronics", {
- }},
- {0x1119, "ICP Vortex Computersysteme GmbH", {
- {0x0000,"GDT6000/6020/6050"},
- {0x0001,"GDT6000b/6010"},
- {0x0002,"GDT6110/6510"},
- {0x0003,"GDT6120/6520"},
- {0x0004,"GDT6530"},
- {0x0005,"GDT6550"},
- {0x0006,"GDT6x17"},
- {0x0007,"GDT6x27"},
- {0x0008,"GDT6537"},
- {0x0009,"GDT5557"},
- {0x000a,"GDT6x15"},
- {0x000b,"GDT6x25"},
- {0x000c,"GDT6535"},
- {0x000d,"GDT6555"},
- {0x0100,"GDT 6117RP/6517RP"},
- {0x0101,"GDT 6127RP/6527RP"},
- {0x0102,"GDT 6537RP"},
- {0x0103,"GDT 6557RP"},
- {0x0104,"GDT 6111RP/6511RP"},
- {0x0105,"GDT 6121RP/6521RP"},
- {0x0110,"GDT 6117RP1/6517RP1"},
- {0x0111,"GDT 6127RP1/6527RP1"},
- {0x0112,"GDT 6537RP1"},
- {0x0113,"GDT 6557RP1"},
- {0x0114,"GDT 6111RP1/6511RP1"},
- {0x0115,"GDT 6121RP1/6521RP1"},
- {0x0120,"GDT 6117RP2/6517RP2"},
- {0x0121,"GDT 6127RP2/6527RP2"},
- {0x0122,"GDT 6537RP2"},
- {0x0123,"GDT 6557RP2"},
- {0x0124,"GDT 6111RP2/6511RP2"},
- {0x0125,"GDT 6121RP2/6521RP2"},
- }},
- {0x111a, "Efficient Networks, Inc", {
- {0x0000,"155P-MF1 (FPGA)"},
- {0x0002,"155P-MF1 (ASIC)"},
- }},
- {0x111b, "Teledyne Electronic Systems", {
- }},
- {0x111c, "Tricord Systems Inc.", {
- }},
- {0x111d, "Integrated Device Tech", {
- }},
- {0x111e, "Eldec", {
- }},
- {0x111f, "Precision Digital Images", {
- }},
- {0x1120, "EMC Corporation", {
- }},
- {0x1121, "Zilog", {
- }},
- {0x1122, "Multi-tech Systems, Inc.", {
- }},
- {0x1123, "Excellent Design, Inc.", {
- }},
- {0x1124, "Leutron Vision AG", {
- }},
- {0x1125, "Eurocore", {
- }},
- {0x1127, "FORE Systems Inc", {
- {0x0210,"PCA-200PC"},
- {0x0300,"PCA-200E"},
- }},
- {0x1129, "Firmworks", {
- }},
- {0x112a, "Hermes Electronics Company, Ltd.", {
- }},
- {0x112b, "Linotype - Hell AG", {
- }},
- {0x112c, "Zenith Data Systems", {
- }},
- {0x112d, "Ravicad", {
- }},
- {0x112e, "Infomedia Microelectronics Inc.", {
- }},
- {0x112f, "Imaging Technology Inc", {
- {0x0000,"MVC IC-PCI"},
- }},
- {0x1130, "Computervision", {
- }},
- {0x1131, "Philips Semiconductors", {
- {0x7145,"SAA7145"},
- {0x7146,"SAA7146"},
- }},
- {0x1132, "Mitel Corp.", {
- }},
- {0x1133, "Eicon Technology Corporation", {
- {0xe001,"DIVA20PRO"},
- {0xe002,"DIVA20"},
- {0xe003,"DIVA20PRO_U"},
- {0xe004,"DIVA20_U"},
- }},
- {0x1134, "Mercury Computer Systems", {
- }},
- {0x1135, "Fuji Xerox Co Ltd", {
- }},
- {0x1136, "Momentum Data Systems", {
- }},
- {0x1137, "Cisco Systems Inc", {
- }},
- {0x1138, "Ziatech Corporation", {
- {0x8905,"8905 [STD 32 Bridge]"},
- }},
- {0x1139, "Dynamic Pictures, Inc", {
- }},
- {0x113a, "FWB Inc", {
- }},
- {0x113b, "Network Computing Devices", {
- }},
- {0x113c, "Cyclone Microsystems, Inc.", {
- {0x0001,"PCI-SDK [PCI i960 Evaluation Platform]"},
- {0x0911,"PCI-911 [PCI-based i960Jx Intelligent I/O Controller]"},
- {0x0912,"PCI-912 [i960CF-based Intelligent I/O Controller]"},
- {0x0913,"PCI-913"},
- }},
- {0x113d, "Leading Edge Products Inc", {
- }},
- {0x113e, "Sanyo Electric Co - Computer Engineering Dept", {
- }},
- {0x113f, "Equinox Systems, Inc.", {
- }},
- {0x1140, "Intervoice Inc", {
- }},
- {0x1141, "Crest Microsystem Inc", {
- }},
- {0x1142, "Alliance Semiconductor Corporation", {
- {0x3210,"AP6410"},
- {0x6422,"AP6422"},
- {0x6424,"AT24"},
- {0x643d,"AT3D"},
- }},
- {0x1143, "NetPower, Inc", {
- }},
- {0x1144, "Cincinnati Milacron", {
- }},
- {0x1145, "Workbit Corporation", {
- }},
- {0x1146, "Force Computers", {
- }},
- {0x1147, "Interface Corp", {
- }},
- {0x1148, "Schneider & Koch", {
- }},
- {0x1149, "Win System Corporation", {
- }},
- {0x114a, "VMIC", {
- {0x7587,"VMIVME-7587"},
- }},
- {0x114b, "Canopus Co., Ltd", {
- }},
- {0x114c, "Annabooks", {
- }},
- {0x114d, "IC Corporation", {
- }},
- {0x114e, "Nikon Systems Inc", {
- }},
- {0x114f, "Digi International", {
- {0x0002,"AccelePort EPC"},
- {0x0003,"RightSwitch SE-6"},
- {0x0004,"AccelePort Xem"},
- {0x0006,"AccelePort Xr,C/X"},
- {0x0009,"AccelePort Xr/J"},
- {0x000a,"AccelePort EPC/J"},
- {0x0027,"AccelePort Xr 920"},
- }},
- {0x1150, "Thinking Machines Corp", {
- }},
- {0x1151, "JAE Electronics Inc.", {
- }},
- {0x1152, "Megatek", {
- }},
- {0x1153, "Land Win Electronic Corp", {
- }},
- {0x1154, "Melco Inc", {
- }},
- {0x1155, "Pine Technology Ltd", {
- }},
- {0x1156, "Periscope Engineering", {
- }},
- {0x1157, "Avsys Corporation", {
- }},
- {0x1158, "Voarx R & D Inc", {
- }},
- {0x1159, "Mutech Corp", {
- {0x0001,"MV-1000"},
- }},
- {0x115a, "Harlequin Ltd", {
- }},
- {0x115b, "Parallax Graphics", {
- }},
- {0x115c, "Photron Ltd.", {
- }},
- {0x115d, "Xircom", {
- }},
- {0x115e, "Peer Protocols Inc", {
- }},
- {0x115f, "Maxtor Corporation", {
- }},
- {0x1160, "Megasoft Inc", {
- }},
- {0x1161, "PFU Limited", {
- }},
- {0x1162, "OA Laboratory Co Ltd", {
- }},
- {0x1163, "Rendition", {
- {0x0001,"Verite 1000 PCI"},
- {0x2000,"Verite V2100"},
- }},
- {0x1164, "Advanced Peripherals Technologies", {
- }},
- {0x1165, "Imagraph Corporation", {
- }},
- {0x1166, "Pequr Technology", {
- }},
- {0x1167, "Mutoh Industries Inc", {
- }},
- {0x1168, "Thine Electronics Inc", {
- }},
- {0x1169, "Centre for Development of Advanced Computing", {
- }},
- {0x116a, "Polaris Communications", {
- }},
- {0x116b, "Connectware Inc", {
- }},
- {0x116c, "Intelligent Resources Integrated Systems", {
- }},
- {0x116d, "Martin-Marietta", {
- }},
- {0x116e, "Electronics for Imaging", {
- }},
- {0x116f, "Workstation Technology", {
- }},
- {0x1170, "Inventec Corporation", {
- }},
- {0x1171, "Loughborough Sound Images Plc", {
- }},
- {0x1172, "Altera Corporation", {
- }},
- {0x1173, "Adobe Systems, Inc", {
- }},
- {0x1174, "Bridgeport Machines", {
- }},
- {0x1175, "Mitron Computer Inc.", {
- }},
- {0x1176, "SBE Incorporated", {
- }},
- {0x1177, "Silicon Engineering", {
- }},
- {0x1178, "Alfa, Inc.", {
- }},
- {0x1179, "Toshiba America Info Systems", {
- {0x0601,"601"},
- {0x060a,"ToPIC95"},
- {0x060f,"ToPIC97"},
- {0x0701,"Lucent DSP1645 [Mars]"},
- }},
- {0x117b, "L G Electronics, Inc.", {
- }},
- {0x117c, "Atto Technology", {
- }},
- {0x117d, "Becton & Dickinson", {
- }},
- {0x117e, "T/R Systems", {
- }},
- {0x117f, "Integrated Circuit Systems", {
- }},
- {0x1180, "Ricoh Co Ltd", {
- {0x0466,"RL5C466"},
- }},
- {0x1181, "Telmatics International", {
- }},
- {0x1183, "Fujikura Ltd", {
- }},
- {0x1184, "Forks Inc", {
- }},
- {0x1185, "Dataworld International Ltd", {
- }},
- {0x1186, "D-Link System Inc", {
- }},
- {0x1187, "Advanced Technology Laboratories, Inc.", {
- }},
- {0x1188, "Shima Seiki Manufacturing Ltd.", {
- }},
- {0x1189, "Matsushita Electronics Co Ltd", {
- }},
- {0x118a, "Hilevel Technology", {
- }},
- {0x118b, "Hypertec Pty Limited", {
- }},
- {0x118c, "Corollary, Inc", {
- {0x0014,"PCIB [C-bus II to PCI bus host bridge chip]"},
- }},
- {0x118d, "BitFlow Inc", {
- {0x0001,"n/a [Raptor-PCI framegrabber]"},
- }},
- {0x118e, "Hermstedt GmbH", {
- }},
- {0x118f, "Green Logic", {
- }},
- {0x1191, "Artop Electronic Corp", {
- {0x0004,"ATP8400"},
- {0x0005,"ATP850UF"},
- }},
- {0x1192, "Densan Company Ltd", {
- }},
- {0x1193, "Zeitnet Inc.", {
- {0x0001,"1221"},
- {0x0002,"1225"},
- }},
- {0x1194, "Toucan Technology", {
- }},
- {0x1195, "Ratoc System Inc", {
- }},
- {0x1196, "Hytec Electronics Ltd", {
- }},
- {0x1197, "Gage Applied Sciences, Inc.", {
- }},
- {0x1198, "Lambda Systems Inc", {
- }},
- {0x1199, "Attachmate Corporation", {
- }},
- {0x119a, "Mind Share, Inc.", {
- }},
- {0x119b, "Omega Micro Inc.", {
- {0x1221,"82C092G"},
- }},
- {0x119c, "Information Technology Inst.", {
- }},
- {0x119d, "Bug, Inc. Sapporo Japan", {
- }},
- {0x119e, "Fujitsu Microelectronics Ltd.", {
- }},
- {0x119f, "Bull HN Information Systems", {
- }},
- {0x11a0, "Convex Computer Corporation", {
- }},
- {0x11a1, "Hamamatsu Photonics K.K.", {
- }},
- {0x11a2, "Sierra Research and Technology", {
- }},
- {0x11a3, "Deuretzbacher GmbH & Co. Eng. KG", {
- }},
- {0x11a4, "Barco Graphics NV", {
- }},
- {0x11a5, "Microunity Systems Eng. Inc", {
- }},
- {0x11a6, "Pure Data Ltd.", {
- }},
- {0x11a7, "Power Computing Corp.", {
- }},
- {0x11a8, "Systech Corp.", {
- }},
- {0x11a9, "InnoSys Inc.", {
- }},
- {0x11aa, "Actel", {
- }},
- {0x11ab, "Galileo Technology Ltd.", {
- {0x0146,"GT-64010"},
- {0x4801,"GT-48001"},
- }},
- {0x11ac, "Canon Information Systems Research Aust.", {
- }},
- {0x11ad, "Lite-On Communications Inc", {
- {0x0002,"LNE100TX"},
- }},
- {0x11ae, "Aztech System Ltd", {
- }},
- {0x11af, "Avid Technology Inc.", {
- }},
- {0x11b0, "V3 Semiconductor Inc.", {
- {0x0292,"V292PBC [Am29030/40 Bridge]"},
- {0x0960,"V96xPBC"},
- {0xc960,"V96DPC"},
- }},
- {0x11b1, "Apricot Computers", {
- }},
- {0x11b2, "Eastman Kodak", {
- }},
- {0x11b3, "Barr Systems Inc.", {
- }},
- {0x11b4, "Leitch Technology International", {
- }},
- {0x11b5, "Radstone Technology Plc", {
- }},
- {0x11b6, "United Video Corp", {
- }},
- {0x11b8, "XPoint Technologies, Inc", {
- }},
- {0x11b9, "Pathlight Technology Inc.", {
- }},
- {0x11ba, "Videotron Corp", {
- }},
- {0x11bb, "Pyramid Technology", {
- }},
- {0x11bc, "Network Peripherals Inc", {
- {0x0001,"NP-PCI"},
- }},
- {0x11bd, "Pinnacle Systems Inc.", {
- }},
- {0x11be, "International Microcircuits Inc", {
- }},
- {0x11bf, "Astrodesign, Inc.", {
- }},
- {0x11c0, "Hewlett Packard", {
- }},
- {0x11c1, "Lucent Microelectronics", {
- {0x0440,"L56xMF"},
- }},
- {0x11c2, "Sand Microelectronics", {
- }},
- {0x11c4, "Document Technologies, Inc", {
- }},
- {0x11c5, "Shiva Corporation", {
- }},
- {0x11c6, "Dainippon Screen Mfg. Co. Ltd", {
- }},
- {0x11c7, "D.C.M. Data Systems", {
- }},
- {0x11c8, "Dolphin Interconnect Solutions AS", {
- {0x0658,"PSB"},
- }},
- {0x11c9, "Magma", {
- }},
- {0x11ca, "LSI Systems, Inc", {
- }},
- {0x11cb, "Specialix Research Ltd.", {
- {0x2000,"PCI_9050"},
- {0x4000,"SUPI_1"},
- {0x8000,"T225"},
- }},
- {0x11cc, "Michels & Kleberhoff Computer GmbH", {
- }},
- {0x11cd, "HAL Computer Systems, Inc.", {
- }},
- {0x11ce, "Netaccess", {
- }},
- {0x11cf, "Pioneer Electronic Corporation", {
- }},
- {0x11d0, "Lockheed Martin Federal Systems-Manassas", {
- }},
- {0x11d1, "Auravision", {
- {0x01f7,"VxP524"},
- }},
- {0x11d2, "Intercom Inc.", {
- }},
- {0x11d3, "Trancell Systems Inc", {
- }},
- {0x11d4, "Analog Devices", {
- }},
- {0x11d5, "Ikon Corporation", {
- {0x0115,"10115"},
- {0x0117,"10117"},
- }},
- {0x11d6, "Tekelec Telecom", {
- }},
- {0x11d7, "Trenton Technology, Inc.", {
- }},
- {0x11d8, "Image Technologies Development", {
- }},
- {0x11d9, "TEC Corporation", {
- }},
- {0x11da, "Novell", {
- }},
- {0x11db, "Sega Enterprises Ltd", {
- }},
- {0x11dc, "Questra Corporation", {
- }},
- {0x11dd, "Crosfield Electronics Limited", {
- }},
- {0x11de, "Zoran Corporation", {
- {0x6057,"ZR36057"},
- {0x6120,"ZR36120"},
- }},
- {0x11df, "New Wave PDG", {
- }},
- {0x11e0, "Cray Communications A/S", {
- }},
- {0x11e1, "GEC Plessey Semi Inc.", {
- }},
- {0x11e2, "Samsung Information Systems America", {
- }},
- {0x11e3, "Quicklogic Corporation", {
- }},
- {0x11e4, "Second Wave Inc", {
- }},
- {0x11e5, "IIX Consulting", {
- }},
- {0x11e6, "Mitsui-Zosen System Research", {
- }},
- {0x11e7, "Toshiba America, Elec. Company", {
- }},
- {0x11e8, "Digital Processing Systems Inc.", {
- }},
- {0x11e9, "Highwater Designs Ltd.", {
- }},
- {0x11ea, "Elsag Bailey", {
- }},
- {0x11eb, "Formation Inc.", {
- }},
- {0x11ec, "Coreco Inc", {
- }},
- {0x11ed, "Mediamatics", {
- }},
- {0x11ee, "Dome Imaging Systems Inc", {
- }},
- {0x11ef, "Nicolet Technologies B.V.", {
- }},
- {0x11f0, "Compu-Shack GmbH", {
- }},
- {0x11f1, "Symbios Logic Inc", {
- }},
- {0x11f2, "Picture Tel Japan K.K.", {
- }},
- {0x11f3, "Keithley Metrabyte", {
- }},
- {0x11f4, "Kinetic Systems Corporation", {
- {0x2915,"CAMAC controller"},
- }},
- {0x11f5, "Computing Devices International", {
- }},
- {0x11f6, "Compex", {
- {0x0112,"ENet100VG4"},
- {0x1401,"ReadyLink 2000"},
- }},
- {0x11f7, "Scientific Atlanta", {
- }},
- {0x11f8, "PMC-Sierra Inc.", {
- {0x7375,"PM7375 [LASAR-155 ATM SAR]"},
- }},
- {0x11f9, "I-Cube Inc", {
- }},
- {0x11fa, "Kasan Electronics Company, Ltd.", {
- }},
- {0x11fb, "Datel Inc", {
- }},
- {0x11fc, "Silicon Magic", {
- }},
- {0x11fd, "High Street Consultants", {
- }},
- {0x11fe, "Comtrol Corporation", {
- {0x0001,"RocketPort 8 Oct"},
- {0x0002,"RocketPort 8 Intf"},
- {0x0003,"RocketPort 16 Intf"},
- {0x0004,"RocketPort 32 Intf"},
- }},
- {0x11ff, "Scion Corporation", {
- }},
- {0x1200, "CSS Corporation", {
- }},
- {0x1201, "Vista Controls Corp", {
- }},
- {0x1202, "Network General Corp.", {
- }},
- {0x1203, "Bayer Corporation, Agfa Division", {
- }},
- {0x1204, "Lattice Semiconductor Corporation", {
- }},
- {0x1205, "Array Corporation", {
- }},
- {0x1206, "Amdahl Corporation", {
- }},
- {0x1208, "Parsytec GmbH", {
- }},
- {0x1209, "SCI Systems Inc", {
- }},
- {0x120a, "Synaptel", {
- }},
- {0x120b, "Adaptive Solutions", {
- }},
- {0x120c, "Technical Corp.", {
- }},
- {0x120d, "Compression Labs, Inc.", {
- }},
- {0x120e, "Cyclades Corporation", {
- {0x0100,"Cyclom_Y"},
- {0x0200,"Cyclom_Z"},
- }},
- {0x120f, "Essential Communications", {
- {0x0001,"Roadrunner serial HIPPI"},
- }},
- {0x1210, "Hyperparallel Technologies", {
- }},
- {0x1211, "Braintech Inc", {
- }},
- {0x1212, "Kingston Technology Corp.", {
- }},
- {0x1213, "Applied Intelligent Systems, Inc.", {
- }},
- {0x1214, "Performance Technologies, Inc.", {
- }},
- {0x1215, "Interware Co., Ltd", {
- }},
- {0x1216, "Purup Prepress A/S", {
- }},
- {0x1217, "O2 Micro, Inc.", {
- {0x6729,"6729"},
- {0x673a,"6730"},
- {0x6832,"6832"},
- }},
- {0x1218, "Hybricon Corp.", {
- }},
- {0x1219, "First Virtual Corporation", {
- }},
- {0x121a, "3Dfx Interactive, Inc.", {
- {0x0001,"Voodoo"},
- {0x0002,"Voodoo2"},
- }},
- {0x121b, "Advanced Telecommunications Modules", {
- }},
- {0x121c, "Nippon Texaco., Ltd", {
- }},
- {0x121d, "Lippert Automationstechnik GmbH", {
- }},
- {0x121e, "CSPI", {
- }},
- {0x121f, "Arcus Technology, Inc.", {
- }},
- {0x1220, "Ariel Corporation", {
- }},
- {0x1221, "Contec Co., Ltd", {
- }},
- {0x1222, "Ancor Communications, Inc.", {
- }},
- {0x1223, "Heurikon/Computer Products", {
- }},
- {0x1224, "Interactive Images", {
- }},
- {0x1225, "Power I/O, Inc.", {
- }},
- {0x1227, "Tech-Source", {
- }},
- {0x1228, "Norsk Elektro Optikk A/S", {
- }},
- {0x1229, "Data Kinesis Inc.", {
- }},
- {0x122a, "Integrated Telecom", {
- }},
- {0x122b, "LG Industrial Systems Co., Ltd", {
- }},
- {0x122c, "Sican GmbH", {
- }},
- {0x122d, "Aztech System Ltd", {
- }},
- {0x122e, "Xyratex", {
- }},
- {0x122f, "Andrew Corporation", {
- }},
- {0x1230, "Fishcamp Engineering", {
- }},
- {0x1231, "Woodward McCoach, Inc.", {
- }},
- {0x1232, "GPT Limited", {
- }},
- {0x1233, "Bus-Tech, Inc.", {
- }},
- {0x1234, "Technical Corp.", {
- }},
- {0x1235, "Risq Modular Systems, Inc.", {
- }},
- {0x1236, "Sigma Designs Corporation", {
- {0x6401,"REALmagic 64/GX (SD 6425)"},
- }},
- {0x1237, "Alta Technology Corporation", {
- }},
- {0x1238, "Adtran", {
- }},
- {0x1239, "3DO Company", {
- }},
- {0x123a, "Visicom Laboratories, Inc.", {
- }},
- {0x123b, "Seeq Technology, Inc.", {
- }},
- {0x123c, "Century Systems, Inc.", {
- }},
- {0x123d, "Engineering Design Team, Inc.", {
- }},
- {0x123e, "Simutech, Inc.", {
- }},
- {0x123f, "C-Cube Microsystems", {
- {0x00e4,"MPEG"},
- }},
- {0x1240, "Marathon Technologies Corp.", {
- }},
- {0x1241, "DSC Communications", {
- }},
- {0x1243, "Delphax", {
- }},
- {0x1244, "AVM Audiovisuelles MKTG & Computer System GmbH", {
- }},
- {0x1245, "A.P.D., S.A.", {
- }},
- {0x1246, "Dipix Technologies, Inc.", {
- }},
- {0x1247, "Xylon Research, Inc.", {
- }},
- {0x1248, "Central Data Corporation", {
- }},
- {0x1249, "Samsung Electronics Co., Ltd.", {
- }},
- {0x124a, "AEG Electrocom GmbH", {
- }},
- {0x124b, "SBS/Greenspring Modular I/O", {
- }},
- {0x124c, "Solitron Technologies, Inc.", {
- }},
- {0x124d, "Stallion Technologies, Inc.", {
- {0x0000,"EasyConnection 8/32 - PCI"},
- {0x0002,"EasyConnection 8/64 - PCI"},
- {0x0003,"EasyIO - PCI"},
- }},
- {0x124e, "Cylink", {
- }},
- {0x124f, "Infotrend Technology, Inc.", {
- }},
- {0x1250, "Hitachi Microcomputer System Ltd", {
- }},
- {0x1251, "VLSI Solutions Oy", {
- }},
- {0x1253, "Guzik Technical Enterprises", {
- }},
- {0x1254, "Linear Systems Ltd.", {
- }},
- {0x1255, "Optibase Ltd", {
- {0x1110,"MPEG Forge"},
- {0x1210,"MPEG Fusion"},
- {0x2110,"VideoPlex"},
- {0x2120,"VideoPlex CC"},
- {0x2130,"VideoQuest"},
- }},
- {0x1256, "Perceptive Solutions, Inc.", {
- }},
- {0x1257, "Vertex Networks, Inc.", {
- }},
- {0x1258, "Gilbarco, Inc.", {
- }},
- {0x1259, "Allied Telesyn International", {
- }},
- {0x125a, "ABB Power Systems", {
- }},
- {0x125b, "Asix Electronics Corporation", {
- }},
- {0x125c, "Aurora Technologies, Inc.", {
- }},
- {0x125d, "ESS Technology", {
- }},
- {0x125e, "Specialvideo Engineering SRL", {
- }},
- {0x125f, "Concurrent Technologies, Inc.", {
- }},
- {0x1260, "Harris Semiconductor", {
- }},
- {0x1261, "Matsushita-Kotobuki Electronics Industries, Ltd.", {
- }},
- {0x1262, "ES Computer Company, Ltd.", {
- }},
- {0x1263, "Sonic Solutions", {
- }},
- {0x1264, "Aval Nagasaki Corporation", {
- }},
- {0x1265, "Casio Computer Co., Ltd.", {
- }},
- {0x1266, "Microdyne Corporation", {
- }},
- {0x1267, "S. A. Telecommunications", {
- {0x5352,"PCR2101"},
- {0x5a4b,"Telsat Turbo"},
- }},
- {0x1268, "Tektronix", {
- }},
- {0x1269, "Thomson-CSF/TTM", {
- }},
- {0x126a, "Lexmark International, Inc.", {
- }},
- {0x126b, "Adax, Inc.", {
- }},
- {0x126c, "Northern Telecom", {
- }},
- {0x126d, "Splash Technology, Inc.", {
- }},
- {0x126e, "Sumitomo Metal Industries, Ltd.", {
- }},
- {0x126f, "Silicon Motion, Inc.", {
- }},
- {0x1270, "Olympus Optical Co., Ltd.", {
- }},
- {0x1271, "GW Instruments", {
- }},
- {0x1272, "Telematics International", {
- }},
- {0x1273, "Hughes Network Systems", {
- {0x0002,"DirecPC"},
- }},
- {0x1274, "Ensoniq", {
- {0x5000,"AudioPCI"},
- }},
- {0x1275, "Network Appliance Corporation", {
- }},
- {0x1276, "Switched Network Technologies, Inc.", {
- }},
- {0x1277, "Comstream", {
- }},
- {0x1278, "Transtech Parallel Systems Ltd.", {
- }},
- {0x1279, "Transmeta Corporation", {
- }},
- {0x127a, "Rockwell International", {
- }},
- {0x127b, "Pixera Corporation", {
- }},
- {0x127c, "Crosspoint Solutions, Inc.", {
- }},
- {0x127d, "Vela Research", {
- }},
- {0x127e, "Winnov, L.P.", {
- }},
- {0x127f, "Fujifilm", {
- }},
- {0x1280, "Photoscript Group Ltd.", {
- }},
- {0x1281, "Yokogawa Electric Corporation", {
- }},
- {0x1282, "Davicom Semiconductor, Inc.", {
- }},
- {0x1283, "Integrated Technology Express, Inc.", {
- }},
- {0x1284, "Sahara Networks, Inc.", {
- }},
- {0x1285, "Platform Technologies, Inc.", {
- }},
- {0x1286, "Mazet GmbH", {
- }},
- {0x1287, "M-Pact, Inc.", {
- }},
- {0x1288, "Timestep Corporation", {
- }},
- {0x1289, "AVC Technology, Inc.", {
- }},
- {0x128a, "Asante Technologies, Inc.", {
- }},
- {0x128b, "Transwitch Corporation", {
- }},
- {0x128c, "Retix Corporation", {
- }},
- {0x128d, "G2 Networks, Inc.", {
- }},
- {0x128e, "Samho Multi Tech Ltd.", {
- }},
- {0x128f, "Tateno Dennou, Inc.", {
- }},
- {0x1290, "Sord Computer Corporation", {
- }},
- {0x1291, "NCS Computer Italia", {
- }},
- {0x1292, "Tritech Microelectronics Inc", {
- }},
- {0x1293, "Media Reality Technology", {
- }},
- {0x1294, "Rhetorex, Inc.", {
- }},
- {0x1295, "Imagenation Corporation", {
- }},
- {0x1296, "Kofax Image Products", {
- }},
- {0x1297, "Holco Enterprise Co, Ltd/Shuttle Computer", {
- }},
- {0x1298, "Spellcaster Telecommunications Inc.", {
- }},
- {0x1299, "Knowledge Technology Lab.", {
- }},
- {0x129b, "Image Access", {
- }},
- {0x129c, "Jaycor", {
- }},
- {0x129d, "Compcore Multimedia, Inc.", {
- }},
- {0x129e, "Victor Company of Japan, Ltd.", {
- }},
- {0x129f, "OEC Medical Systems, Inc.", {
- }},
- {0x12a0, "Allen-Bradley Company", {
- }},
- {0x12a1, "Simpact Associates, Inc.", {
- }},
- {0x12a2, "Newgen Systems Corporation", {
- }},
- {0x12a3, "Lucent Technologies", {
- }},
- {0x12a4, "NTT Electronics Technology Company", {
- }},
- {0x12a5, "Vision Dynamics Ltd.", {
- }},
- {0x12a6, "Scalable Networks, Inc.", {
- }},
- {0x12a7, "AMO GmbH", {
- }},
- {0x12a8, "News Datacom", {
- }},
- {0x12a9, "Xiotech Corporation", {
- }},
- {0x12aa, "SDL Communications, Inc.", {
- }},
- {0x12ab, "Yuan Yuan Enterprise Co., Ltd.", {
- }},
- {0x12ac, "Measurex Corporation", {
- }},
- {0x12ad, "Multidata GmbH", {
- }},
- {0x12ae, "Alteon Networks Inc.", {
- {0x0001,"AceNIC Gigabit Ethernet"},
- }},
- {0x12af, "TDK USA Corp", {
- }},
- {0x12b0, "Jorge Scientific Corp", {
- }},
- {0x12b1, "GammaLink", {
- }},
- {0x12b2, "General Signal Networks", {
- }},
- {0x12b3, "Inter-Face Co Ltd", {
- }},
- {0x12b4, "FutureTel Inc", {
- }},
- {0x12b5, "Granite Systems Inc.", {
- }},
- {0x12b6, "Natural Microsystems", {
- }},
- {0x12b7, "Cognex Modular Vision Systems Div. - Acumen Inc.", {
- }},
- {0x12b8, "Korg", {
- }},
- {0x12b9, "US Robotics", {
- }},
- {0x12ba, "PMC Sierra", {
- }},
- {0x12bb, "Nippon Unisoft Corporation", {
- }},
- {0x12bc, "Array Microsystems", {
- }},
- {0x12bd, "Computerm Corp.", {
- }},
- {0x12be, "Anchor Chips Inc.", {
- }},
- {0x12bf, "Fujifilm Microdevices", {
- }},
- {0x12c0, "Infimed", {
- }},
- {0x12c1, "GMM Research Corp", {
- }},
- {0x12c2, "Mentec Limited", {
- }},
- {0x12c3, "Holtek Microelectronics Inc", {
- }},
- {0x12c4, "Connect Tech Inc", {
- }},
- {0x12c5, "Picture Elements Incorporated", {
- {0x0081,"PCIVST [PCI Grayscale Thresholding Engine]"},
- }},
- {0x12c6, "Mitani Corporation", {
- }},
- {0x12c7, "Dialogic Corp", {
- }},
- {0x12c8, "G Force Co, Ltd", {
- }},
- {0x12c9, "Gigi Operations", {
- }},
- {0x12ca, "Integrated Computing Engines", {
- }},
- {0x12cb, "Antex Electronics Corporation", {
- }},
- {0x12cc, "Pluto Technologies International", {
- }},
- {0x12cd, "Aims Lab", {
- }},
- {0x12ce, "Netspeed Inc.", {
- }},
- {0x12cf, "Prophet Systems, Inc.", {
- }},
- {0x12d0, "GDE Systems, Inc.", {
- }},
- {0x12d1, "PSITech", {
- }},
- {0x12d2, "NVidia / SGS Thomson (Joint Venture)", {
- {0x0018,"Riva128"},
- }},
- {0x12d3, "Vingmed Sound A/S", {
- }},
- {0x12d4, "DGM&S", {
- }},
- {0x12d5, "Equator Technologies", {
- }},
- {0x12d6, "Analogic Corp", {
- }},
- {0x12d7, "Biotronic SRL", {
- }},
- {0x12d8, "Pericom Semiconductor", {
- }},
- {0x12d9, "Aculab PLC", {
- }},
- {0x12da, "True Time Inc.", {
- }},
- {0x12db, "Annapolis Micro Systems, Inc", {
- }},
- {0x12dc, "Symicron Computer Communication Ltd.", {
- }},
- {0x12dd, "Management Graphics", {
- }},
- {0x12de, "Rainbow Technologies", {
- }},
- {0x12df, "SBS Technologies Inc", {
- }},
- {0x12e0, "Chase Research", {
- }},
- {0x12e1, "Nintendo Co, Ltd", {
- }},
- {0x12e2, "Datum Inc. Bancomm-Timing Division", {
- }},
- {0x12e3, "Imation Corp - Medical Imaging Systems", {
- }},
- {0x12e4, "Brooktrout Technology Inc", {
- }},
- {0x12e5, "Apex Semiconductor Inc", {
- }},
- {0x12e6, "Cirel Systems", {
- }},
- {0x12e7, "Sunsgroup Corporation", {
- }},
- {0x12e8, "Crisc Corp", {
- }},
- {0x12e9, "GE Spacenet", {
- }},
- {0x12ea, "Zuken", {
- }},
- {0x12eb, "Aureal Semiconductor", {
- }},
- {0x12ec, "3A International, Inc.", {
- }},
- {0x12ed, "Optivision Inc.", {
- }},
- {0x12ee, "Orange Micro", {
- }},
- {0x12ef, "Vienna Systems", {
- }},
- {0x12f0, "Pentek", {
- }},
- {0x12f1, "Sorenson Vision Inc", {
- }},
- {0x12f2, "Gammagraphx, Inc.", {
- }},
- {0x12f3, "Radstone Technology", {
- }},
- {0x12f4, "Megatel", {
- }},
- {0x12f5, "Forks", {
- }},
- {0x12f6, "Dawson France", {
- }},
- {0x12f7, "Cognex", {
- }},
- {0x12f8, "Electronic Design GmbH", {
- }},
- {0x12f9, "Four Fold Ltd", {
- }},
- {0x12fb, "Spectrum Signal Processing", {
- }},
- {0x12fc, "Capital Equipment Corp", {
- }},
- {0x12fd, "I2S", {
- }},
- {0x12fe, "ESD Electronic System Design GmbH", {
- }},
- {0x12ff, "Lexicon", {
- }},
- {0x1300, "Harman International Industries Inc", {
- }},
- {0x1302, "Computer Sciences Corp", {
- }},
- {0x1303, "Innovative Integration", {
- }},
- {0x1304, "Juniper Networks", {
- }},
- {0x1305, "Netphone, Inc", {
- }},
- {0x1306, "Duet Technologies", {
- }},
- {0x1307, "Computer Boards", {
- {0x0001,"DAS1602/16"},
- }},
- {0x1308, "Jato Technologies Inc.", {
- }},
- {0x1309, "AB Semiconductor Ltd", {
- }},
- {0x130a, "Mitsubishi Electric Microcomputer", {
- }},
- {0x130b, "Colorgraphic Communications Corp", {
- }},
- {0x130c, "Ambex Technologies, Inc", {
- }},
- {0x130d, "Accelerix Inc", {
- }},
- {0x130e, "Yamatake-Honeywell Co. Ltd", {
- }},
- {0x130f, "Advanet Inc", {
- }},
- {0x1310, "Gespac", {
- }},
- {0x1311, "Videoserver, Inc", {
- }},
- {0x1312, "Acuity Imaging, Inc", {
- }},
- {0x1313, "Yaskawa Electric Co.", {
- }},
- {0x1316, "Teradyne Inc", {
- }},
- {0x1317, "Bridgecom, Inc", {
- }},
- {0x1318, "Packet Engines Inc.", {
- }},
- {0x1319, "Fortemedia, Inc", {
- }},
- {0x131a, "Finisar Corp.", {
- }},
- {0x131c, "Nippon Electro-Sensory Devices Corp", {
- }},
- {0x131d, "Sysmic, Inc.", {
- }},
- {0x131e, "Xinex Networks Inc", {
- }},
- {0x131f, "Siig Inc", {
- }},
- {0x1320, "Crypto AG", {
- }},
- {0x1321, "Arcobel Graphics BV", {
- }},
- {0x1322, "MTT Co., Ltd", {
- }},
- {0x1323, "Dome Inc", {
- }},
- {0x1324, "Sphere Communications", {
- }},
- {0x1325, "Salix Technologies, Inc", {
- }},
- {0x1326, "Seachange international", {
- }},
- {0x1327, "Voss scientific", {
- }},
- {0x1328, "quadrant international", {
- }},
- {0x1329, "Productivity Enhancement", {
- }},
- {0x132a, "Microcom Inc.", {
- }},
- {0x132b, "Broadband Technologies", {
- }},
- {0x132c, "Micrel Inc", {
- }},
- {0x132d, "Integrated Silicon Solution, Inc.", {
- }},
- {0x1330, "MMC Networks", {
- }},
- {0x1331, "Radisys Corp.", {
- }},
- {0x1332, "Micro Memory", {
- }},
- {0x1334, "Redcreek Communications, Inc", {
- }},
- {0x1335, "Videomail, Inc", {
- }},
- {0x1337, "Third Planet Publishing", {
- }},
- {0x1338, "BT Electronics", {
- }},
- {0x133a, "Vtel Corp", {
- }},
- {0x133b, "Softcom Microsystems", {
- }},
- {0x133c, "Holontech Corp", {
- }},
- {0x133d, "SS Technologies", {
- }},
- {0x133e, "Virtual Computer Corp", {
- }},
- {0x133f, "SCM Microsystems", {
- }},
- {0x1340, "Atalla Corp", {
- }},
- {0x1341, "Kyoto Microcomputer Co", {
- }},
- {0x1342, "Promax Systems Inc", {
- }},
- {0x1343, "Phylon Communications Inc", {
- }},
- {0x1344, "Crucial Technology", {
- }},
- {0x1345, "Arescom Inc", {
- }},
- {0x1347, "Odetics", {
- }},
- {0x1349, "Sumitomo Electric Industries, Ltd.", {
- }},
- {0x134a, "DTC Technology Corp.", {
- }},
- {0x134b, "ARK Research Corp.", {
- }},
- {0x134c, "Chori Joho System Co. Ltd", {
- }},
- {0x134d, "PCTel Inc", {
- }},
- {0x134e, "CSTI", {
- }},
- {0x134f, "Algo System Co Ltd", {
- }},
- {0x1350, "Systec Co. Ltd", {
- }},
- {0x1351, "Sonix Inc", {
- }},
- {0x1353, "Dassault A.T.", {
- }},
- {0x1354, "Dwave System Inc", {
- }},
- {0x1355, "Kratos Analytical Ltd", {
- }},
- {0x1356, "The Logical Co", {
- }},
- {0x1359, "Prisa Networks", {
- }},
- {0x135a, "Brain Boxes", {
- }},
- {0x135b, "Giganet Inc", {
- }},
- {0x135c, "Quatech Inc", {
- }},
- {0x135d, "ABB Network Partner AB", {
- }},
- {0x135e, "Sealevel Systems Inc", {
- }},
- {0x135f, "I-Data International A-S", {
- }},
- {0x1360, "Meinberg Funkuhren", {
- }},
- {0x1361, "Soliton Systems K.K.", {
- }},
- {0x1362, "Fujifacom Corporation", {
- }},
- {0x1363, "Phoenix Technology Ltd", {
- }},
- {0x1364, "ATM Communications Inc", {
- }},
- {0x1365, "Hypercope GmbH", {
- }},
- {0x1366, "Teijin Seiki Co. Ltd", {
- }},
- {0x1367, "Hitachi Zosen Corporation", {
- }},
- {0x1368, "Skyware Corporation", {
- }},
- {0x1369, "Digigram", {
- }},
- {0x136a, "High Soft Tech", {
- }},
- {0x136b, "Kawasaki Steel Corporation", {
- }},
- {0x136c, "Adtek System Science Co Ltd", {
- }},
- {0x136d, "Gigalabs Inc", {
- }},
- {0x136f, "Applied Magic Inc", {
- }},
- {0x1370, "ATL Products", {
- }},
- {0x1371, "CNet Technology Inc", {
- }},
- {0x1373, "Silicon Vision Inc", {
- }},
- {0x1374, "Silicom Ltd", {
- }},
- {0x1375, "Argosystems Inc", {
- }},
- {0x1376, "LMC", {
- }},
- {0x1377, "Electronic Equipment Production & Distribution GmbH", {
- }},
- {0x1378, "Telemann Co. Ltd", {
- }},
- {0x1379, "Asahi Kasei Microsystems Co Ltd", {
- }},
- {0x137a, "Mark of the Unicorn Inc", {
- }},
- {0x137b, "PPT Vision", {
- }},
- {0x137c, "Iwatsu Electric Co Ltd", {
- }},
- {0x137d, "Dynachip Corporation", {
- }},
- {0x137e, "Patriot Scientific Corporation", {
- }},
- {0x137f, "Japan Satellite Systems Inc", {
- }},
- {0x1380, "Sanritz Automation Co Ltd", {
- }},
- {0x1381, "Brains Co. Ltd", {
- }},
- {0x1382, "Marian - Electronic & Software", {
- }},
- {0x1383, "Controlnet Inc", {
- }},
- {0x1384, "Reality Simulation Systems Inc", {
- }},
- {0x1385, "Netgear", {
- }},
- {0x1386, "Video Domain Technologies", {
- }},
- {0x1387, "Systran Corp", {
- }},
- {0x1388, "Hitachi Information Technology Co Ltd", {
- }},
- {0x1389, "Applicom International", {
- }},
- {0x138a, "Fusion Micromedia Corp", {
- }},
- {0x138b, "Tokimec Inc", {
- }},
- {0x138c, "Silicon Reality", {
- }},
- {0x138d, "Future Techno Designs pte Ltd", {
- }},
- {0x138e, "Basler GmbH", {
- }},
- {0x138f, "Patapsco Designs Inc", {
- }},
- {0x1390, "Concept Development Inc", {
- }},
- {0x1391, "Development Concepts Inc", {
- }},
- {0x1392, "Medialight Inc", {
- }},
- {0x1393, "Moxa Technologies Co Ltd", {
- }},
- {0x1394, "Level One Communications", {
- }},
- {0x1395, "Ambicom Inc", {
- }},
- {0x1396, "Cipher Systems Inc", {
- }},
- {0x1397, "Cologne Chip Designs GmbH", {
- }},
- {0x1398, "Clarion co. Ltd", {
- }},
- {0x1399, "Rios systems Co Ltd", {
- }},
- {0x139a, "Alacritech Inc", {
- }},
- {0x139b, "Mediasonic Multimedia Systems Ltd", {
- }},
- {0x139c, "Quantum 3d Inc", {
- }},
- {0x139d, "EPL limited", {
- }},
- {0x139e, "Media4", {
- }},
- {0x139f, "Aethra s.r.l.", {
- }},
- {0x13a0, "Crystal Group Inc", {
- }},
- {0x13a1, "Kawasaki Heavy Industries Ltd", {
- }},
- {0x13a2, "Ositech Communications Inc", {
- }},
- {0x13a3, "Hi-Fn", {
- }},
- {0x13a4, "Rascom Inc", {
- }},
- {0x13a5, "Audio Digital Imaging Inc", {
- }},
- {0x13a6, "Videonics Inc", {
- }},
- {0x13a7, "Teles AG", {
- }},
- {0x13a8, "Exar Corp.", {
- }},
- {0x13a9, "Siemens Medical Systems, Ultrasound Group", {
- }},
- {0x13aa, "Broadband Networks Inc", {
- }},
- {0x13ab, "Arcom Control Systems Ltd", {
- }},
- {0x13ac, "Motion Media Technology Ltd", {
- }},
- {0x13ad, "Nexus Inc", {
- }},
- {0x13ae, "ALD Technology Ltd", {
- }},
- {0x13af, "T.Sqware", {
- }},
- {0x13b0, "Maxspeed Corp", {
- }},
- {0x13b1, "Tamura corporation", {
- }},
- {0x13b2, "Techno Chips Co. Ltd", {
- }},
- {0x13b3, "Lanart Corporation", {
- }},
- {0x13b4, "Wellbean Co Inc", {
- }},
- {0x13b5, "ARM", {
- }},
- {0x13b6, "Dlog GmbH", {
- }},
- {0x13b7, "Logic Devices Inc", {
- }},
- {0x13b8, "Nokia Telecommunications oy", {
- }},
- {0x13b9, "Elecom Co Ltd", {
- }},
- {0x13ba, "Oxford Instruments", {
- }},
- {0x13bb, "Sanyo Technosound Co Ltd", {
- }},
- {0x13bc, "Bitran Corporation", {
- }},
- {0x13bd, "Sharp corporation", {
- }},
- {0x13be, "Miroku Jyoho Service Co. Ltd", {
- }},
- {0x13bf, "Sharewave Inc", {
- }},
- {0x13c0, "Microgate Corporation", {
- }},
- {0x13c1, "3ware Inc", {
- }},
- {0x13c2, "Technotrend Systemtechnik GmbH", {
- }},
- {0x13c3, "Janz Computer AG", {
- }},
- {0x13c4, "Phase Metrics", {
- }},
- {0x13c5, "Alphi Technology Corp", {
- }},
- {0x13c6, "Condor Engineering Inc", {
- }},
- {0x13c7, "Blue Chip Technology Ltd", {
- }},
- {0x13c8, "Apptech Inc", {
- }},
- {0x13c9, "Eaton Corporation", {
- }},
- {0x13ca, "Iomega Corporation", {
- }},
- {0x13cb, "Yano Electric Co Ltd", {
- }},
- {0x13cc, "Metheus Corporation", {
- }},
- {0x13cd, "Compatible Systems Corporation", {
- }},
- {0x13ce, "Cocom A/S", {
- }},
- {0x13cf, "Studio Audio & Video Ltd", {
- }},
- {0x13d0, "Techsan Electronics Co Ltd", {
- }},
- {0x13d1, "Abocom Systems Inc", {
- }},
- {0x13d2, "Shark Multimedia Inc", {
- }},
- {0x13d3, "IMC Networks", {
- }},
- {0x13d4, "Graphics Microsystems Inc", {
- }},
- {0x13d5, "Media 100 Inc", {
- }},
- {0x13d6, "K.I. Technology Co Ltd", {
- }},
- {0x13d7, "Toshiba Engineering Corporation", {
- }},
- {0x13d8, "Phobos corporation", {
- }},
- {0x13d9, "Apex PC Solutions Inc", {
- }},
- {0x13da, "Intresource Systems pte Ltd", {
- }},
- {0x13db, "Janich & Klass Computertechnik GmbH", {
- }},
- {0x13dc, "Netboost Corporation", {
- }},
- {0x13dd, "Multimedia Bundle Inc", {
- }},
- {0x13de, "ABB Robotics Products AB", {
- }},
- {0x13df, "E-Tech Inc", {
- }},
- {0x13e0, "GVC Corporation", {
- }},
- {0x13e1, "Silicom Multimedia Systems Inc", {
- }},
- {0x13e2, "Dynamics Research Corporation", {
- }},
- {0x13e3, "Nest Inc", {
- }},
- {0x13e4, "Calculex Inc", {
- }},
- {0x13e5, "Telesoft Design Ltd", {
- }},
- {0x13e6, "Argosy research Inc", {
- }},
- {0x13e7, "NAC Incorporated", {
- }},
- {0x13e8, "Chip Express Corporation", {
- }},
- {0x13e9, "Chip Express Corporation", {
- }},
- {0x13ea, "Dallas Semiconductor", {
- }},
- {0x13eb, "Hauppauge Computer Works Inc", {
- }},
- {0x13ec, "Zydacron Inc", {
- }},
- {0x13ed, "Raytheion E-Systems", {
- }},
- {0x13ee, "Hayes Microcomputer Products Inc", {
- }},
- {0x13ef, "Coppercom Inc", {
- }},
- {0x13f0, "Sundance technology Inc", {
- }},
- {0x13f1, "Oce' - Technologies B.V.", {
- }},
- {0x13f2, "Ford Microelectronics Inc", {
- }},
- {0x13f3, "Mcdata Corporation", {
- }},
- {0x13f4, "Troika Design Inc", {
- }},
- {0x13f5, "Kansai Electric Co. Ltd", {
- }},
- {0x13f6, "C-Media Electronics Inc", {
- }},
- {0x13f7, "Wildfire Communications", {
- }},
- {0x13f8, "Ad Lib Multimedia Inc", {
- }},
- {0x13f9, "NTT Advanced Technology Corp.", {
- }},
- {0x13fa, "Pentland Systems Ltd", {
- }},
- {0x13fb, "Aydin Corp", {
- }},
- {0x13fc, "Computer Peripherals International", {
- }},
- {0x13fd, "Micro Science Inc", {
- }},
- {0x13fe, "Advantech Co. Ltd", {
- }},
- {0x13ff, "Silicon Spice Inc", {
- }},
- {0x1400, "Artx Inc", {
- }},
- {0x1401, "CR-Systems A/S", {
- }},
- {0x1402, "Meilhaus Electronic GmbH", {
- }},
- {0x1403, "Ascor Inc", {
- }},
- {0x1404, "Fundamental Software Inc", {
- }},
- {0x1405, "Excalibur Systems Inc", {
- }},
- {0x1406, "Oce' Printing Systems GmbH", {
- }},
- {0x1407, "Lava Computer mfg Inc", {
- }},
- {0x1408, "Aloka Co. Ltd", {
- }},
- {0x1409, "Timedia Technology Co Ltd", {
- }},
- {0x140a, "DSP Research Inc", {
- }},
- {0x140b, "Ramix Inc", {
- }},
- {0x140c, "Elmic Systems Inc", {
- }},
- {0x140d, "Matsushita Electric Works Ltd", {
- }},
- {0x140e, "Goepel Electronic GmbH", {
- }},
- {0x140f, "Salient Systems Corp", {
- }},
- {0x1410, "Midas lab Inc", {
- }},
- {0x1411, "Ikos Systems Inc", {
- }},
- {0x1412, "IC Ensemble Inc", {
- }},
- {0x1413, "Addonics", {
- }},
- {0x1414, "Microsoft Corporation", {
- }},
- {0x1415, "Oxford Semiconductor Ltd", {
- }},
- {0x1416, "Multiwave Innovation pte Ltd", {
- }},
- {0x1417, "Convergenet Technologies Inc", {
- }},
- {0x1418, "Kyushu electronics systems Inc", {
- }},
- {0x1419, "Excel Switching Corp", {
- }},
- {0x141a, "Apache Micro Peripherals Inc", {
- }},
- {0x141b, "Zoom Telephonics Inc", {
- }},
- {0x141d, "Digitan Systems Inc", {
- }},
- {0x141e, "Fanuc Ltd", {
- }},
- {0x141f, "Visiontech Ltd", {
- }},
- {0x1420, "Psion Dacom plc", {
- }},
- {0x1421, "Ads Technologies Inc", {
- }},
- {0x1422, "Ygrec Systems Co Ltd", {
- }},
- {0x1423, "Custom Technology Corp.", {
- }},
- {0x1424, "Videoserver Connections", {
- }},
- {0x1425, "ASIC Designers Inc", {
- }},
- {0x1426, "Storage Technology Corp.", {
- }},
- {0x1427, "Better On-Line Solutions", {
- }},
- {0x1428, "Edec Co Ltd", {
- }},
- {0x1429, "Unex Technology Corp.", {
- }},
- {0x142a, "Kingmax Technology Inc", {
- }},
- {0x142b, "Radiolan", {
- }},
- {0x142c, "Minton Optic Industry Co Ltd", {
- }},
- {0x142d, "Pix stream Inc", {
- }},
- {0x142e, "Vitec Multimedia", {
- }},
- {0x142f, "Radicom Research Inc", {
- }},
- {0x1430, "ITT Aerospace/Communications Division", {
- }},
- {0x1431, "Gilat Satellite Networks", {
- }},
- {0x1432, "Edimax Computer Co.", {
- }},
- {0x1433, "Eltec Elektronik GmbH", {
- }},
- {0x1435, "Real Time Devices US Inc.", {
- }},
- {0x1436, "CIS Technology Inc", {
- }},
- {0x1668, "Action Tec Electronics Inc", {
- }},
- {0x1b13, "Jaton Corp", {
- }},
- {0x1c1c, "Symphony", {
- {0x0001,"82C101"},
- }},
- {0x21c3, "21st Century Computer Corp.", {
- }},
- {0x270b, "Xantel Corporation", {
- }},
- {0x270f, "Chaintech Computer Co. Ltd", {
- }},
- {0x3388, "Hint Corp", {
- }},
- {0x3d3d, "3DLabs", {
- {0x0001,"GLINT 300SX"},
- {0x0002,"GLINT 500TX"},
- {0x0003,"GLINT Delta"},
- {0x0004,"Permedia"},
- {0x0006,"GLINT MX"},
- }},
- {0x4005, "Avance Logic Inc.", {
- {0x2064,"ALG2064i"},
- {0x2301,"ALG2301"},
- {0x2302,"ALG2302"},
- }},
- {0x4444, "Internext Compression Inc", {
- }},
- {0x4680, "Umax Computer Corp", {
- }},
- {0x4843, "Hercules Computer Technology Inc", {
- }},
- {0x4978, "Axil Computer Inc", {
- }},
- {0x4a14, "NetVin", {
- {0x5000,"PCI NV5000SC"},
- }},
- {0x4ddc, "ILC Data Device Corp", {
- }},
- {0x5053, "Voyetra Technologies", {
- }},
- {0x5143, "Qualcomm Inc", {
- }},
- {0x5333, "S3 Inc.", {
- {0x0551,"Plato/PX (system)"},
- {0x5631,"86C325 [ViRGE]"},
- {0x8810,"86C764_0 [Trio 32 vers 0]"},
- {0x8811,"86C764_1 [Trio 32/64 vers 1]"},
- {0x8812,"Aurora64V+"},
- {0x8813,"86C764_3 [Trio 32/64 vers 3]"},
- {0x8814,"Trio64UV+"},
- {0x8815,"Aurora128"},
- {0x883d,"ViRGE/VX"},
- {0x8880,"Vision 868 vers 0"},
- {0x8881,"Vision 868 vers 1"},
- {0x8882,"Vision 868 vers 2"},
- {0x8883,"Vision 868 vers 3"},
- {0x88b0,"Vision 928 vers 0"},
- {0x88b1,"Vision 928 vers 1"},
- {0x88b2,"Vision 928 vers 2"},
- {0x88b3,"Vision 928 vers 3"},
- {0x88c0,"Vision 864 vers 0"},
- {0x88c1,"Vision 864 vers 1"},
- {0x88c2,"86C864"},
- {0x88c3,"86C864"},
- {0x88d0,"Vision 964 vers 0"},
- {0x88d1,"Vision 964 vers 1"},
- {0x88d2,"86C964"},
- {0x88d3,"86C964"},
- {0x88f0,"Vision 968"},
- {0x88f1,"86C968"},
- {0x88f2,"86C968"},
- {0x88f3,"86C968"},
- {0x8901,"Trio64V2/DX or /GX"},
- {0x8902,"Plato/PX (graphics)"},
- {0x8a01,"ViRGE/DX or /GX"},
- {0x8a10,"ViRGE/GX2"},
- {0x8c01,"ViRGE/MX"},
- {0x8c02,"ViRGE/MX+"},
- {0x8c03,"ViRGE/MX+MV"},
- {0xca00,"SonicVibes"},
- }},
- {0x5555, "Genroco, Inc", {
- {0x0003,"TURBOstor HFP-832 [HiPPI NIC]"},
- }},
- {0x6374, "c't Magazin f€r Computertechnik", {
- {0x6773,"GPPCI"},
- }},
- {0x6666, "Decision Computer International Co.", {
- }},
- {0x8008, "Quancm Electronic GmbH", {
- {0x0010,"WDOG1 [PCI-Watchdog 1]"},
- {0x0011,"PWDOG2 [Watchdog2/PCI]"},
- }},
- {0x8086, "Intel Corporation", {
- {0x0482,"82375EB"},
- {0x0483,"82424ZX [Saturn]"},
- {0x0484,"82378IB [SIO ISA Bridge]"},
- {0x0486,"82430ZX [Aries]"},
- {0x04a3,"82434LX [Mercury/Neptune]"},
- {0x0960,"80960RP [i960 RP Microprocessor/Bridge]"},
- {0x1221,"82092AA_0"},
- {0x1222,"82092AA_1"},
- {0x1223,"SAA7116"},
- {0x1226,"82596"},
- {0x1227,"82865"},
- {0x1228,"82556"},
- {0x1229,"82557"},
- {0x122d,"430FX - 82437FX TSC [Triton I]"},
- {0x122e,"82371FB PIIX ISA [Triton I]"},
- {0x1230,"82371FB PIIX IDE [Triton I]"},
- {0x1234,"430MX - 82371MX MPIIX [430MX PCIset - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)]"},
- {0x1235,"430MX - 82437MX MTSC [430MX PCIset - 82437MX Mobile System Controller (MTSC) and 82438MX Mobile Data Path (MTDP)]"},
- {0x1237,"440FX - 82441FX PMC [Natoma]"},
- {0x124b,"82380FB"},
- {0x1250,"430HX - 82439HX TXC [Triton II]"},
- {0x1960,"80960RP [i960RP Microprocessor]"},
- {0x7000,"82371SB PIIX3 ISA [Natoma/Triton II]"},
- {0x7010,"82371SB PIIX3 IDE [Natoma/Triton II]"},
- {0x7020,"82371SB PIIX3 USB [Natoma/Triton II]"},
- {0x7030,"430VX - 82437VX TVX [Triton VX]"},
- {0x7100,"430TX - 82439TX MTXC"},
- {0x7110,"82371AB PIIX4 ISA"},
- {0x7111,"82371AB PIIX4 IDE"},
- {0x7112,"82371AB PIIX4 USB"},
- {0x7113,"82371AB PIIX4 ACPI"},
- {0x7180,"440LX - 82443LX PAC Host"},
- {0x7181,"440LX - 82443LX PAC AGP"},
- {0x7190,"440BX - 82443BX Host"},
- {0x7191,"440BX - 82443BX AGP"},
- {0x7192,"440BX - 82443BX (AGP disabled)"},
- {0x7800,"i740"},
- {0x84c4,"82450KX [Orion]"},
- {0x84c5,"82450GX [Orion]"},
- }},
- {0x8800, "Trigem Computer Inc.", {
- }},
- {0x8888, "Silicon Magic", {
- }},
- {0x8e0e, "Computone Corporation", {
- }},
- {0x8e2e, "KTI", {
- {0x3000,"ET32P2"},
- }},
- {0x9004, "Adaptec", {
- {0x1078,"AIC-7810"},
- {0x5078,"AIC-7850"},
- {0x5178,"7851"},
- {0x5278,"7852"},
- {0x5575,"2930"},
- {0x5578,"AIC-7855"},
- {0x5800,"AIC-5800"},
- {0x6075,"AIC-1480"},
- {0x6078,"AIC-7860"},
- {0x6178,"AIC-7861"},
- {0x6278,"AIC-7860"},
- {0x6378,"AIC-7860"},
- {0x7078,"AIC-7870"},
- {0x7178,"AIC-7871"},
- {0x7278,"AIC-7872"},
- {0x7378,"AIC-7873"},
- {0x7478,"AIC-7874 [AHA-2944]"},
- {0x7578,"7875"},
- {0x7678,"7876"},
- {0x7895,"AIC-7895"},
- {0x8078,"AIC-7880U"},
- {0x8178,"AIC-7881U"},
- {0x8278,"AIC-7882U"},
- {0x8378,"AIC-7883U"},
- {0x8478,"AIC-7884U"},
- {0x8578,"7885"},
- {0x8678,"7886"},
- {0x8b78,"ABA-1030"},
- }},
- {0x907f, "Atronics", {
- {0x2015,"IDE-2015PL"},
- }},
- {0x9412, "Holtek", {
- {0x6565,"6565"},
- }},
- {0xa200, "NEC Corporation", {
- }},
- {0xa259, "Hewlett Packard", {
- }},
- {0xa25b, "Hewlett Packard GmbH PL24-MKT", {
- }},
- {0xa304, "Sony", {
- }},
- {0xa727, "3Com Corporation", {
- }},
- {0xaa42, "Scitex Digital Video", {
- }},
- {0xb1b3, "Shiva Europe Limited", {
- }},
- {0xc001, "TSI Telsys", {
- }},
- {0xc0a9, "Micron/Crucial Technology", {
- }},
- {0xc0de, "Motorola", {
- }},
- {0xc0fe, "Motion Engineering, Inc.", {
- }},
- {0xcafe, "Chrysalis-ITS", {
- }},
- {0xd4d4, "Dy4 Systems Inc", {
- }},
- {0xe159, "Tiger Jet Network Inc.", {
- {0x0001,"300"},
- }},
- {0xecc0, "Echo Corporation", {
- }},
- {0xedd8, "ARK Logic Inc", {
- {0xa091,"1000PV [Stingray]"},
- {0xa099,"2000PV [Stingray]"},
- {0xa0a1,"2000MT"},
- {0xa0a9,"2000MI"},
- }},
-};
-
diff --git a/os/pc/pcmciamodem.c b/os/pc/pcmciamodem.c
deleted file mode 100644
index 800f406c..00000000
--- a/os/pc/pcmciamodem.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-/*
- * PCMCIA modem.
- * By default, this will set it up with the port and irq of
- * COM2 unless a serialx=type=com line is found in plan9.ini.
- * The assumption is that a laptop with a pcmcia will have only
- * one com port.
- */
-
-enum {
- Maxcard= 8,
-};
-
-static char* modems[] = {
- "IBM 33.6 Data/Fax/Voice Modem",
- "CM-56G", /* Xircom CreditCard Modem 56 - GlobalACCESS */
- "KeepInTouch",
- "CEM56",
- "MONTANA V.34 FAX/MODEM", /* Motorola */
- "REM10",
- "GSM/GPRS",
- "AirCard 555",
- "Gold Card Global", /* Psion V90 Gold card */
- "Merlin UMTS Modem", /* Novatel card */
- 0,
-};
-
-void
-pcmciamodemlink(void)
-{
- ISAConf isa;
- int i, j, slot, com2used, usingcom2;
-
- i = 0;
- com2used = 0;
- for(j = 0; modems[j]; j++){
- memset(&isa, 0, sizeof(isa));
-
- /* look for a configuration line */
- for(; i < Maxcard; i++){
- if(isaconfig("serial", i, &isa))
- if(cistrcmp(isa.type, "com") == 0)
- break;
- memset(&isa, 0, sizeof(isa));
- }
-
- usingcom2 = 0;
- if (isa.irq == 0 && isa.port == 0) {
- if (com2used == 0) {
- /* default is COM2 */
- isa.irq = 3;
- isa.port = 0x2F8;
- usingcom2 = 1;
- } else
- break;
- }
- slot = pcmspecial(modems[j], &isa);
- if(slot >= 0){
- if(usingcom2)
- com2used = 1;
- if(ioalloc(isa.port, 8, 0, modems[j]) < 0)
- print("%s port %lux already in use\n", modems[j], isa.port);
- print("%s in pcmcia slot %d port 0x%lux irq %d\n",
- modems[j], slot, isa.port, isa.irq);
- }
- }
-}
diff --git a/os/pc/piix4smbus.c b/os/pc/piix4smbus.c
deleted file mode 100644
index ced41001..00000000
--- a/os/pc/piix4smbus.c
+++ /dev/null
@@ -1,213 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-//
-// SMBus support for the PIIX4
-//
-enum
-{
- IntelVendID= 0x8086,
- Piix4PMID= 0x7113, /* PIIX4 power management function */
-
- // SMBus configuration registers (function 3)
- SMBbase= 0x90, // 4 byte base address (bit 0 == 1, bit 3:1 == 0)
- SMBconfig= 0xd2,
- SMBintrselect= (7<<1),
- SMIenable= (0<<1), // interrupts sent to SMI#
- IRQ9enable= (4<<1), // intettupts sent to IRQ9
- SMBenable= (1<<0), // 1 enables
-
- // SMBus IO space registers
- Hoststatus= 0x0, // (writing 1 bits reset the interrupt bits)
- Failed= (1<<4), // transaction terminated by KILL
- Bus_error= (1<<3), // transactio collision
- Dev_error= (1<<2), // device error interrupt
- Host_complete= (1<<1), // host command completion interrupt
- Host_busy= (1<<0), //
- Slavestatus= 0x1, // (writing 1 bits reset)
- Alert_sts= (1<<5), // someone asserted SMBALERT#
- Shdw2_sts= (1<<4), // slave accessed shadow 2 port
- Shdw1_sts= (1<<3), // slave accessed shadow 1 port
- Slv_sts= (1<<2), // slave accessed shadow 1 port
- Slv_bsy= (1<<0),
- Hostcontrol= 0x2,
- Start= (1<<6), // start execution
- Cmd_prot= (7<<2), // command protocol mask
- Quick= (0<<2), // address only
- Byte= (1<<2), // address + cmd
- ByteData= (2<<2), // address + cmd + data
- WordData= (3<<2), // address + cmd + data + data
- Kill= (1<<1), // abort in progress command
- Ienable= (1<<0), // enable completion interrupts
- Hostcommand= 0x3,
- Hostaddress= 0x4,
- AddressMask= (0x7f<<1), // target address
- Read= (1<<0), // 1 == read, 0 == write
- Hostdata0= 0x5,
- Hostdata1= 0x6,
- Blockdata= 0x7,
- Slavecontrol= 0x8,
- Alert_en= (1<<3), // enable inter on SMBALERT#
- Shdw2_en= (1<<2), // enable inter on external shadow 2 access
- Shdw1_en= (1<<1), // enable inter on external shadow 1 access
- Slv_en= (1<<0), // enable inter on access of host ctlr slave port
- Shadowcommand= 0x9,
- Slaveevent= 0xa,
- Slavedata= 0xc,
-};
-
-static struct
-{
- int rw;
- int cmd;
- int len;
- int proto;
-} proto[] =
-{
- [SMBquick] { 0, 0, 0, Quick },
- [SMBsend] { 0, 1, 0, Byte },
- [SMBbytewrite] { 0, 1, 1, ByteData },
- [SMBwordwrite] { 0, 1, 2, WordData },
- [SMBrecv] { Read, 0, 1, Byte },
- [SMBbyteread] { Read, 1, 1, ByteData },
- [SMBwordread] { Read, 1, 2, WordData },
-};
-
-static void
-transact(SMBus *s, int type, int addr, int cmd, uchar *data)
-{
- int tries, status;
- char err[256];
-
- if(type < 0 || type > nelem(proto))
- panic("piix4smbus: illegal transaction type %d", type);
-
- if(waserror()){
- qunlock(s);
- nexterror();
- }
- qlock(s);
-
- // wait a while for the host interface to be available
- for(tries = 0; tries < 1000000; tries++){
- if((inb(s->base+Hoststatus) & Host_busy) == 0)
- break;
- sched();
- }
- if(tries >= 1000000){
- // try aborting current transaction
- outb(s->base+Hostcontrol, Kill);
- for(tries = 0; tries < 1000000; tries++){
- if((inb(s->base+Hoststatus) & Host_busy) == 0)
- break;
- sched();
- }
- if(tries >= 1000000){
- snprint(err, sizeof(err), "SMBus jammed: %2.2ux", inb(s->base+Hoststatus));
- error(err);
- }
- }
-
- // set up for transaction
- outb(s->base+Hostaddress, (addr<<1)|proto[type].rw);
- if(proto[type].cmd)
- outb(s->base+Hostcommand, cmd);
- if(proto[type].rw != Read){
- switch(proto[type].len){
- case 2:
- outb(s->base+Hostdata1, data[1]);
- // fall through
- case 1:
- outb(s->base+Hostdata0, data[0]);
- break;
- }
- }
-
-
- // reset the completion/error bits and start transaction
- outb(s->base+Hoststatus, Failed|Bus_error|Dev_error|Host_complete);
- outb(s->base+Hostcontrol, Start|proto[type].proto);
-
- // wait for completion
- status = 0;
- for(tries = 0; tries < 1000000; tries++){
- status = inb(s->base+Hoststatus);
- if(status & (Failed|Bus_error|Dev_error|Host_complete))
- break;
- sched();
- }
- if((status & Host_complete) == 0){
- snprint(err, sizeof(err), "SMBus request failed: %2.2ux", status);
- error(err);
- }
-
- // get results
- if(proto[type].rw == Read){
- switch(proto[type].len){
- case 2:
- data[1] = inb(s->base+Hostdata1);
- // fall through
- case 1:
- data[0] = inb(s->base+Hostdata0);
- break;
- }
- }
- qunlock(s);
- poperror();
-}
-
-static SMBus smbusproto =
-{
- .transact = transact,
-};
-
-//
-// return 0 if this is a piix4 with an smbus interface
-//
-SMBus*
-piix4smbus(void)
-{
- Pcidev *p;
- static SMBus *s;
-
- if(s != nil)
- return s;
-
- p = pcimatch(nil, IntelVendID, Piix4PMID);
- if(p == nil)
- return nil;
-
- s = smalloc(sizeof(*s));
- memmove(s, &smbusproto, sizeof(*s));
- s->arg = p;
-
- // disable the smbus
- pcicfgw8(p, SMBconfig, IRQ9enable|0);
-
- // see if bios gave us a viable port space
- s->base = pcicfgr32(p, SMBbase) & ~1;
-print("SMB base from bios is 0x%lux\n", s->base);
- if(ioalloc(s->base, 0xd, 0, "piix4smbus") < 0){
- s->base = ioalloc(-1, 0xd, 2, "piix4smbus");
- if(s->base < 0){
- free(s);
- print("piix4smbus: can't allocate io port\n");
- return nil;
- }
-print("SMB base ialloc is 0x%lux\n", s->base);
- pcicfgw32(p, SMBbase, s->base|1);
- }
-
- // disable SMBus interrupts, abort any transaction in progress
- outb(s->base+Hostcontrol, Kill);
- outb(s->base+Slavecontrol, 0);
-
- // enable the smbus
- pcicfgw8(p, SMBconfig, IRQ9enable|SMBenable);
-
- return s;
-}
diff --git a/os/pc/pix b/os/pc/pix
deleted file mode 100644
index 2fa7639b..00000000
--- a/os/pc/pix
+++ /dev/null
@@ -1,156 +0,0 @@
-dev
- root
- cons
- arch
- env
- mnt
- pipe
- prog
- rtc
- srv
- dup
- ssl
- cap
-
-# draw screen vga vgax cga
-# pointer
-# vga
-
- ip bootp ip ipv6 ipaux iproute arp netlog ptclbsum386 iprouter plan9 nullmedium pktmedium
- ether netif netaux
-
- sd
- ds
- uart
- floppy dma
- tinyfs
-# mouse
-# dbg x86break
-
-ip
- il
- tcp
- udp
- rudp
- gre
- ipifc
- icmp
- icmp6
- ipmux
-lib
- interp
- keyring
- sec
- mp
-# draw
-# memlayer
-# memdraw
-# tk
- math
- kern
-
-link
-# ps2mouse
- ether82557 pci
- ethermedium
- loopbackmedium
- netdevmedium
-
-misc
-# vgaclgd542x
-# vgas3 +cur vgasavage
-# cga
- sdata pci sdscsi
-
- uarti8250
-
-mod
- sys
-# draw
-# tk
- keyring
- crypt
- ipints
-
- math
-
-init
- soeinit # it will do
-
-code
- int kernel_pool_pcnt = 10;
- int main_pool_pcnt = 40;
- int heap_pool_pcnt = 20;
- int image_pool_pcnt = 0;
- int cflag=0;
- int swcursor=0;
- int consoleprint=0;
- void screeninit(void){}
-
-port
- alarm
- alloc
- allocb
- chan
- dev
- dial
- dis
- discall
- exception
- exportfs
- inferno
- latin1
- nocache
- nodynld
- parse
- pgrp
- print
- proc
- qio
- qlock
- random
- sysfile
- taslock
- xalloc
-
-root
- /chan
- /dev
- /dis
- /env
- /fd /
- /n
- /n/remote
- /net
- /nvfs
- /prog
- /dis/lib
- /dis/svc
- /dis/wm
- /osinit.dis
- /dis/sh.dis
- /dis/ls.dis
- /dis/cat.dis
- /dis/bind.dis
- /dis/mount.dis
- /dis/pwd.dis
- /dis/echo.dis
- /dis/cd.dis
- /dis/lib/bufio.dis
- /dis/lib/string.dis
- /dis/lib/readdir.dis
- /dis/lib/workdir.dis
- /dis/lib/daytime.dis
- /dis/lib/auth.dis
- /dis/lib/ssl.dis
- /dis/lib/filepat.dis
-
-# kfs
- /dis/disk/kfs.dis
- /dis/lib/arg.dis
- /dis/lib/daytime.dis
- /dis/lib/string.dis
- /dis/lib/styx.dis
-
-# auth
- /nvfs/default /usr/inferno/keyring/default
diff --git a/os/pc/ps2mouse.c b/os/pc/ps2mouse.c
deleted file mode 100644
index 49654bad..00000000
--- a/os/pc/ps2mouse.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-/*
- * mouse types
- */
-enum
-{
- Mouseother= 0,
- Mouseserial= 1,
- MousePS2= 2,
-};
-
-static int mousetype;
-
-/*
- * ps/2 mouse message is three bytes
- *
- * byte 0 - 0 0 SDY SDX 1 M R L
- * byte 1 - DX
- * byte 2 - DY
- *
- * shift & left button is the same as middle button
- */
-static void
-ps2mouseputc(int c, int shift)
-{
- static short msg[3];
- static int nb;
- static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 };
- int buttons, dx, dy;
-
- /*
- * check byte 0 for consistency
- */
- if(nb==0 && (c&0xc8)!=0x08)
- return;
-
- msg[nb] = c;
- if(++nb == 3){
- nb = 0;
- if(msg[0] & 0x10)
- msg[1] |= 0xFF00;
- if(msg[0] & 0x20)
- msg[2] |= 0xFF00;
-
- buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
- dx = msg[1];
- dy = -msg[2];
- mousetrack(buttons, dx, dy, 1);
- }
- return;
-}
-
-/*
- * set up a ps2 mouse
- */
-static void
-ps2mouse(void)
-{
- if(mousetype == MousePS2)
- return;
-
- i8042auxenable(ps2mouseputc);
- /* make mouse streaming, enabled */
- i8042auxcmd(0xEA);
- i8042auxcmd(0xF4);
-
- mousetype = MousePS2;
-}
-
-void
-ps2mouselink(void)
-{
- /*
- * hack
- */
- ps2mouse();
-}
diff --git a/os/pc/ptclbsum386.s b/os/pc/ptclbsum386.s
deleted file mode 100644
index ba0a6a4d..00000000
--- a/os/pc/ptclbsum386.s
+++ /dev/null
@@ -1,126 +0,0 @@
-TEXT ptclbsum(SB), $0
- MOVL addr+0(FP), SI
- MOVL len+4(FP), CX
-
- XORL AX, AX /* sum */
-
- TESTL $1, SI /* byte aligned? */
- MOVL SI, DI
- JEQ _2align
-
- DECL CX
- JLT _return
-
- MOVB 0x00(SI), AH
- INCL SI
-
-_2align:
- TESTL $2, SI /* word aligned? */
- JEQ _32loop
-
- CMPL CX, $2 /* less than 2 bytes? */
- JLT _1dreg
- SUBL $2, CX
-
- XORL BX, BX
- MOVW 0x00(SI), BX
- ADDL BX, AX
- ADCL $0, AX
- LEAL 2(SI), SI
-
-_32loop:
- CMPL CX, $0x20
- JLT _8loop
-
- MOVL CX, BP
- SHRL $5, BP
- ANDL $0x1F, CX
-
-_32loopx:
- MOVL 0x00(SI), BX
- MOVL 0x1C(SI), DX
- ADCL BX, AX
- MOVL 0x04(SI), BX
- ADCL DX, AX
- MOVL 0x10(SI), DX
- ADCL BX, AX
- MOVL 0x08(SI), BX
- ADCL DX, AX
- MOVL 0x14(SI), DX
- ADCL BX, AX
- MOVL 0x0C(SI), BX
- ADCL DX, AX
- MOVL 0x18(SI), DX
- ADCL BX, AX
- LEAL 0x20(SI), SI
- ADCL DX, AX
-
- DECL BP
- JNE _32loopx
-
- ADCL $0, AX
-
-_8loop:
- CMPL CX, $0x08
- JLT _2loop
-
- MOVL CX, BP
- SHRL $3, BP
- ANDL $0x07, CX
-
-_8loopx:
- MOVL 0x00(SI), BX
- ADCL BX, AX
- MOVL 0x04(SI), DX
- ADCL DX, AX
-
- LEAL 0x08(SI), SI
- DECL BP
- JNE _8loopx
-
- ADCL $0, AX
-
-_2loop:
- CMPL CX, $0x02
- JLT _1dreg
-
- MOVL CX, BP
- SHRL $1, BP
- ANDL $0x01, CX
-
-_2loopx:
- MOVWLZX 0x00(SI), BX
- ADCL BX, AX
-
- LEAL 0x02(SI), SI
- DECL BP
- JNE _2loopx
-
- ADCL $0, AX
-
-_1dreg:
- TESTL $1, CX /* 1 byte left? */
- JEQ _fold
-
- XORL BX, BX
- MOVB 0x00(SI), BX
- ADDL BX, AX
- ADCL $0, AX
-
-_fold:
- MOVL AX, BX
- SHRL $16, BX
- JEQ _swab
-
- ANDL $0xFFFF, AX
- ADDL BX, AX
- JMP _fold
-
-_swab:
- TESTL $1, addr+0(FP)
- /*TESTL $1, DI*/
- JNE _return
- XCHGB AH, AL
-
-_return:
- RET
diff --git a/os/pc/screen.c b/os/pc/screen.c
deleted file mode 100644
index e879b050..00000000
--- a/os/pc/screen.c
+++ /dev/null
@@ -1,410 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19)
-
-Point ZP = {0, 0};
-
-Rectangle physgscreenr;
-Cursorinfo cursor; /* TO DO */
-
-Memdata gscreendata;
-Memimage *gscreen;
-
-VGAscr vgascreen[1];
-
-Cursor arrow = {
- { -1, -1 },
- { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
- 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
- 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
- 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
- },
- { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
- 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
- 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
- 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
- },
-};
-
-int
-screensize(int x, int y, int z, ulong chan)
-{
- VGAscr *scr;
-
- memimageinit();
- scr = &vgascreen[0];
-
- /*
- * BUG: need to check if any xalloc'ed memory needs to
- * be given back if aperture is set.
- */
- if(scr->aperture == 0){
- int width = (x*z)/BI2WD;
-
- gscreendata.bdata = xalloc(width*BY2WD*y);
- if(gscreendata.bdata == 0)
- error("screensize: vga soft memory");
-/* memset(gscreendata.bdata, 0x72, width*BY2WD*y); /* not really black */
- scr->useflush = 1;
- scr->aperture = VGAMEM();
- scr->apsize = 1<<16;
- }
- else
- gscreendata.bdata = KADDR(scr->aperture);
-
- if(gscreen)
- freememimage(gscreen);
-
- gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
- vgaimageinit(chan);
- if(gscreen == nil)
- return -1;
-
- if(scr->dev && scr->dev->flush)
- scr->useflush = 1;
-
- scr->palettedepth = 6; /* default */
- scr->gscreendata = &gscreendata;
- scr->memdefont = getmemdefont();
- scr->gscreen = gscreen;
-
- physgscreenr = gscreen->r;
-
- drawcmap();
- return 0;
-}
-
-int
-screenaperture(int size, int align)
-{
- VGAscr *scr;
- ulong aperture;
-
- scr = &vgascreen[0];
-
- if(size == 0){
- if(scr->aperture && scr->isupamem)
- upafree(scr->aperture, scr->apsize);
- scr->aperture = 0;
- scr->isupamem = 0;
- return 0;
- }
- if(scr->dev && scr->dev->linear){
- aperture = scr->dev->linear(scr, &size, &align);
- if(aperture == 0)
- return 1;
- }else{
- aperture = upamalloc(0, size, align);
- if(aperture == 0)
- return 1;
-
- if(scr->aperture && scr->isupamem)
- upafree(scr->aperture, scr->apsize);
- scr->isupamem = 1;
- }
-
- scr->aperture = aperture;
- scr->apsize = size;
-
- return 0;
-}
-
-uchar*
-attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
-{
- VGAscr *scr;
-
- scr = &vgascreen[0];
- if(scr->gscreen == nil || scr->gscreendata == nil)
- return nil;
-
- *r = scr->gscreen->clipr;
- *chan = scr->gscreen->chan;
- *d = scr->gscreen->depth;
- *width = scr->gscreen->width;
- *softscreen = scr->useflush;
-
- return scr->gscreendata->bdata;
-}
-
-/*
- * It would be fair to say that this doesn't work for >8-bit screens.
- */
-void
-flushmemscreen(Rectangle r)
-{
- VGAscr *scr;
- uchar *sp, *disp, *sdisp, *edisp;
- int y, len, incs, off, page;
-
- scr = &vgascreen[0];
- if(scr->dev && scr->dev->flush){
- scr->dev->flush(scr, r);
- return;
- }
- if(scr->gscreen == nil || scr->useflush == 0)
- return;
- if(scr->dev == nil || scr->dev->page == nil)
- return;
-
- if(rectclip(&r, scr->gscreen->r) == 0)
- return;
-
- incs = scr->gscreen->width * BY2WD;
-
- switch(scr->gscreen->depth){
- default:
- len = 0;
- panic("flushmemscreen: depth\n");
- break;
- case 8:
- len = Dx(r);
- break;
- }
- if(len < 1)
- return;
-
- off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
- page = off/scr->apsize;
- off %= scr->apsize;
- disp = KADDR(scr->aperture);
- sdisp = disp+off;
- edisp = disp+scr->apsize;
-
- off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
-
- sp = scr->gscreendata->bdata + off;
-
- scr->dev->page(scr, page);
- for(y = r.min.y; y < r.max.y; y++) {
- if(sdisp + incs < edisp) {
- memmove(sdisp, sp, len);
- sp += incs;
- sdisp += incs;
- }
- else {
- off = edisp - sdisp;
- page++;
- if(off <= len){
- if(off > 0)
- memmove(sdisp, sp, off);
- scr->dev->page(scr, page);
- if(len - off > 0)
- memmove(disp, sp+off, len - off);
- }
- else {
- memmove(sdisp, sp, len);
- scr->dev->page(scr, page);
- }
- sp += incs;
- sdisp += incs - scr->apsize;
- }
- }
-}
-
-void
-getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
-{
- VGAscr *scr;
- ulong x;
-
- scr = &vgascreen[0];
- if(scr->gscreen == nil)
- return;
-
- switch(scr->gscreen->depth){
- default:
- x = 0x0F;
- break;
- case 8:
- x = 0xFF;
- break;
- }
- p &= x;
-
- lock(&cursor);
- *pr = scr->colormap[p][0];
- *pg = scr->colormap[p][1];
- *pb = scr->colormap[p][2];
- unlock(&cursor);
-}
-
-int
-setpalette(ulong p, ulong r, ulong g, ulong b)
-{
- VGAscr *scr;
- int d;
-
- scr = &vgascreen[0];
- d = scr->palettedepth;
-
- lock(&cursor);
- scr->colormap[p][0] = r;
- scr->colormap[p][1] = g;
- scr->colormap[p][2] = b;
- vgao(PaddrW, p);
- vgao(Pdata, r>>(32-d));
- vgao(Pdata, g>>(32-d));
- vgao(Pdata, b>>(32-d));
- unlock(&cursor);
-
- return ~0;
-}
-
-/*
- * On some video cards (e.g. Mach64), the palette is used as the
- * DAC registers for >8-bit modes. We don't want to set them when the user
- * is trying to set a colormap and the card is in one of these modes.
- */
-int
-setcolor(ulong p, ulong r, ulong g, ulong b)
-{
- VGAscr *scr;
- int x;
-
- scr = &vgascreen[0];
- if(scr->gscreen == nil)
- return 0;
-
- switch(scr->gscreen->depth){
- case 1:
- case 2:
- case 4:
- x = 0x0F;
- break;
- case 8:
- x = 0xFF;
- break;
- default:
- return 0;
- }
- p &= x;
-
- return setpalette(p, r, g, b);
-}
-
-int
-cursoron(int dolock)
-{
- VGAscr *scr;
- int v;
-
- scr = &vgascreen[0];
- if(scr->cur == nil || scr->cur->move == nil)
- return 0;
-
- if(dolock)
- lock(&cursor);
- v = scr->cur->move(scr, mousexy());
- if(dolock)
- unlock(&cursor);
-
- return v;
-}
-
-void
-cursoroff(int)
-{
-}
-
-void
-setcursor(Cursor* curs)
-{
- VGAscr *scr;
-
- scr = &vgascreen[0];
- if(scr->cur == nil || scr->cur->load == nil)
- return;
-
- scr->cur->load(scr, curs);
-}
-
-int hwaccel = 1;
-int hwblank = 0; /* turned on by drivers that are known good */
-int panning = 0;
-
-int
-hwdraw(Memdrawparam *par)
-{
- VGAscr *scr;
- Memimage *dst, *src;
- int m;
-
- if(hwaccel == 0)
- return 0;
-
- dst = par->dst;
- scr = &vgascreen[0];
- if(dst == nil || dst->data == nil)
- return 0;
-
- if(dst->data->bdata != gscreendata.bdata)
- return 0;
-
- if(scr->fill==nil && scr->scroll==nil)
- return 0;
-
- /*
- * If we have an opaque mask and source is one opaque
- * pixel we can convert to the destination format and just
- * replicate with memset.
- */
- m = Simplesrc|Simplemask|Fullmask;
- if(scr->fill
- && (par->state&m)==m
- && ((par->srgba&0xFF) == 0xFF)
- && (par->op&S) == S)
- return scr->fill(scr, par->r, par->sdval);
-
- /*
- * If no source alpha, an opaque mask, we can just copy the
- * source onto the destination. If the channels are the same and
- * the source is not replicated, memmove suffices.
- */
- m = Simplemask|Fullmask;
- src = par->src;
- if(scr->scroll
- && src->data->bdata==dst->data->bdata
- && !(src->flags&Falpha)
- && (par->state&m)==m
- && (par->op&S) == S)
- return scr->scroll(scr, par->r, par->sr);
-
- return 0;
-}
-
-void
-blankscreen(int blank)
-{
- VGAscr *scr;
-
- scr = &vgascreen[0];
- if(hwblank){
- if(scr->blank)
- scr->blank(scr, blank);
- else
- vgablank(scr, blank);
- }
-}
-
-void
-cursorenable(void)
-{
-}
-
-void
-cursordisable(void)
-{
-}
diff --git a/os/pc/screen.h b/os/pc/screen.h
deleted file mode 100644
index bcc1f230..00000000
--- a/os/pc/screen.h
+++ /dev/null
@@ -1,173 +0,0 @@
-typedef struct Cursor Cursor;
-
-enum {
- CURSWID = 16,
- CURSHGT = 16,
-};
-
-struct Cursor
-{
- Point offset;
- uchar clr[CURSWID/BI2BY*CURSHGT];
- uchar set[CURSWID/BI2BY*CURSHGT];
-};
-typedef struct Cursorinfo Cursorinfo;
-struct Cursorinfo {
- Cursor;
- Lock;
-};
-
-/* devmouse.c */
-extern void mousetrack(int, int, int, int);
-extern Point mousexy(void);
-
-extern void mouseaccelerate(int);
-extern int m3mouseputc(Queue*, int);
-extern int m5mouseputc(Queue*, int);
-extern int mouseputc(Queue*, int);
-
-extern Cursorinfo cursor;
-extern Cursor arrow;
-
-/*
- * Generic VGA registers.
- */
-enum {
- MiscW = 0x03C2, /* Miscellaneous Output (W) */
- MiscR = 0x03CC, /* Miscellaneous Output (R) */
- Status0 = 0x03C2, /* Input status 0 (R) */
- Status1 = 0x03DA, /* Input Status 1 (R) */
- FeatureR = 0x03CA, /* Feature Control (R) */
- FeatureW = 0x03DA, /* Feature Control (W) */
-
- Seqx = 0x03C4, /* Sequencer Index, Data at Seqx+1 */
- Crtx = 0x03D4, /* CRT Controller Index, Data at Crtx+1 */
- Grx = 0x03CE, /* Graphics Controller Index, Data at Grx+1 */
- Attrx = 0x03C0, /* Attribute Controller Index and Data */
-
- PaddrW = 0x03C8, /* Palette Address Register, write */
- Pdata = 0x03C9, /* Palette Data Register */
- Pixmask = 0x03C6, /* Pixel Mask Register */
- PaddrR = 0x03C7, /* Palette Address Register, read */
- Pstatus = 0x03C7, /* DAC Status (RO) */
-
- Pcolours = 256, /* Palette */
- Pred = 0,
- Pgreen = 1,
- Pblue = 2,
-
- Pblack = 0x00,
- Pwhite = 0xFF,
-};
-
-#define VGAMEM() 0xA0000
-#define vgai(port) inb(port)
-#define vgao(port, data) outb(port, data)
-
-extern int vgaxi(long, uchar);
-extern int vgaxo(long, uchar, uchar);
-
-/*
- */
-typedef struct VGAdev VGAdev;
-typedef struct VGAcur VGAcur;
-typedef struct VGAscr VGAscr;
-
-struct VGAdev {
- char* name;
-
- void (*enable)(VGAscr*);
- void (*disable)(VGAscr*);
- void (*page)(VGAscr*, int);
- ulong (*linear)(VGAscr*, int*, int*);
- void (*drawinit)(VGAscr*);
- int (*fill)(VGAscr*, Rectangle, ulong);
- void (*ovlctl)(VGAscr*, Chan*, void*, int);
- int (*ovlwrite)(VGAscr*, void*, int, vlong);
- void (*flush)(VGAscr*, Rectangle);
-};
-
-struct VGAcur {
- char* name;
-
- void (*enable)(VGAscr*);
- void (*disable)(VGAscr*);
- void (*load)(VGAscr*, Cursor*);
- int (*move)(VGAscr*, Point);
-
- int doespanning;
-};
-
-/*
- */
-struct VGAscr {
- Lock devlock;
- VGAdev* dev;
-
- VGAcur* cur;
- ulong storage;
- Cursor;
-
- int useflush;
-
- ulong aperture; /* physical address */
- int isupamem;
- int apsize;
-
- ulong io; /* device specific registers */
-
- ulong colormap[Pcolours][3];
- int palettedepth;
-
- ulong *mmio;
- Memimage* gscreen;
- Memdata* gscreendata;
- Memsubfont* memdefont;
-
- int (*fill)(VGAscr*, Rectangle, ulong);
- int (*scroll)(VGAscr*, Rectangle, Rectangle);
- void (*blank)(VGAscr*, int);
- ulong id; /* internal identifier for driver use */
- int isblank;
- int overlayinit;
-};
-
-extern VGAscr vgascreen[];
-
-enum {
- Backgnd = 0, /* black */
-};
-
-/* mouse.c */
-extern void mousectl(Cmdbuf*);
-
-/* screen.c */
-extern int hwaccel; /* use hw acceleration; default on */
-extern int hwblank; /* use hw blanking; default on */
-extern int panning; /* use virtual screen panning; default off */
-extern void addvgaseg(char*, ulong, ulong);
-extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*);
-extern void flushmemscreen(Rectangle);
-extern int cursoron(int);
-extern void cursoroff(int);
-extern void setcursor(Cursor*);
-extern int screensize(int, int, int, ulong);
-extern int screenaperture(int, int);
-extern Rectangle physgscreenr; /* actual monitor size */
-extern void blankscreen(int);
-
-/* devdraw.c */
-extern void deletescreenimage(void);
-extern int drawhasclients(void);
-extern ulong blanktime;
-extern void setscreenimageclipr(Rectangle);
-extern void drawflush(void);
-extern int drawidletime(void);
-
-/* vga.c */
-extern void vgascreenwin(VGAscr*);
-extern void vgaimageinit(ulong);
-extern ulong vgapcilinear(VGAscr*, int*, int*, int, int);
-
-extern void drawblankscreen(int);
-extern void vgablank(VGAscr*, int);
diff --git a/os/pc/sd53c8xx.c b/os/pc/sd53c8xx.c
deleted file mode 100644
index a03ac93c..00000000
--- a/os/pc/sd53c8xx.c
+++ /dev/null
@@ -1,2135 +0,0 @@
-/*
- * NCR/Symbios/LSI Logic 53c8xx driver for Plan 9
- * Nigel Roles (nigel@9fs.org)
- *
- * 27/5/02 Fixed problems with transfers >= 256 * 512
- *
- * 13/3/01 Fixed microcode to support targets > 7
- *
- * 01/12/00 Removed previous comments. Fixed a small problem in
- * mismatch recovery for targets with synchronous offsets of >=16
- * connected to >=875s. Thanks, Jean.
- *
- * Known problems
- *
- * Read/write mismatch recovery may fail on 53c1010s. Really need to get a manual.
- */
-
-#define MAXTARGET 16 /* can be 8 or 16 */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "../port/sd.h"
-extern SDifc sd53c8xxifc;
-
-/**********************************/
-/* Portable configuration macros */
-/**********************************/
-
-//#define BOOTDEBUG
-//#define ASYNC_ONLY
-//#define INTERNAL_SCLK
-//#define ALWAYS_DO_WDTR
-#define WMR_DEBUG
-
-/**********************************/
-/* CPU specific macros */
-/**********************************/
-
-#define PRINTPREFIX "sd53c8xx: "
-
-#ifdef BOOTDEBUG
-
-#define KPRINT oprint
-#define IPRINT intrprint
-#define DEBUG(n) 1
-#define IFLUSH() iflush()
-
-#else
-
-#define KPRINT if(0) print
-#define IPRINT if(0) print
-#define DEBUG(n) (0)
-#define IFLUSH()
-
-#endif /* BOOTDEBUG */
-
-/*******************************/
-/* General */
-/*******************************/
-
-#ifndef DMASEG
-#define DMASEG(x) PCIWADDR(x)
-#define legetl(x) (*(ulong*)(x))
-#define lesetl(x,v) (*(ulong*)(x) = (v))
-#define swabl(a,b,c)
-#else
-#endif /*DMASEG */
-#define DMASEG_TO_KADDR(x) KADDR((x)-PCIWINDOW)
-#define KPTR(x) ((x) == 0 ? 0 : DMASEG_TO_KADDR(x))
-
-#define MEGA 1000000L
-#ifdef INTERNAL_SCLK
-#define SCLK (33 * MEGA)
-#else
-#define SCLK (40 * MEGA)
-#endif /* INTERNAL_SCLK */
-#define ULTRA_NOCLOCKDOUBLE_SCLK (80 * MEGA)
-
-#define MAXSYNCSCSIRATE (5 * MEGA)
-#define MAXFASTSYNCSCSIRATE (10 * MEGA)
-#define MAXULTRASYNCSCSIRATE (20 * MEGA)
-#define MAXULTRA2SYNCSCSIRATE (40 * MEGA)
-#define MAXASYNCCORERATE (25 * MEGA)
-#define MAXSYNCCORERATE (25 * MEGA)
-#define MAXFASTSYNCCORERATE (50 * MEGA)
-#define MAXULTRASYNCCORERATE (80 * MEGA)
-#define MAXULTRA2SYNCCORERATE (160 * MEGA)
-
-
-#define X_MSG 1
-#define X_MSG_SDTR 1
-#define X_MSG_WDTR 3
-
-struct na_patch {
- unsigned lwoff;
- unsigned char type;
-};
-
-typedef struct Ncr {
- uchar scntl0; /* 00 */
- uchar scntl1;
- uchar scntl2;
- uchar scntl3;
-
- uchar scid; /* 04 */
- uchar sxfer;
- uchar sdid;
- uchar gpreg;
-
- uchar sfbr; /* 08 */
- uchar socl;
- uchar ssid;
- uchar sbcl;
-
- uchar dstat; /* 0c */
- uchar sstat0;
- uchar sstat1;
- uchar sstat2;
-
- uchar dsa[4]; /* 10 */
-
- uchar istat; /* 14 */
- uchar istatpad[3];
-
- uchar ctest0; /* 18 */
- uchar ctest1;
- uchar ctest2;
- uchar ctest3;
-
- uchar temp[4]; /* 1c */
-
- uchar dfifo; /* 20 */
- uchar ctest4;
- uchar ctest5;
- uchar ctest6;
-
- uchar dbc[3]; /* 24 */
- uchar dcmd; /* 27 */
-
- uchar dnad[4]; /* 28 */
- uchar dsp[4]; /* 2c */
- uchar dsps[4]; /* 30 */
-
- uchar scratcha[4]; /* 34 */
-
- uchar dmode; /* 38 */
- uchar dien;
- uchar dwt;
- uchar dcntl;
-
- uchar adder[4]; /* 3c */
-
- uchar sien0; /* 40 */
- uchar sien1;
- uchar sist0;
- uchar sist1;
-
- uchar slpar; /* 44 */
- uchar slparpad0;
- uchar macntl;
- uchar gpcntl;
-
- uchar stime0; /* 48 */
- uchar stime1;
- uchar respid;
- uchar respidpad0;
-
- uchar stest0; /* 4c */
- uchar stest1;
- uchar stest2;
- uchar stest3;
-
- uchar sidl; /* 50 */
- uchar sidlpad[3];
-
- uchar sodl; /* 54 */
- uchar sodlpad[3];
-
- uchar sbdl; /* 58 */
- uchar sbdlpad[3];
-
- uchar scratchb[4]; /* 5c */
-} Ncr;
-
-typedef struct Movedata {
- uchar dbc[4];
- uchar pa[4];
-} Movedata;
-
-typedef enum NegoState {
- NeitherDone, WideInit, WideResponse, WideDone,
- SyncInit, SyncResponse, BothDone
-} NegoState;
-
-typedef enum State {
- Allocated, Queued, Active, Done
-} State;
-
-typedef struct Dsa {
- uchar stateb;
- uchar result;
- uchar dmablks;
- uchar flag; /* setbyte(state,3,...) */
-
- union {
- ulong dmancr; /* For block transfer: NCR order (little-endian) */
- uchar dmaaddr[4];
- };
-
- uchar target; /* Target */
- uchar pad0[3];
-
- uchar lun; /* Logical Unit Number */
- uchar pad1[3];
-
- uchar scntl3;
- uchar sxfer;
- uchar pad2[2];
-
- uchar next[4]; /* chaining for SCRIPT (NCR byte order) */
- struct Dsa *freechain; /* chaining for freelist */
- Rendez;
- uchar scsi_id_buf[4];
- Movedata msg_out_buf;
- Movedata cmd_buf;
- Movedata data_buf;
- Movedata status_buf;
- uchar msg_out[10]; /* enough to include SDTR */
- uchar status;
- int p9status;
- uchar parityerror;
-} Dsa;
-
-typedef enum Feature {
- BigFifo = 1, /* 536 byte fifo */
- BurstOpCodeFetch = 2, /* burst fetch opcodes */
- Prefetch = 4, /* prefetch 8 longwords */
- LocalRAM = 8, /* 4K longwords of local RAM */
- Differential = 16, /* Differential support */
- Wide = 32, /* Wide capable */
- Ultra = 64, /* Ultra capable */
- ClockDouble = 128, /* Has clock doubler */
- ClockQuad = 256, /* Has clock quadrupler (same as Ultra2) */
- Ultra2 = 256,
-} Feature;
-
-typedef enum Burst {
- Burst2 = 0,
- Burst4 = 1,
- Burst8 = 2,
- Burst16 = 3,
- Burst32 = 4,
- Burst64 = 5,
- Burst128 = 6
-} Burst;
-
-typedef struct Variant {
- ushort did;
- uchar maxrid; /* maximum allowed revision ID */
- char *name;
- Burst burst; /* codings for max burst */
- uchar maxsyncoff; /* max synchronous offset */
- uchar registers; /* number of 32 bit registers */
- unsigned feature;
-} Variant;
-
-static unsigned char cf2[] = { 6, 2, 3, 4, 6, 8, 12, 16 };
-#define NULTRA2SCF (sizeof(cf2)/sizeof(cf2[0]))
-#define NULTRASCF (NULTRA2SCF - 2)
-#define NSCF (NULTRASCF - 1)
-
-typedef struct Controller {
- Lock;
- struct {
- uchar scntl3;
- uchar stest2;
- } bios;
- uchar synctab[NULTRA2SCF - 1][8];/* table of legal tpfs */
- NegoState s[MAXTARGET];
- uchar scntl3[MAXTARGET];
- uchar sxfer[MAXTARGET];
- uchar cap[MAXTARGET]; /* capabilities byte from Identify */
- ushort capvalid; /* bit per target for validity of cap[] */
- ushort wide; /* bit per target set if wide negotiated */
- ulong sclk; /* clock speed of controller */
- uchar clockmult; /* set by synctabinit */
- uchar ccf; /* CCF bits */
- uchar tpf; /* best tpf value for this controller */
- uchar feature; /* requested features */
- int running; /* is the script processor running? */
- int ssm; /* single step mode */
- Ncr *n; /* pointer to registers */
- Variant *v; /* pointer to variant type */
- ulong *script; /* where the real script is */
- ulong scriptpa; /* where the real script is */
- Pcidev* pcidev;
- SDev* sdev;
-
- struct {
- Lock;
- uchar head[4]; /* head of free list (NCR byte order) */
- Dsa *tail;
- Dsa *freechain;
- } dsalist;
-
- QLock q[MAXTARGET]; /* queues for each target */
-} Controller;
-
-#define SYNCOFFMASK(c) (((c)->v->maxsyncoff * 2) - 1)
-#define SSIDMASK(c) (((c)->v->feature & Wide) ? 15 : 7)
-
-/* ISTAT */
-enum { Abrt = 0x80, Srst = 0x40, Sigp = 0x20, Sem = 0x10, Con = 0x08, Intf = 0x04, Sip = 0x02, Dip = 0x01 };
-
-/* DSTAT */
-enum { Dfe = 0x80, Mdpe = 0x40, Bf = 0x20, Abrted = 0x10, Ssi = 0x08, Sir = 0x04, Iid = 0x01 };
-
-/* SSTAT */
-enum { DataOut, DataIn, Cmd, Status, ReservedOut, ReservedIn, MessageOut, MessageIn };
-
-static void setmovedata(Movedata*, ulong, ulong);
-static void advancedata(Movedata*, long);
-static int bios_set_differential(Controller *c);
-
-static char *phase[] = {
- "data out", "data in", "command", "status",
- "reserved out", "reserved in", "message out", "message in"
-};
-
-#ifdef BOOTDEBUG
-#define DEBUGSIZE 10240
-char debugbuf[DEBUGSIZE];
-char *debuglast;
-
-static void
-intrprint(char *format, ...)
-{
- if (debuglast == 0)
- debuglast = debugbuf;
- debuglast = vseprint(debuglast, debugbuf + (DEBUGSIZE - 1), format, (&format + 1));
-}
-
-static void
-iflush()
-{
- int s;
- char *endp;
- s = splhi();
- if (debuglast == 0)
- debuglast = debugbuf;
- if (debuglast == debugbuf) {
- splx(s);
- return;
- }
- endp = debuglast;
- splx(s);
- screenputs(debugbuf, endp - debugbuf);
- s = splhi();
- memmove(debugbuf, endp, debuglast - endp);
- debuglast -= endp - debugbuf;
- splx(s);
-}
-
-static void
-oprint(char *format, ...)
-{
- int s;
-
- iflush();
- s = splhi();
- if (debuglast == 0)
- debuglast = debugbuf;
- debuglast = vseprint(debuglast, debugbuf + (DEBUGSIZE - 1), format, (&format + 1));
- splx(s);
- iflush();
-}
-#endif
-
-#include "sd53c8xx.i"
-
-static Dsa *
-dsaalloc(Controller *c, int target, int lun)
-{
- Dsa *d;
-
- ilock(&c->dsalist);
- if ((d = c->dsalist.freechain) == 0) {
- d = xalloc(sizeof(*d));
- if (DEBUG(1)) {
- KPRINT(PRINTPREFIX "%d/%d: allocated new dsa %lux\n", target, lun, (ulong)d);
- }
- lesetl(d->next, 0);
- lesetl(&d->stateb, A_STATE_ALLOCATED);
- if (legetl(c->dsalist.head) == 0)
- lesetl(c->dsalist.head, DMASEG(d)); /* ATOMIC?!? */
- else
- lesetl(c->dsalist.tail->next, DMASEG(d)); /* ATOMIC?!? */
- c->dsalist.tail = d;
- }
- else {
- if (DEBUG(1)) {
- KPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
- }
- c->dsalist.freechain = d->freechain;
- lesetl(&d->stateb, A_STATE_ALLOCATED);
- }
- iunlock(&c->dsalist);
- d->target = target;
- d->lun = lun;
- return d;
-}
-
-static void
-dsafree(Controller *c, Dsa *d)
-{
- ilock(&c->dsalist);
- d->freechain = c->dsalist.freechain;
- c->dsalist.freechain = d;
- lesetl(&d->stateb, A_STATE_FREE);
- iunlock(&c->dsalist);
-}
-
-static Dsa *
-dsafind(Controller *c, uchar target, uchar lun, uchar state)
-{
- Dsa *d;
- for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
- if (d->target != 0xff && d->target != target)
- continue;
- if (lun != 0xff && d->lun != lun)
- continue;
- if (state != 0xff && d->stateb != state)
- continue;
- break;
- }
- return d;
-}
-
-static void
-dumpncrregs(Controller *c, int intr)
-{
- int i;
- Ncr *n = c->n;
- int depth = c->v->registers / 4;
-
- if (intr) {
- IPRINT("sa = %.8lux\n", c->scriptpa);
- }
- else {
- KPRINT("sa = %.8lux\n", c->scriptpa);
- }
- for (i = 0; i < depth; i++) {
- int j;
- for (j = 0; j < 4; j++) {
- int k = j * depth + i;
- uchar *p;
-
- /* display little-endian to make 32-bit values readable */
- p = (uchar*)n+k*4;
- if (intr) {
- IPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80);
- }
- else {
- KPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80);
- }
- USED(p);
- }
- if (intr) {
- IPRINT("\n");
- }
- else {
- KPRINT("\n");
- }
- }
-}
-
-static int
-chooserate(Controller *c, int tpf, int *scfp, int *xferpp)
-{
- /* find lowest entry >= tpf */
- int besttpf = 1000;
- int bestscfi = 0;
- int bestxferp = 0;
- int scf, xferp;
- int maxscf;
-
- if (c->v->feature & Ultra2)
- maxscf = NULTRA2SCF;
- else if (c->v->feature & Ultra)
- maxscf = NULTRASCF;
- else
- maxscf = NSCF;
-
- /*
- * search large clock factors first since this should
- * result in more reliable transfers
- */
- for (scf = maxscf; scf >= 1; scf--) {
- for (xferp = 0; xferp < 8; xferp++) {
- unsigned char v = c->synctab[scf - 1][xferp];
- if (v == 0)
- continue;
- if (v >= tpf && v < besttpf) {
- besttpf = v;
- bestscfi = scf;
- bestxferp = xferp;
- }
- }
- }
- if (besttpf == 1000)
- return 0;
- if (scfp)
- *scfp = bestscfi;
- if (xferpp)
- *xferpp = bestxferp;
- return besttpf;
-}
-
-static void
-synctabinit(Controller *c)
-{
- int scf;
- unsigned long scsilimit;
- int xferp;
- unsigned long cr, sr;
- int tpf;
- int fast;
- int maxscf;
-
- if (c->v->feature & Ultra2)
- maxscf = NULTRA2SCF;
- else if (c->v->feature & Ultra)
- maxscf = NULTRASCF;
- else
- maxscf = NSCF;
-
- /*
- * for chips with no clock doubler, but Ultra capable (e.g. 860, or interestingly the
- * first spin of the 875), assume 80MHz
- * otherwise use the internal (33 Mhz) or external (40MHz) default
- */
-
- if ((c->v->feature & Ultra) != 0 && (c->v->feature & (ClockDouble | ClockQuad)) == 0)
- c->sclk = ULTRA_NOCLOCKDOUBLE_SCLK;
- else
- c->sclk = SCLK;
-
- /*
- * otherwise, if the chip is Ultra capable, but has a slow(ish) clock,
- * invoke the doubler
- */
-
- if (SCLK <= 40000000) {
- if (c->v->feature & ClockDouble) {
- c->sclk *= 2;
- c->clockmult = 1;
- }
- else if (c->v->feature & ClockQuad) {
- c->sclk *= 4;
- c->clockmult = 1;
- }
- else
- c->clockmult = 0;
- }
- else
- c->clockmult = 0;
-
- /* derive CCF from sclk */
- /* woebetide anyone with SCLK < 16.7 or > 80MHz */
- if (c->sclk <= 25 * MEGA)
- c->ccf = 1;
- else if (c->sclk <= 3750000)
- c->ccf = 2;
- else if (c->sclk <= 50 * MEGA)
- c->ccf = 3;
- else if (c->sclk <= 75 * MEGA)
- c->ccf = 4;
- else if ((c->v->feature & ClockDouble) && c->sclk <= 80 * MEGA)
- c->ccf = 5;
- else if ((c->v->feature & ClockQuad) && c->sclk <= 120 * MEGA)
- c->ccf = 6;
- else if ((c->v->feature & ClockQuad) && c->sclk <= 160 * MEGA)
- c->ccf = 7;
-
- for (scf = 1; scf < maxscf; scf++) {
- /* check for legal core rate */
- /* round up so we run slower for safety */
- cr = (c->sclk * 2 + cf2[scf] - 1) / cf2[scf];
- if (cr <= MAXSYNCCORERATE) {
- scsilimit = MAXSYNCSCSIRATE;
- fast = 0;
- }
- else if (cr <= MAXFASTSYNCCORERATE) {
- scsilimit = MAXFASTSYNCSCSIRATE;
- fast = 1;
- }
- else if ((c->v->feature & Ultra) && cr <= MAXULTRASYNCCORERATE) {
- scsilimit = MAXULTRASYNCSCSIRATE;
- fast = 2;
- }
- else if ((c->v->feature & Ultra2) && cr <= MAXULTRA2SYNCCORERATE) {
- scsilimit = MAXULTRA2SYNCSCSIRATE;
- fast = 3;
- }
- else
- continue;
- for (xferp = 11; xferp >= 4; xferp--) {
- int ok;
- int tp;
- /* calculate scsi rate - round up again */
- /* start from sclk for accuracy */
- int totaldivide = xferp * cf2[scf];
- sr = (c->sclk * 2 + totaldivide - 1) / totaldivide;
- if (sr > scsilimit)
- break;
- /*
- * now work out transfer period
- * round down now so that period is pessimistic
- */
- tp = (MEGA * 1000) / sr;
- /*
- * bounds check it
- */
- if (tp < 25 || tp > 255 * 4)
- continue;
- /*
- * spot stupid special case for Ultra or Ultra2
- * while working out factor
- */
- if (tp == 25)
- tpf = 10;
- else if (tp == 50)
- tpf = 12;
- else if (tp < 52)
- continue;
- else
- tpf = tp / 4;
- /*
- * now check tpf looks sensible
- * given core rate
- */
- switch (fast) {
- case 0:
- /* scf must be ccf for SCSI 1 */
- ok = tpf >= 50 && scf == c->ccf;
- break;
- case 1:
- ok = tpf >= 25 && tpf < 50;
- break;
- case 2:
- /*
- * must use xferp of 4, or 5 at a pinch
- * for an Ultra transfer
- */
- ok = xferp <= 5 && tpf >= 12 && tpf < 25;
- break;
- case 3:
- ok = xferp == 4 && (tpf == 10 || tpf == 11);
- break;
- default:
- ok = 0;
- }
- if (!ok)
- continue;
- c->synctab[scf - 1][xferp - 4] = tpf;
- }
- }
-
-#ifndef NO_ULTRA2
- if (c->v->feature & Ultra2)
- tpf = 10;
- else
-#endif
- if (c->v->feature & Ultra)
- tpf = 12;
- else
- tpf = 25;
- for (; tpf < 256; tpf++) {
- if (chooserate(c, tpf, &scf, &xferp) == tpf) {
- unsigned tp = tpf == 10 ? 25 : (tpf == 12 ? 50 : tpf * 4);
- unsigned long khz = (MEGA + tp - 1) / (tp);
- KPRINT(PRINTPREFIX "tpf=%d scf=%d.%.1d xferp=%d mhz=%ld.%.3ld\n",
- tpf, cf2[scf] / 2, (cf2[scf] & 1) ? 5 : 0,
- xferp + 4, khz / 1000, khz % 1000);
- USED(khz);
- if (c->tpf == 0)
- c->tpf = tpf; /* note lowest value for controller */
- }
- }
-}
-
-static void
-synctodsa(Dsa *dsa, Controller *c)
-{
-/*
- KPRINT("synctodsa(dsa=%lux, target=%d, scntl3=%.2lx sxfer=%.2x)\n",
- dsa, dsa->target, c->scntl3[dsa->target], c->sxfer[dsa->target]);
-*/
- dsa->scntl3 = c->scntl3[dsa->target];
- dsa->sxfer = c->sxfer[dsa->target];
-}
-
-static void
-setsync(Dsa *dsa, Controller *c, int target, uchar ultra, uchar scf, uchar xferp, uchar reqack)
-{
- c->scntl3[target] =
- (c->scntl3[target] & 0x08) | (((scf << 4) | c->ccf | (ultra << 7)) & ~0x08);
- c->sxfer[target] = (xferp << 5) | reqack;
- c->s[target] = BothDone;
- if (dsa) {
- synctodsa(dsa, c);
- c->n->scntl3 = c->scntl3[target];
- c->n->sxfer = c->sxfer[target];
- }
-}
-
-static void
-setasync(Dsa *dsa, Controller *c, int target)
-{
- setsync(dsa, c, target, 0, c->ccf, 0, 0);
-}
-
-static void
-setwide(Dsa *dsa, Controller *c, int target, uchar wide)
-{
- c->scntl3[target] = wide ? (1 << 3) : 0;
- setasync(dsa, c, target);
- c->s[target] = WideDone;
-}
-
-static int
-buildsdtrmsg(uchar *buf, uchar tpf, uchar offset)
-{
- *buf++ = X_MSG;
- *buf++ = 3;
- *buf++ = X_MSG_SDTR;
- *buf++ = tpf;
- *buf = offset;
- return 5;
-}
-
-static int
-buildwdtrmsg(uchar *buf, uchar expo)
-{
- *buf++ = X_MSG;
- *buf++ = 2;
- *buf++ = X_MSG_WDTR;
- *buf = expo;
- return 4;
-}
-
-static void
-start(Controller *c, long entry)
-{
- ulong p;
-
- if (c->running)
- panic(PRINTPREFIX "start called while running");
- c->running = 1;
- p = c->scriptpa + entry;
- lesetl(c->n->dsp, p);
- if (c->ssm)
- c->n->dcntl |= 0x4; /* start DMA in SSI mode */
-}
-
-static void
-ncrcontinue(Controller *c)
-{
- if (c->running)
- panic(PRINTPREFIX "ncrcontinue called while running");
- /* set the start DMA bit to continue execution */
- c->running = 1;
- c->n->dcntl |= 0x4;
-}
-
-static void
-softreset(Controller *c)
-{
- Ncr *n = c->n;
-
- n->istat = Srst; /* software reset */
- n->istat = 0;
- /* general initialisation */
- n->scid = (1 << 6) | 7; /* respond to reselect, ID 7 */
- n->respid = 1 << 7; /* response ID = 7 */
-
-#ifdef INTERNAL_SCLK
- n->stest1 = 0x80; /* disable external scsi clock */
-#else
- n->stest1 = 0x00;
-#endif
-
- n->stime0 = 0xdd; /* about 0.5 second timeout on each device */
- n->scntl0 |= 0x8; /* Enable parity checking */
-
- /* continued setup */
- n->sien0 = 0x8f;
- n->sien1 = 0x04;
- n->dien = 0x7d;
- n->stest3 = 0x80; /* TolerANT enable */
- c->running = 0;
-
- if (c->v->feature & BigFifo)
- n->ctest5 = (1 << 5);
- n->dmode = c->v->burst << 6; /* set burst length bits */
- if (c->v->burst & 4)
- n->ctest5 |= (1 << 2); /* including overflow into ctest5 bit 2 */
- if (c->v->feature & Prefetch)
- n->dcntl |= (1 << 5); /* prefetch enable */
- else if (c->v->feature & BurstOpCodeFetch)
- n->dmode |= (1 << 1); /* burst opcode fetch */
- if (c->v->feature & Differential) {
- /* chip capable */
- if ((c->feature & Differential) || bios_set_differential(c)) {
- /* user enabled, or some evidence bios set differential */
- if (n->sstat2 & (1 << 2))
- print(PRINTPREFIX "can't go differential; wrong cable\n");
- else {
- n->stest2 = (1 << 5);
- print(PRINTPREFIX "differential mode set\n");
- }
- }
- }
- if (c->clockmult) {
- n->stest1 |= (1 << 3); /* power up doubler */
- delay(2);
- n->stest3 |= (1 << 5); /* stop clock */
- n->stest1 |= (1 << 2); /* enable doubler */
- n->stest3 &= ~(1 << 5); /* start clock */
- /* pray */
- }
-}
-
-static void
-msgsm(Dsa *dsa, Controller *c, int msg, int *cont, int *wakeme)
-{
- uchar histpf, hisreqack;
- int tpf;
- int scf, xferp;
- int len;
-
- Ncr *n = c->n;
-
- switch (c->s[dsa->target]) {
- case SyncInit:
- switch (msg) {
- case A_SIR_MSG_SDTR:
- /* reply to my SDTR */
- histpf = n->scratcha[2];
- hisreqack = n->scratcha[3];
- KPRINT(PRINTPREFIX "%d: SDTN response %d %d\n",
- dsa->target, histpf, hisreqack);
-
- if (hisreqack == 0)
- setasync(dsa, c, dsa->target);
- else {
- /* hisreqack should be <= c->v->maxsyncoff */
- tpf = chooserate(c, histpf, &scf, &xferp);
- KPRINT(PRINTPREFIX "%d: SDTN: using %d %d\n",
- dsa->target, tpf, hisreqack);
- setsync(dsa, c, dsa->target, tpf < 25, scf, xferp, hisreqack);
- }
- *cont = -2;
- return;
- case A_SIR_EV_PHASE_SWITCH_AFTER_ID:
- /* target ignored ATN for message after IDENTIFY - not SCSI-II */
- KPRINT(PRINTPREFIX "%d: illegal phase switch after ID message - SCSI-1 device?\n", dsa->target);
- KPRINT(PRINTPREFIX "%d: SDTN: async\n", dsa->target);
- setasync(dsa, c, dsa->target);
- *cont = E_to_decisions;
- return;
- case A_SIR_MSG_REJECT:
- /* rejection of my SDTR */
- KPRINT(PRINTPREFIX "%d: SDTN: rejected SDTR\n", dsa->target);
- //async:
- KPRINT(PRINTPREFIX "%d: SDTN: async\n", dsa->target);
- setasync(dsa, c, dsa->target);
- *cont = -2;
- return;
- }
- break;
- case WideInit:
- switch (msg) {
- case A_SIR_MSG_WDTR:
- /* reply to my WDTR */
- KPRINT(PRINTPREFIX "%d: WDTN: response %d\n",
- dsa->target, n->scratcha[2]);
- setwide(dsa, c, dsa->target, n->scratcha[2]);
- *cont = -2;
- return;
- case A_SIR_EV_PHASE_SWITCH_AFTER_ID:
- /* target ignored ATN for message after IDENTIFY - not SCSI-II */
- KPRINT(PRINTPREFIX "%d: illegal phase switch after ID message - SCSI-1 device?\n", dsa->target);
- setwide(dsa, c, dsa->target, 0);
- *cont = E_to_decisions;
- return;
- case A_SIR_MSG_REJECT:
- /* rejection of my SDTR */
- KPRINT(PRINTPREFIX "%d: WDTN: rejected WDTR\n", dsa->target);
- setwide(dsa, c, dsa->target, 0);
- *cont = -2;
- return;
- }
- break;
-
- case NeitherDone:
- case WideDone:
- case BothDone:
- switch (msg) {
- case A_SIR_MSG_WDTR: {
- uchar hiswide, mywide;
- hiswide = n->scratcha[2];
- mywide = (c->v->feature & Wide) != 0;
- KPRINT(PRINTPREFIX "%d: WDTN: target init %d\n",
- dsa->target, hiswide);
- if (hiswide < mywide)
- mywide = hiswide;
- KPRINT(PRINTPREFIX "%d: WDTN: responding %d\n",
- dsa->target, mywide);
- setwide(dsa, c, dsa->target, mywide);
- len = buildwdtrmsg(dsa->msg_out, mywide);
- setmovedata(&dsa->msg_out_buf, DMASEG(dsa->msg_out), len);
- *cont = E_response;
- c->s[dsa->target] = WideResponse;
- return;
- }
- case A_SIR_MSG_SDTR:
-#ifdef ASYNC_ONLY
- *cont = E_reject;
- return;
-#else
- /* target decides to renegotiate */
- histpf = n->scratcha[2];
- hisreqack = n->scratcha[3];
- KPRINT(PRINTPREFIX "%d: SDTN: target init %d %d\n",
- dsa->target, histpf, hisreqack);
- if (hisreqack == 0) {
- /* he wants asynchronous */
- setasync(dsa, c, dsa->target);
- tpf = 0;
- }
- else {
- /* he wants synchronous */
- tpf = chooserate(c, histpf, &scf, &xferp);
- if (hisreqack > c->v->maxsyncoff)
- hisreqack = c->v->maxsyncoff;
- KPRINT(PRINTPREFIX "%d: using %d %d\n",
- dsa->target, tpf, hisreqack);
- setsync(dsa, c, dsa->target, tpf < 25, scf, xferp, hisreqack);
- }
- /* build my SDTR message */
- len = buildsdtrmsg(dsa->msg_out, tpf, hisreqack);
- setmovedata(&dsa->msg_out_buf, DMASEG(dsa->msg_out), len);
- *cont = E_response;
- c->s[dsa->target] = SyncResponse;
- return;
-#endif
- }
- break;
- case WideResponse:
- switch (msg) {
- case A_SIR_EV_RESPONSE_OK:
- c->s[dsa->target] = WideDone;
- KPRINT(PRINTPREFIX "%d: WDTN: response accepted\n", dsa->target);
- *cont = -2;
- return;
- case A_SIR_MSG_REJECT:
- setwide(dsa, c, dsa->target, 0);
- KPRINT(PRINTPREFIX "%d: WDTN: response REJECTed\n", dsa->target);
- *cont = -2;
- return;
- }
- break;
- case SyncResponse:
- switch (msg) {
- case A_SIR_EV_RESPONSE_OK:
- c->s[dsa->target] = BothDone;
- KPRINT(PRINTPREFIX "%d: SDTN: response accepted (%s)\n",
- dsa->target, phase[n->sstat1 & 7]);
- *cont = -2;
- return; /* chf */
- case A_SIR_MSG_REJECT:
- setasync(dsa, c, dsa->target);
- KPRINT(PRINTPREFIX "%d: SDTN: response REJECTed\n", dsa->target);
- *cont = -2;
- return;
- }
- break;
- }
- KPRINT(PRINTPREFIX "%d: msgsm: state %d msg %d\n",
- dsa->target, c->s[dsa->target], msg);
- *wakeme = 1;
- return;
-}
-
-static void
-calcblockdma(Dsa *d, ulong base, ulong count)
-{
- ulong blocks;
- if (DEBUG(3))
- blocks = 0;
- else {
- blocks = count / A_BSIZE;
- if (blocks > 255)
- blocks = 255;
- }
- d->dmablks = blocks;
- d->dmaaddr[0] = base;
- d->dmaaddr[1] = base >> 8;
- d->dmaaddr[2] = base >> 16;
- d->dmaaddr[3] = base >> 24;
- setmovedata(&d->data_buf, base + blocks * A_BSIZE, count - blocks * A_BSIZE);
- d->flag = legetl(d->data_buf.dbc) == 0;
-}
-
-static ulong
-read_mismatch_recover(Controller *c, Ncr *n, Dsa *dsa)
-{
- ulong dbc;
- uchar dfifo = n->dfifo;
- int inchip;
-
- dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
- if (n->ctest5 & (1 << 5))
- inchip = ((dfifo | ((n->ctest5 & 3) << 8)) - (dbc & 0x3ff)) & 0x3ff;
- else
- inchip = ((dfifo & 0x7f) - (dbc & 0x7f)) & 0x7f;
- if (inchip) {
- IPRINT(PRINTPREFIX "%d/%d: read_mismatch_recover: DMA FIFO = %d\n",
- dsa->target, dsa->lun, inchip);
- }
- if (n->sxfer & SYNCOFFMASK(c)) {
- /* SCSI FIFO */
- uchar fifo = n->sstat1 >> 4;
- if (c->v->maxsyncoff > 8)
- fifo |= (n->sstat2 & (1 << 4));
- if (fifo) {
- inchip += fifo;
- IPRINT(PRINTPREFIX "%d/%d: read_mismatch_recover: SCSI FIFO = %d\n",
- dsa->target, dsa->lun, fifo);
- }
- }
- else {
- if (n->sstat0 & (1 << 7)) {
- inchip++;
- IPRINT(PRINTPREFIX "%d/%d: read_mismatch_recover: SIDL full\n",
- dsa->target, dsa->lun);
- }
- if (n->sstat2 & (1 << 7)) {
- inchip++;
- IPRINT(PRINTPREFIX "%d/%d: read_mismatch_recover: SIDL msb full\n",
- dsa->target, dsa->lun);
- }
- }
- USED(inchip);
- return dbc;
-}
-
-static ulong
-write_mismatch_recover(Controller *c, Ncr *n, Dsa *dsa)
-{
- ulong dbc;
- uchar dfifo = n->dfifo;
- int inchip;
-
- dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
- USED(dsa);
- if (n->ctest5 & (1 << 5))
- inchip = ((dfifo | ((n->ctest5 & 3) << 8)) - (dbc & 0x3ff)) & 0x3ff;
- else
- inchip = ((dfifo & 0x7f) - (dbc & 0x7f)) & 0x7f;
-#ifdef WMR_DEBUG
- if (inchip) {
- IPRINT(PRINTPREFIX "%d/%d: write_mismatch_recover: DMA FIFO = %d\n",
- dsa->target, dsa->lun, inchip);
- }
-#endif
- if (n->sstat0 & (1 << 5)) {
- inchip++;
-#ifdef WMR_DEBUG
- IPRINT(PRINTPREFIX "%d/%d: write_mismatch_recover: SODL full\n", dsa->target, dsa->lun);
-#endif
- }
- if (n->sstat2 & (1 << 5)) {
- inchip++;
-#ifdef WMR_DEBUG
- IPRINT(PRINTPREFIX "%d/%d: write_mismatch_recover: SODL msb full\n", dsa->target, dsa->lun);
-#endif
- }
- if (n->sxfer & SYNCOFFMASK(c)) {
- /* synchronous SODR */
- if (n->sstat0 & (1 << 6)) {
- inchip++;
-#ifdef WMR_DEBUG
- IPRINT(PRINTPREFIX "%d/%d: write_mismatch_recover: SODR full\n",
- dsa->target, dsa->lun);
-#endif
- }
- if (n->sstat2 & (1 << 6)) {
- inchip++;
-#ifdef WMR_DEBUG
- IPRINT(PRINTPREFIX "%d/%d: write_mismatch_recover: SODR msb full\n",
- dsa->target, dsa->lun);
-#endif
- }
- }
- /* clear the dma fifo */
- n->ctest3 |= (1 << 2);
- /* wait till done */
- while ((n->dstat & Dfe) == 0)
- ;
- return dbc + inchip;
-}
-
-static void
-sd53c8xxinterrupt(Ureg *ur, void *a)
-{
- uchar istat;
- ushort sist;
- uchar dstat;
- int wakeme = 0;
- int cont = -1;
- Dsa *dsa;
- Controller *c = a;
- Ncr *n = c->n;
-
- USED(ur);
- if (DEBUG(1)) {
- IPRINT(PRINTPREFIX "int\n");
- }
- ilock(c);
- istat = n->istat;
- if (istat & Intf) {
- Dsa *d;
- int wokesomething = 0;
- if (DEBUG(1)) {
- IPRINT(PRINTPREFIX "Intfly\n");
- }
- n->istat = Intf;
- /* search for structures in A_STATE_DONE */
- for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
- if (d->stateb == A_STATE_DONE) {
- d->p9status = d->status;
- if (DEBUG(1)) {
- IPRINT(PRINTPREFIX "waking up dsa %lux\n", (ulong)d);
- }
- wakeup(d);
- wokesomething = 1;
- }
- }
- if (!wokesomething) {
- IPRINT(PRINTPREFIX "nothing to wake up\n");
- }
- }
-
- if ((istat & (Sip | Dip)) == 0) {
- if (DEBUG(1)) {
- IPRINT(PRINTPREFIX "int end %x\n", istat);
- }
- iunlock(c);
- return;
- }
-
- sist = (n->sist1<<8)|n->sist0; /* BUG? can two-byte read be inconsistent? */
- dstat = n->dstat;
- dsa = (Dsa *)DMASEG_TO_KADDR(legetl(n->dsa));
- c->running = 0;
- if (istat & Sip) {
- if (DEBUG(1)) {
- IPRINT("sist = %.4x\n", sist);
- }
- if (sist & 0x80) {
- ulong addr;
- ulong sa;
- ulong dbc;
- ulong tbc;
- int dmablks;
- ulong dmaaddr;
-
- addr = legetl(n->dsp);
- sa = addr - c->scriptpa;
- if (DEBUG(1) || DEBUG(2)) {
- IPRINT(PRINTPREFIX "%d/%d: Phase Mismatch sa=%.8lux\n",
- dsa->target, dsa->lun, sa);
- }
- /*
- * now recover
- */
- if (sa == E_data_in_mismatch) {
- /*
- * though this is a failure in the residue, there may have been blocks
- * as well. if so, dmablks will not have been zeroed, since the state
- * was not saved by the microcode.
- */
- dbc = read_mismatch_recover(c, n, dsa);
- tbc = legetl(dsa->data_buf.dbc) - dbc;
- dsa->dmablks = 0;
- n->scratcha[2] = 0;
- advancedata(&dsa->data_buf, tbc);
- if (DEBUG(1) || DEBUG(2)) {
- IPRINT(PRINTPREFIX "%d/%d: transferred = %ld residue = %ld\n",
- dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc));
- }
- cont = E_data_mismatch_recover;
- }
- else if (sa == E_data_in_block_mismatch) {
- dbc = read_mismatch_recover(c, n, dsa);
- tbc = A_BSIZE - dbc;
- /* recover current state from registers */
- dmablks = n->scratcha[2];
- dmaaddr = legetl(n->scratchb);
- /* we have got to dmaaddr + tbc */
- /* we have dmablks * A_BSIZE - tbc + residue left to do */
- /* so remaining transfer is */
- IPRINT("in_block_mismatch: dmaaddr = 0x%lux tbc=%lud dmablks=%d\n",
- dmaaddr, tbc, dmablks);
- calcblockdma(dsa, dmaaddr + tbc,
- dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));
- /* copy changes into scratch registers */
- IPRINT("recalc: dmablks %d dmaaddr 0x%lx pa 0x%lx dbc %ld\n",
- dsa->dmablks, legetl(dsa->dmaaddr),
- legetl(dsa->data_buf.pa), legetl(dsa->data_buf.dbc));
- n->scratcha[2] = dsa->dmablks;
- lesetl(n->scratchb, dsa->dmancr);
- cont = E_data_block_mismatch_recover;
- }
- else if (sa == E_data_out_mismatch) {
- dbc = write_mismatch_recover(c, n, dsa);
- tbc = legetl(dsa->data_buf.dbc) - dbc;
- dsa->dmablks = 0;
- n->scratcha[2] = 0;
- advancedata(&dsa->data_buf, tbc);
- if (DEBUG(1) || DEBUG(2)) {
- IPRINT(PRINTPREFIX "%d/%d: transferred = %ld residue = %ld\n",
- dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc));
- }
- cont = E_data_mismatch_recover;
- }
- else if (sa == E_data_out_block_mismatch) {
- dbc = write_mismatch_recover(c, n, dsa);
- tbc = legetl(dsa->data_buf.dbc) - dbc;
- /* recover current state from registers */
- dmablks = n->scratcha[2];
- dmaaddr = legetl(n->scratchb);
- /* we have got to dmaaddr + tbc */
- /* we have dmablks blocks - tbc + residue left to do */
- /* so remaining transfer is */
- IPRINT("out_block_mismatch: dmaaddr = %lux tbc=%lud dmablks=%d\n",
- dmaaddr, tbc, dmablks);
- calcblockdma(dsa, dmaaddr + tbc,
- dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));
- /* copy changes into scratch registers */
- n->scratcha[2] = dsa->dmablks;
- lesetl(n->scratchb, dsa->dmancr);
- cont = E_data_block_mismatch_recover;
- }
- else if (sa == E_id_out_mismatch) {
- /*
- * target switched phases while attention held during
- * message out. The possibilities are:
- * 1. It didn't like the last message. This is indicated
- * by the new phase being message_in. Use script to recover
- *
- * 2. It's not SCSI-II compliant. The new phase will be other
- * than message_in. We should also indicate that the device
- * is asynchronous, if it's the SDTR that got ignored
- *
- * For now, if the phase switch is not to message_in, and
- * and it happens after IDENTIFY and before SDTR, we
- * notify the negotiation state machine.
- */
- ulong lim = legetl(dsa->msg_out_buf.dbc);
- uchar p = n->sstat1 & 7;
- dbc = write_mismatch_recover(c, n, dsa);
- tbc = lim - dbc;
- IPRINT(PRINTPREFIX "%d/%d: msg_out_mismatch: %lud/%lud sent, phase %s\n",
- dsa->target, dsa->lun, tbc, lim, phase[p]);
- if (p != MessageIn && tbc == 1) {
- msgsm(dsa, c, A_SIR_EV_PHASE_SWITCH_AFTER_ID, &cont, &wakeme);
- }
- else
- cont = E_id_out_mismatch_recover;
- }
- else if (sa == E_cmd_out_mismatch) {
- /*
- * probably the command count is longer than the device wants ...
- */
- ulong lim = legetl(dsa->cmd_buf.dbc);
- uchar p = n->sstat1 & 7;
- dbc = write_mismatch_recover(c, n, dsa);
- tbc = lim - dbc;
- IPRINT(PRINTPREFIX "%d/%d: cmd_out_mismatch: %lud/%lud sent, phase %s\n",
- dsa->target, dsa->lun, tbc, lim, phase[p]);
- USED(p, tbc);
- cont = E_to_decisions;
- }
- else {
- IPRINT(PRINTPREFIX "%d/%d: ma sa=%.8lux wanted=%s got=%s\n",
- dsa->target, dsa->lun, sa,
- phase[n->dcmd & 7],
- phase[n->sstat1 & 7]);
- dumpncrregs(c, 1);
- dsa->p9status = SDeio; /* chf */
- wakeme = 1;
- }
- }
- /*else*/ if (sist & 0x400) {
- if (DEBUG(0)) {
- IPRINT(PRINTPREFIX "%d/%d Sto\n", dsa->target, dsa->lun);
- }
- dsa->p9status = SDtimeout;
- dsa->stateb = A_STATE_DONE;
- softreset(c);
- cont = E_issue_check;
- wakeme = 1;
- }
- if (sist & 0x1) {
- IPRINT(PRINTPREFIX "%d/%d: parity error\n", dsa->target, dsa->lun);
- dsa->parityerror = 1;
- }
- if (sist & 0x4) {
- IPRINT(PRINTPREFIX "%d/%d: unexpected disconnect\n",
- dsa->target, dsa->lun);
- dumpncrregs(c, 1);
- //wakeme = 1;
- dsa->p9status = SDeio;
- }
- }
- if (istat & Dip) {
- if (DEBUG(1)) {
- IPRINT("dstat = %.2x\n", dstat);
- }
- /*else*/ if (dstat & Ssi) {
- ulong *p = DMASEG_TO_KADDR(legetl(n->dsp));
- ulong w = (uchar *)p - (uchar *)c->script;
- IPRINT("[%lux]", w);
- USED(w);
- cont = -2; /* restart */
- }
- if (dstat & Sir) {
- switch (legetl(n->dsps)) {
- case A_SIR_MSG_IO_COMPLETE:
- dsa->p9status = dsa->status;
- wakeme = 1;
- break;
- case A_SIR_MSG_SDTR:
- case A_SIR_MSG_WDTR:
- case A_SIR_MSG_REJECT:
- case A_SIR_EV_RESPONSE_OK:
- msgsm(dsa, c, legetl(n->dsps), &cont, &wakeme);
- break;
- case A_SIR_MSG_IGNORE_WIDE_RESIDUE:
- /* back up one in the data transfer */
- IPRINT(PRINTPREFIX "%d/%d: ignore wide residue %d, WSR = %d\n",
- dsa->target, dsa->lun, n->scratcha[1], n->scntl2 & 1);
- if (dsa->flag == 2) {
- IPRINT(PRINTPREFIX "%d/%d: transfer over; residue ignored\n",
- dsa->target, dsa->lun);
- }
- else {
- calcblockdma(dsa, legetl(dsa->dmaaddr) - 1,
- dsa->dmablks * A_BSIZE + legetl(dsa->data_buf.dbc) + 1);
- }
- cont = -2;
- break;
- case A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT:
- IPRINT(PRINTPREFIX "%d: not msg_in after reselect (%s)",
- n->ssid & SSIDMASK(c), phase[n->sstat1 & 7]);
- dsa = dsafind(c, n->ssid & SSIDMASK(c), -1, A_STATE_DISCONNECTED);
- dumpncrregs(c, 1);
- wakeme = 1;
- break;
- case A_SIR_NOTIFY_MSG_IN:
- IPRINT(PRINTPREFIX "%d/%d: msg_in %d\n",
- dsa->target, dsa->lun, n->sfbr);
- cont = -2;
- break;
- case A_SIR_NOTIFY_DISC:
- IPRINT(PRINTPREFIX "%d/%d: disconnect:", dsa->target, dsa->lun);
- goto dsadump;
- case A_SIR_NOTIFY_STATUS:
- IPRINT(PRINTPREFIX "%d/%d: status\n", dsa->target, dsa->lun);
- cont = -2;
- break;
- case A_SIR_NOTIFY_COMMAND:
- IPRINT(PRINTPREFIX "%d/%d: commands\n", dsa->target, dsa->lun);
- cont = -2;
- break;
- case A_SIR_NOTIFY_DATA_IN:
- IPRINT(PRINTPREFIX "%d/%d: data in a %lx b %lx\n",
- dsa->target, dsa->lun, legetl(n->scratcha), legetl(n->scratchb));
- cont = -2;
- break;
- case A_SIR_NOTIFY_BLOCK_DATA_IN:
- IPRINT(PRINTPREFIX "%d/%d: block data in: a2 %x b %lx\n",
- dsa->target, dsa->lun, n->scratcha[2], legetl(n->scratchb));
- cont = -2;
- break;
- case A_SIR_NOTIFY_DATA_OUT:
- IPRINT(PRINTPREFIX "%d/%d: data out\n", dsa->target, dsa->lun);
- cont = -2;
- break;
- case A_SIR_NOTIFY_DUMP:
- IPRINT(PRINTPREFIX "%d/%d: dump\n", dsa->target, dsa->lun);
- dumpncrregs(c, 1);
- cont = -2;
- break;
- case A_SIR_NOTIFY_DUMP2:
- IPRINT(PRINTPREFIX "%d/%d: dump2:", dsa->target, dsa->lun);
- IPRINT(" sa %lux", legetl(n->dsp) - c->scriptpa);
- IPRINT(" dsa %lux", legetl(n->dsa));
- IPRINT(" sfbr %ux", n->sfbr);
- IPRINT(" a %lux", legetl(n->scratcha));
- IPRINT(" b %lux", legetl(n->scratchb));
- IPRINT(" ssid %ux", n->ssid);
- IPRINT("\n");
- cont = -2;
- break;
- case A_SIR_NOTIFY_WAIT_RESELECT:
- IPRINT(PRINTPREFIX "wait reselect\n");
- cont = -2;
- break;
- case A_SIR_NOTIFY_RESELECT:
- IPRINT(PRINTPREFIX "reselect: ssid %.2x sfbr %.2x at %ld\n",
- n->ssid, n->sfbr, TK2MS(m->ticks));
- cont = -2;
- break;
- case A_SIR_NOTIFY_ISSUE:
- IPRINT(PRINTPREFIX "%d/%d: issue:", dsa->target, dsa->lun);
- dsadump:
- IPRINT(" tgt=%d", dsa->target);
- IPRINT(" time=%ld", TK2MS(m->ticks));
- IPRINT("\n");
- cont = -2;
- break;
- case A_SIR_NOTIFY_ISSUE_CHECK:
- IPRINT(PRINTPREFIX "issue check\n");
- cont = -2;
- break;
- case A_SIR_NOTIFY_SIGP:
- IPRINT(PRINTPREFIX "responded to SIGP\n");
- cont = -2;
- break;
- case A_SIR_NOTIFY_DUMP_NEXT_CODE: {
- ulong *dsp = DMASEG_TO_KADDR(legetl(n->dsp));
- int x;
- IPRINT(PRINTPREFIX "code at %lux", dsp - c->script);
- for (x = 0; x < 6; x++) {
- IPRINT(" %.8lux", dsp[x]);
- }
- IPRINT("\n");
- USED(dsp);
- cont = -2;
- break;
- }
- case A_SIR_NOTIFY_WSR:
- IPRINT(PRINTPREFIX "%d/%d: WSR set\n", dsa->target, dsa->lun);
- cont = -2;
- break;
- case A_SIR_NOTIFY_LOAD_SYNC:
- IPRINT(PRINTPREFIX "%d/%d: scntl=%.2x sxfer=%.2x\n",
- dsa->target, dsa->lun, n->scntl3, n->sxfer);
- cont = -2;
- break;
- case A_SIR_NOTIFY_RESELECTED_ON_SELECT:
- if (DEBUG(2)) {
- IPRINT(PRINTPREFIX "%d/%d: reselected during select\n",
- dsa->target, dsa->lun);
- }
- cont = -2;
- break;
- case A_error_reselected: /* dsa isn't valid here */
- print(PRINTPREFIX "reselection error\n");
- dumpncrregs(c, 1);
- for (dsa = KPTR(legetl(c->dsalist.head)); dsa; dsa = KPTR(legetl(dsa->next))) {
- IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
- }
- break;
- default:
- IPRINT(PRINTPREFIX "%d/%d: script error %ld\n",
- dsa->target, dsa->lun, legetl(n->dsps));
- dumpncrregs(c, 1);
- wakeme = 1;
- }
- }
- /*else*/ if (dstat & Iid) {
- ulong addr = legetl(n->dsp);
- ulong dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
- IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
- dsa->target, dsa->lun,
- addr, addr - c->scriptpa, dbc);
- addr = (ulong)DMASEG_TO_KADDR(addr);
- IPRINT("%.8lux %.8lux %.8lux\n",
- *(ulong *)(addr - 12), *(ulong *)(addr - 8), *(ulong *)(addr - 4));
- USED(addr, dbc);
- dsa->p9status = SDeio;
- wakeme = 1;
- }
- /*else*/ if (dstat & Bf) {
- IPRINT(PRINTPREFIX "%d/%d: Bus Fault\n", dsa->target, dsa->lun);
- dumpncrregs(c, 1);
- dsa->p9status = SDeio;
- wakeme = 1;
- }
- }
- if (cont == -2)
- ncrcontinue(c);
- else if (cont >= 0)
- start(c, cont);
- if (wakeme){
- if(dsa->p9status == SDnostatus)
- dsa->p9status = SDeio;
- wakeup(dsa);
- }
- iunlock(c);
- if (DEBUG(1)) {
- IPRINT(PRINTPREFIX "int end 1\n");
- }
-}
-
-static int
-done(void *arg)
-{
- return ((Dsa *)arg)->p9status != SDnostatus;
-}
-
-static void
-setmovedata(Movedata *d, ulong pa, ulong bc)
-{
- d->pa[0] = pa;
- d->pa[1] = pa>>8;
- d->pa[2] = pa>>16;
- d->pa[3] = pa>>24;
- d->dbc[0] = bc;
- d->dbc[1] = bc>>8;
- d->dbc[2] = bc>>16;
- d->dbc[3] = bc>>24;
-}
-
-static void
-advancedata(Movedata *d, long v)
-{
- lesetl(d->pa, legetl(d->pa) + v);
- lesetl(d->dbc, legetl(d->dbc) - v);
-}
-
-static void
-dumpwritedata(uchar *data, int datalen)
-{
- int i;
- uchar *bp;
- if (!DEBUG(0)){
- USED(data, datalen);
- return;
- }
-
- if (datalen) {
- KPRINT(PRINTPREFIX "write:");
- for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) {
- KPRINT("%.2ux", *bp);
- }
- if (i < datalen) {
- KPRINT("...");
- }
- KPRINT("\n");
- }
-}
-
-static void
-dumpreaddata(uchar *data, int datalen)
-{
- int i;
- uchar *bp;
- if (!DEBUG(0)){
- USED(data, datalen);
- return;
- }
-
- if (datalen) {
- KPRINT(PRINTPREFIX "read:");
- for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) {
- KPRINT("%.2ux", *bp);
- }
- if (i < datalen) {
- KPRINT("...");
- }
- KPRINT("\n");
- }
-}
-
-static void
-busreset(Controller *c)
-{
- int x, ntarget;
-
- /* bus reset */
- c->n->scntl1 |= (1 << 3);
- delay(500);
- c->n->scntl1 &= ~(1 << 3);
- if(!(c->v->feature & Wide))
- ntarget = 8;
- else
- ntarget = MAXTARGET;
- for (x = 0; x < ntarget; x++) {
- setwide(0, c, x, 0);
-#ifndef ASYNC_ONLY
- c->s[x] = NeitherDone;
-#endif
- }
- c->capvalid = 0;
-}
-
-static void
-reset(Controller *c)
-{
- /* should wakeup all pending tasks */
- softreset(c);
- busreset(c);
-}
-
-static int
-sd53c8xxrio(SDreq* r)
-{
- Dsa *d;
- uchar *bp;
- Controller *c;
- uchar target_expo, my_expo;
- int bc, check, i, status, target;
-
- if((target = r->unit->subno) == 0x07)
- return r->status = SDtimeout; /* assign */
- c = r->unit->dev->ctlr;
-
- check = 0;
- d = dsaalloc(c, target, r->lun);
-
- qlock(&c->q[target]); /* obtain access to target */
-docheck:
- /* load the transfer control stuff */
- d->scsi_id_buf[0] = 0;
- d->scsi_id_buf[1] = c->sxfer[target];
- d->scsi_id_buf[2] = target;
- d->scsi_id_buf[3] = c->scntl3[target];
- synctodsa(d, c);
-
- bc = 0;
-
- d->msg_out[bc] = 0x80 | r->lun;
-
-#ifndef NO_DISCONNECT
- d->msg_out[bc] |= (1 << 6);
-#endif
- bc++;
-
- /* work out what to do about negotiation */
- switch (c->s[target]) {
- default:
- KPRINT(PRINTPREFIX "%d: strange nego state %d\n", target, c->s[target]);
- c->s[target] = NeitherDone;
- /* fall through */
- case NeitherDone:
- if ((c->capvalid & (1 << target)) == 0)
- break;
- target_expo = (c->cap[target] >> 5) & 3;
- my_expo = (c->v->feature & Wide) != 0;
- if (target_expo < my_expo)
- my_expo = target_expo;
-#ifdef ALWAYS_DO_WDTR
- bc += buildwdtrmsg(d->msg_out + bc, my_expo);
- KPRINT(PRINTPREFIX "%d: WDTN: initiating expo %d\n", target, my_expo);
- c->s[target] = WideInit;
- break;
-#else
- if (my_expo) {
- bc += buildwdtrmsg(d->msg_out + bc, (c->v->feature & Wide) ? 1 : 0);
- KPRINT(PRINTPREFIX "%d: WDTN: initiating expo %d\n", target, my_expo);
- c->s[target] = WideInit;
- break;
- }
- KPRINT(PRINTPREFIX "%d: WDTN: narrow\n", target);
- /* fall through */
-#endif
- case WideDone:
- if (c->cap[target] & (1 << 4)) {
- KPRINT(PRINTPREFIX "%d: SDTN: initiating %d %d\n", target, c->tpf, c->v->maxsyncoff);
- bc += buildsdtrmsg(d->msg_out + bc, c->tpf, c->v->maxsyncoff);
- c->s[target] = SyncInit;
- break;
- }
- KPRINT(PRINTPREFIX "%d: SDTN: async only\n", target);
- c->s[target] = BothDone;
- break;
-
- case BothDone:
- break;
- }
-
- setmovedata(&d->msg_out_buf, DMASEG(d->msg_out), bc);
- setmovedata(&d->cmd_buf, DMASEG(r->cmd), r->clen);
- calcblockdma(d, DMASEG(r->data), r->dlen);
-
- if (DEBUG(0)) {
- KPRINT(PRINTPREFIX "%d/%d: exec: ", target, r->lun);
- for (bp = r->cmd; bp < &r->cmd[r->clen]; bp++) {
- KPRINT("%.2ux", *bp);
- }
- KPRINT("\n");
- if (!r->write) {
- KPRINT(PRINTPREFIX "%d/%d: exec: limit=(%d)%ld\n",
- target, r->lun, d->dmablks, legetl(d->data_buf.dbc));
- }
- else
- dumpwritedata(r->data, r->dlen);
- }
-
- setmovedata(&d->status_buf, DMASEG(&d->status), 1);
-
- d->p9status = SDnostatus;
- d->parityerror = 0;
-
- d->stateb = A_STATE_ISSUE; /* start operation */
-
- ilock(c);
- if (c->ssm)
- c->n->dcntl |= 0x10; /* SSI */
- if (c->running) {
- c->n->istat |= Sigp;
- }
- else {
- start(c, E_issue_check);
- }
- iunlock(c);
-
- while(waserror())
- ;
- tsleep(d, done, d, 600 * 1000);
- poperror();
-
- if (!done(d)) {
- KPRINT(PRINTPREFIX "%d/%d: exec: Timed out\n", target, r->lun);
- dumpncrregs(c, 0);
- dsafree(c, d);
- reset(c);
- qunlock(&c->q[target]);
- r->status = SDtimeout;
- return r->status = SDtimeout; /* assign */
- }
-
- if((status = d->p9status) == SDeio)
- c->s[target] = NeitherDone;
- if (d->parityerror) {
- status = SDeio;
- }
-
- /*
- * adjust datalen
- */
- r->rlen = r->dlen;
- if (DEBUG(0)) {
- KPRINT(PRINTPREFIX "%d/%d: exec: before rlen adjust: dmablks %d flag %d dbc %lud\n",
- target, r->lun, d->dmablks, d->flag, legetl(d->data_buf.dbc));
- }
- r->rlen = r->dlen;
- if (d->flag != 2) {
- r->rlen -= d->dmablks * A_BSIZE;
- r->rlen -= legetl(d->data_buf.dbc);
- }
- if(!r->write)
- dumpreaddata(r->data, r->rlen);
- if (DEBUG(0)) {
- KPRINT(PRINTPREFIX "%d/%d: exec: p9status=%d status %d rlen %ld\n",
- target, r->lun, d->p9status, status, r->rlen);
- }
- /*
- * spot the identify
- */
- if ((c->capvalid & (1 << target)) == 0
- && (status == SDok || status == SDcheck)
- && r->cmd[0] == 0x12 && r->dlen >= 8) {
- c->capvalid |= 1 << target;
- bp = r->data;
- c->cap[target] = bp[7];
- KPRINT(PRINTPREFIX "%d: capabilities %.2x\n", target, bp[7]);
- }
- if(!check && status == SDcheck && !(r->flags & SDnosense)){
- check = 1;
- r->write = 0;
- memset(r->cmd, 0, sizeof(r->cmd));
- r->cmd[0] = 0x03;
- r->cmd[1] = r->lun<<5;
- r->cmd[4] = sizeof(r->sense)-1;
- r->clen = 6;
- r->data = r->sense;
- r->dlen = sizeof(r->sense)-1;
- /*
- * Clear out the microcode state
- * so the Dsa can be re-used.
- */
- lesetl(&d->stateb, A_STATE_ALLOCATED);
- goto docheck;
- }
- qunlock(&c->q[target]);
- dsafree(c, d);
-
- if(status == SDok && check){
- status = SDcheck;
- r->flags |= SDvalidsense;
- }
- if(DEBUG(0))
- KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n",
- target, r->flags, status, r->rlen);
- if(r->flags & SDvalidsense){
- if(!DEBUG(0))
- KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n",
- target, r->flags, status, r->rlen);
- for(i = 0; i < r->rlen; i++)
- KPRINT(" %2.2uX", r->sense[i]);
- KPRINT("\n");
- }
- return r->status = status;
-}
-
-static void
-cribbios(Controller *c)
-{
- c->bios.scntl3 = c->n->scntl3;
- c->bios.stest2 = c->n->stest2;
- KPRINT(PRINTPREFIX "bios scntl3(%.2x) stest2(%.2x)\n", c->bios.scntl3, c->bios.stest2);
-}
-
-static int
-bios_set_differential(Controller *c)
-{
- /* Concept lifted from FreeBSD - thanks Gerard */
- /* basically, if clock conversion factors are set, then there is
- * evidence the bios had a go at the chip, and if so, it would
- * have set the differential enable bit in stest2
- */
- return (c->bios.scntl3 & 7) != 0 && (c->bios.stest2 & 0x20) != 0;
-}
-
-#define NCR_VID 0x1000
-#define NCR_810_DID 0x0001
-#define NCR_820_DID 0x0002 /* don't know enough about this one to support it */
-#define NCR_825_DID 0x0003
-#define NCR_815_DID 0x0004
-#define SYM_810AP_DID 0x0005
-#define SYM_860_DID 0x0006
-#define SYM_896_DID 0x000b
-#define SYM_895_DID 0x000c
-#define SYM_885_DID 0x000d /* ditto */
-#define SYM_875_DID 0x000f /* ditto */
-#define SYM_1010_DID 0x0020
-#define SYM_1011_DID 0x0021
-#define SYM_875J_DID 0x008f
-
-static Variant variant[] = {
-{ NCR_810_DID, 0x0f, "NCR53C810", Burst16, 8, 24, 0 },
-{ NCR_810_DID, 0x1f, "SYM53C810ALV", Burst16, 8, 24, Prefetch },
-{ NCR_810_DID, 0xff, "SYM53C810A", Burst16, 8, 24, Prefetch },
-{ SYM_810AP_DID, 0xff, "SYM53C810AP", Burst16, 8, 24, Prefetch },
-{ NCR_815_DID, 0xff, "NCR53C815", Burst16, 8, 24, BurstOpCodeFetch },
-{ NCR_825_DID, 0x0f, "NCR53C825", Burst16, 8, 24, Wide|BurstOpCodeFetch|Differential },
-{ NCR_825_DID, 0xff, "SYM53C825A", Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Differential|Wide },
-{ SYM_860_DID, 0x0f, "SYM53C860", Burst16, 8, 24, Prefetch|Ultra },
-{ SYM_860_DID, 0xff, "SYM53C860LV", Burst16, 8, 24, Prefetch|Ultra },
-{ SYM_875_DID, 0x01, "SYM53C875r1", Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Differential|Wide|Ultra },
-{ SYM_875_DID, 0xff, "SYM53C875", Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Differential|Wide|Ultra|ClockDouble },
-{ SYM_875J_DID, 0xff, "SYM53C875j", Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Differential|Wide|Ultra|ClockDouble },
-{ SYM_885_DID, 0xff, "SYM53C885", Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Wide|Ultra|ClockDouble },
-{ SYM_895_DID, 0xff, "SYM53C895", Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
-{ SYM_896_DID, 0xff, "SYM53C896", Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
-{ SYM_1010_DID, 0xff, "SYM53C1010", Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
-{ SYM_1011_DID, 0xff, "SYM53C1010", Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
-};
-
-static int
-xfunc(Controller *c, enum na_external x, unsigned long *v)
-{
- switch (x)
- {
- case X_scsi_id_buf:
- *v = offsetof(Dsa, scsi_id_buf[0]); return 1;
- case X_msg_out_buf:
- *v = offsetof(Dsa, msg_out_buf); return 1;
- case X_cmd_buf:
- *v = offsetof(Dsa, cmd_buf); return 1;
- case X_data_buf:
- *v = offsetof(Dsa, data_buf); return 1;
- case X_status_buf:
- *v = offsetof(Dsa, status_buf); return 1;
- case X_dsa_head:
- *v = DMASEG(&c->dsalist.head[0]); return 1;
- case X_ssid_mask:
- *v = SSIDMASK(c); return 1;
- default:
- print("xfunc: can't find external %d\n", x);
- return 0;
- }
-}
-
-static int
-na_fixup(Controller *c, ulong pa_reg,
- struct na_patch *patch, int patches,
- int (*externval)(Controller*, int, ulong*))
-{
- int p;
- int v;
- ulong *script, pa_script;
- unsigned long lw, lv;
-
- script = c->script;
- pa_script = c->scriptpa;
- for (p = 0; p < patches; p++) {
- switch (patch[p].type) {
- case 1:
- /* script relative */
- script[patch[p].lwoff] += pa_script;
- break;
- case 2:
- /* register i/o relative */
- script[patch[p].lwoff] += pa_reg;
- break;
- case 3:
- /* data external */
- lw = script[patch[p].lwoff];
- v = (lw >> 8) & 0xff;
- if (!(*externval)(c, v, &lv))
- return 0;
- v = lv & 0xff;
- script[patch[p].lwoff] = (lw & 0xffff00ffL) | (v << 8);
- break;
- case 4:
- /* 32 bit external */
- lw = script[patch[p].lwoff];
- if (!(*externval)(c, lw, &lv))
- return 0;
- script[patch[p].lwoff] = lv;
- break;
- case 5:
- /* 24 bit external */
- lw = script[patch[p].lwoff];
- if (!(*externval)(c, lw & 0xffffff, &lv))
- return 0;
- script[patch[p].lwoff] = (lw & 0xff000000L) | (lv & 0xffffffL);
- break;
- }
- }
- return 1;
-}
-
-static SDev*
-sd53c8xxpnp(void)
-{
- char *cp;
- Pcidev *p;
- Variant *v;
- int ba, nctlr;
- void *scriptma;
- Controller *ctlr;
- SDev *sdev, *head, *tail;
- ulong regpa, *script, scriptpa;
-
- if(cp = getconf("*maxsd53c8xx"))
- nctlr = strtoul(cp, 0, 0);
- else
- nctlr = 32;
-
- p = nil;
- head = tail = nil;
- while((p = pcimatch(p, NCR_VID, 0)) != nil && nctlr > 0){
- for(v = variant; v < &variant[nelem(variant)]; v++){
- if(p->did == v->did && p->rid <= v->maxrid)
- break;
- }
- if(v >= &variant[nelem(variant)]) {
- print("no match\n");
- continue;
- }
- print(PRINTPREFIX "%s rev. 0x%2.2x intr=%d command=%4.4uX\n",
- v->name, p->rid, p->intl, p->pcr);
-
- regpa = p->mem[1].bar;
- ba = 2;
- if(regpa & 0x04){
- if(p->mem[2].bar)
- continue;
- ba++;
- }
- regpa = upamalloc(regpa & ~0x0F, p->mem[1].size, 0);
- if(regpa == 0)
- continue;
-
- script = nil;
- scriptpa = 0;
- scriptma = nil;
- if((v->feature & LocalRAM) && sizeof(na_script) <= 4096){
- scriptpa = p->mem[ba].bar;
- if((scriptpa & 0x04) && p->mem[ba+1].bar){
- upafree(regpa, p->mem[1].size);
- continue;
- }
- scriptpa = upamalloc(scriptpa & ~0x0F,
- p->mem[ba].size, 0);
- if(scriptpa)
- script = KADDR(scriptpa);
- }
- if(scriptpa == 0){
- /*
- * Either the map failed, or this chip does not have
- * local RAM. It will need a copy of the microcode.
- */
- scriptma = malloc(sizeof(na_script));
- if(scriptma == nil){
- upafree(regpa, p->mem[1].size);
- continue;
- }
- scriptpa = DMASEG(scriptma);
- script = scriptma;
- }
-
- ctlr = malloc(sizeof(Controller));
- sdev = malloc(sizeof(SDev));
- if(ctlr == nil || sdev == nil){
-buggery:
- if(ctlr)
- free(ctlr);
- if(sdev)
- free(sdev);
- if(scriptma)
- free(scriptma);
- else
- upafree(scriptpa, p->mem[ba].size);
- upafree(regpa, p->mem[1].size);
- continue;
- }
-
- ctlr->n = KADDR(regpa);
- ctlr->v = v;
- ctlr->script = script;
- memmove(ctlr->script, na_script, sizeof(na_script));
-
- /*
- * Because we don't yet have an abstraction for the
- * addresses as seen from the controller side (and on
- * the 386 it doesn't matter), the follwong two lines
- * are different between the 386 and alpha copies of
- * this driver.
- */
- ctlr->scriptpa = scriptpa;
- if(!na_fixup(ctlr, regpa, na_patches, NA_PATCHES, xfunc)){
- print("script fixup failed\n");
- goto buggery;
- }
- swabl(ctlr->script, ctlr->script, sizeof(na_script));
-
- ctlr->dsalist.freechain = 0;
- lesetl(ctlr->dsalist.head, 0);
-
- ctlr->pcidev = p;
-
- sdev->ifc = &sd53c8xxifc;
- sdev->ctlr = ctlr;
- if(!(v->feature & Wide))
- sdev->nunit = 8;
- else
- sdev->nunit = MAXTARGET;
- ctlr->sdev = sdev;
-
- if(head != nil)
- tail->next = sdev;
- else
- head = sdev;
- tail = sdev;
-
- nctlr--;
- }
-
- return head;
-}
-
-static SDev*
-sd53c8xxid(SDev* sdev)
-{
- return scsiid(sdev, &sd53c8xxifc);
-}
-
-static int
-sd53c8xxenable(SDev* sdev)
-{
- Pcidev *pcidev;
- Controller *ctlr;
- char name[32];
-
- ctlr = sdev->ctlr;
- pcidev = ctlr->pcidev;
-
- pcisetbme(pcidev);
- snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
- intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
-
- ilock(ctlr);
- synctabinit(ctlr);
- cribbios(ctlr);
- reset(ctlr);
- iunlock(ctlr);
-
- return 1;
-}
-
-SDifc sd53c8xxifc = {
- "53c8xx", /* name */
-
- sd53c8xxpnp, /* pnp */
- nil, /* legacy */
- sd53c8xxid, /* id */
- sd53c8xxenable, /* enable */
- nil, /* disable */
-
- scsiverify, /* verify */
- scsionline, /* online */
- sd53c8xxrio, /* rio */
- nil, /* rctl */
- nil, /* wctl */
-
- scsibio, /* bio */
- nil, /* probe */
- nil, /* clear */
- nil, /* stat */
-};
diff --git a/os/pc/sd53c8xx.i b/os/pc/sd53c8xx.i
deleted file mode 100644
index 6ef50e02..00000000
--- a/os/pc/sd53c8xx.i
+++ /dev/null
@@ -1,773 +0,0 @@
-unsigned long na_script[] = {
- /* extern scsi_id_buf */
- /* extern msg_out_buf */
- /* extern cmd_buf */
- /* extern data_buf */
- /* extern status_buf */
- /* extern msgin_buf */
- /* extern dsa_0 */
- /* extern dsa_1 */
- /* extern dsa_head */
- /* extern ssid_mask */
- /* SIR_MSG_IO_COMPLETE = 0 */
- /* error_not_cmd_complete = 1 */
- /* error_disconnected = 2 */
- /* error_reselected = 3 */
- /* error_unexpected_phase = 4 */
- /* error_weird_message = 5 */
- /* SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT = 6 */
- /* error_not_identify_after_reselect = 7 */
- /* error_too_much_data = 8 */
- /* error_too_little_data = 9 */
- /* SIR_MSG_REJECT = 10 */
- /* SIR_MSG_SDTR = 11 */
- /* SIR_EV_RESPONSE_OK = 12 */
- /* error_sigp_set = 13 */
- /* SIR_EV_PHASE_SWITCH_AFTER_ID = 14 */
- /* SIR_MSG_WDTR = 15 */
- /* SIR_MSG_IGNORE_WIDE_RESIDUE = 16 */
- /* SIR_NOTIFY_DISC = 100 */
- /* SIR_NOTIFY_RESELECT = 101 */
- /* SIR_NOTIFY_MSG_IN = 102 */
- /* SIR_NOTIFY_STATUS = 103 */
- /* SIR_NOTIFY_DUMP = 104 */
- /* SIR_NOTIFY_DUMP2 = 105 */
- /* SIR_NOTIFY_SIGP = 106 */
- /* SIR_NOTIFY_ISSUE = 107 */
- /* SIR_NOTIFY_WAIT_RESELECT = 108 */
- /* SIR_NOTIFY_ISSUE_CHECK = 109 */
- /* SIR_NOTIFY_DUMP_NEXT_CODE = 110 */
- /* SIR_NOTIFY_COMMAND = 111 */
- /* SIR_NOTIFY_DATA_IN = 112 */
- /* SIR_NOTIFY_DATA_OUT = 113 */
- /* SIR_NOTIFY_BLOCK_DATA_IN = 114 */
- /* SIR_NOTIFY_WSR = 115 */
- /* SIR_NOTIFY_LOAD_SYNC = 116 */
- /* SIR_NOTIFY_RESELECTED_ON_SELECT = 117 */
- /* STATE_FREE = 0 */
- /* STATE_ALLOCATED = 1 */
- /* STATE_ISSUE = 2 */
- /* STATE_DISCONNECTED = 3 */
- /* STATE_DONE = 4 */
- /* RESULT_OK = 0 */
- /* MSG_IDENTIFY = 0x80 */
- /* MSG_DISCONNECT = 0x04 */
- /* MSG_SAVE_DATA_POINTER = 0x02 */
- /* MSG_RESTORE_POINTERS = 0x03 */
- /* MSG_IGNORE_WIDE_RESIDUE = 0x23 */
- /* X_MSG = 0x01 */
- /* X_MSG_SDTR = 0x01 */
- /* X_MSG_WDTR = 0x03 */
- /* MSG_REJECT = 0x07 */
- /* BSIZE = 512 */
-/* 0000 */ 0x80880000L, /* jump wait_for_reselection */
-/* 0004 */ 0x00000514L,
-/* 0008 */ 0x88880000L, /* call load_sync */
-/* 000c */ 0x0000074cL,
-/* 0010 */ 0x60000200L, /* clear target */
-/* 0014 */ 0x00000000L,
-/* 0018 */ 0x47000000L, /* select atn from scsi_id_buf, reselected_on_select */
-/* 001c */ 0x000004ecL,
-/* 0020 */ 0x878b0000L, /* jump start1, when msg_in */
-/* 0024 */ 0x00000000L,
-/* 0028 */ 0x1e000000L, /* move from msg_out_buf, when msg_out */
-/* 002c */ 0x00000001L,
-/* 0030 */ 0x868b0000L, /* jump start1, when msg_out */
-/* 0034 */ 0x00fffff0L,
-/* 0038 */ 0x82830000L, /* jump to_decisions, when not cmd */
-/* 003c */ 0x000005f0L,
-/* 0040 */ 0x60000008L, /* clear atn */
-/* 0044 */ 0x00000000L,
-/* 0048 */ 0x1a000000L, /* move from cmd_buf, when cmd */
-/* 004c */ 0x00000002L,
-/* 0050 */ 0x81830000L, /* jump to_decisions, when not data_in */
-/* 0054 */ 0x000005d8L,
-/* 0058 */ 0xc0000004L, /* move memory 4, state, scratcha */
-/* 005c */ 0x00000678L,
-/* 0060 */ 0x00000034L,
-/* 0064 */ 0xc0000004L, /* move memory 4, dmaaddr, scratchb */
-/* 0068 */ 0x0000067cL,
-/* 006c */ 0x0000005cL,
-/* 0070 */ 0x72360000L, /* move scratcha2 to sfbr */
-/* 0074 */ 0x00000000L,
-/* 0078 */ 0x808c0000L, /* jump data_in_normal, if 0 */
-/* 007c */ 0x00000078L,
-/* 0080 */ 0x29000200L, /* move BSIZE, ptr dmaaddr, when data_in */
-/* 0084 */ 0x0000067cL,
-/* 0088 */ 0x7e5d0200L, /* move scratchb1 + BSIZE / 256 to scratchb1 */
-/* 008c */ 0x00000000L,
-/* 0090 */ 0x7f5e0000L, /* move scratchb2 + 0 to scratchb2 with carry */
-/* 0094 */ 0x00000000L,
-/* 0098 */ 0x7f5f0000L, /* move scratchb3 + 0 to scratchb3 with carry */
-/* 009c */ 0x00000000L,
-/* 00a0 */ 0x7e36ff00L, /* move scratcha2 + 255 to scratcha2 */
-/* 00a4 */ 0x00000000L,
-/* 00a8 */ 0xc0000004L, /* move memory 4, scratchb, dmaaddr */
-/* 00ac */ 0x0000005cL,
-/* 00b0 */ 0x0000067cL,
-/* 00b4 */ 0x818b0000L, /* jump data_in_block_loop, when data_in */
-/* 00b8 */ 0x00ffffb4L,
-/* 00bc */ 0xc0000004L, /* move memory 4, scratcha, state */
-/* 00c0 */ 0x00000034L,
-/* 00c4 */ 0x00000678L,
-/* 00c8 */ 0x88880000L, /* call save_state */
-/* 00cc */ 0x000005e0L,
-/* 00d0 */ 0x80880000L, /* jump to_decisions */
-/* 00d4 */ 0x00000558L,
-/* 00d8 */ 0xc0000004L, /* move memory 4, scratchb, dmaaddr */
-/* 00dc */ 0x0000005cL,
-/* 00e0 */ 0x0000067cL,
-/* 00e4 */ 0xc0000004L, /* move memory 4, scratcha, state */
-/* 00e8 */ 0x00000034L,
-/* 00ec */ 0x00000678L,
-/* 00f0 */ 0x80880000L, /* jump to_decisions */
-/* 00f4 */ 0x00000538L,
-/* 00f8 */ 0x72370000L, /* move scratcha3 to sfbr */
-/* 00fc */ 0x00000000L,
-/* 0100 */ 0x98040000L, /* int error_too_much_data, if not 0 */
-/* 0104 */ 0x00000008L,
-/* 0108 */ 0x19000000L, /* move from data_buf, when data_in */
-/* 010c */ 0x00000003L,
-/* 0110 */ 0x78370200L, /* move 2 to scratcha3 */
-/* 0114 */ 0x00000000L,
-/* 0118 */ 0xc0000004L, /* move memory 4, scratcha, state */
-/* 011c */ 0x00000034L,
-/* 0120 */ 0x00000678L,
-/* 0124 */ 0x88880000L, /* call save_state */
-/* 0128 */ 0x00000584L,
-/* 012c */ 0x80880000L, /* jump post_data_to_decisions */
-/* 0130 */ 0x0000052cL,
-/* 0134 */ 0xc0000004L, /* move memory 4, state, scratcha */
-/* 0138 */ 0x00000678L,
-/* 013c */ 0x00000034L,
-/* 0140 */ 0xc0000004L, /* move memory 4, dmaaddr, scratchb */
-/* 0144 */ 0x0000067cL,
-/* 0148 */ 0x0000005cL,
-/* 014c */ 0x72360000L, /* move scratcha2 to sfbr */
-/* 0150 */ 0x00000000L,
-/* 0154 */ 0x808c0000L, /* jump data_out_normal, if 0 */
-/* 0158 */ 0x0000005cL,
-/* 015c */ 0xc0000004L, /* move memory 4, dmaaddr, scratchb */
-/* 0160 */ 0x0000067cL,
-/* 0164 */ 0x0000005cL,
-/* 0168 */ 0x28000200L, /* move BSIZE, ptr dmaaddr, when data_out */
-/* 016c */ 0x0000067cL,
-/* 0170 */ 0x7e5d0200L, /* move scratchb1 + BSIZE / 256 to scratchb1 */
-/* 0174 */ 0x00000000L,
-/* 0178 */ 0x7f5e0000L, /* move scratchb2 + 0 to scratchb2 with carry */
-/* 017c */ 0x00000000L,
-/* 0180 */ 0x7f5f0000L, /* move scratchb3 + 0 to scratchb3 with carry */
-/* 0184 */ 0x00000000L,
-/* 0188 */ 0x7e36ff00L, /* move scratcha2 + 255 to scratcha2 */
-/* 018c */ 0x00000000L,
-/* 0190 */ 0xc0000004L, /* move memory 4, scratchb, dmaaddr */
-/* 0194 */ 0x0000005cL,
-/* 0198 */ 0x0000067cL,
-/* 019c */ 0x808b0000L, /* jump data_out_block_loop, when data_out */
-/* 01a0 */ 0x00ffffa8L,
-/* 01a4 */ 0xc0000004L, /* move memory 4, scratcha, state */
-/* 01a8 */ 0x00000034L,
-/* 01ac */ 0x00000678L,
-/* 01b0 */ 0x80880000L, /* jump to_decisions */
-/* 01b4 */ 0x00000478L,
-/* 01b8 */ 0x72370000L, /* move scratcha3 to sfbr */
-/* 01bc */ 0x00000000L,
-/* 01c0 */ 0x98040000L, /* int error_too_little_data, if not 0 */
-/* 01c4 */ 0x00000009L,
-/* 01c8 */ 0x18000000L, /* move from data_buf, when data_out */
-/* 01cc */ 0x00000003L,
-/* 01d0 */ 0x78370200L, /* move 2 to scratcha3 */
-/* 01d4 */ 0x00000000L,
-/* 01d8 */ 0xc0000004L, /* move memory 4, scratcha, state */
-/* 01dc */ 0x00000034L,
-/* 01e0 */ 0x00000678L,
-/* 01e4 */ 0x88880000L, /* call save_state */
-/* 01e8 */ 0x000004c4L,
-/* 01ec */ 0x80880000L, /* jump post_data_to_decisions */
-/* 01f0 */ 0x0000046cL,
-/* 01f4 */ 0x1b000000L, /* move from status_buf, when status */
-/* 01f8 */ 0x00000004L,
-/* 01fc */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 0200 */ 0x00000004L,
-/* 0204 */ 0x0f000001L, /* move 1, scratcha, when msg_in */
-/* 0208 */ 0x00000034L,
-/* 020c */ 0x808c0007L, /* jump rejected, if MSG_REJECT */
-/* 0210 */ 0x00000088L,
-/* 0214 */ 0x808c0004L, /* jump disconnected, if MSG_DISCONNECT */
-/* 0218 */ 0x00000298L,
-/* 021c */ 0x808c0002L, /* jump msg_in_skip, if MSG_SAVE_DATA_POINTER */
-/* 0220 */ 0x00000090L,
-/* 0224 */ 0x808c0003L, /* jump msg_in_skip, if MSG_RESTORE_POINTERS */
-/* 0228 */ 0x00000088L,
-/* 022c */ 0x808c0023L, /* jump ignore_wide, if MSG_IGNORE_WIDE_RESIDUE */
-/* 0230 */ 0x000001f0L,
-/* 0234 */ 0x808c0001L, /* jump extended, if X_MSG */
-/* 0238 */ 0x00000088L,
-/* 023c */ 0x98040000L, /* int error_not_cmd_complete, if not 0 */
-/* 0240 */ 0x00000001L,
-/* 0244 */ 0x7c027e00L, /* move scntl2&0x7e to scntl2 */
-/* 0248 */ 0x00000000L,
-/* 024c */ 0x60000040L, /* clear ack */
-/* 0250 */ 0x00000000L,
-/* 0254 */ 0x48000000L, /* wait disconnect */
-/* 0258 */ 0x00000000L,
-/* 025c */ 0xc0000004L, /* move memory 4, state, scratcha */
-/* 0260 */ 0x00000678L,
-/* 0264 */ 0x00000034L,
-/* 0268 */ 0x78340400L, /* move STATE_DONE to scratcha0 */
-/* 026c */ 0x00000000L,
-/* 0270 */ 0x78350000L, /* move RESULT_OK to scratcha1 */
-/* 0274 */ 0x00000000L,
-/* 0278 */ 0xc0000004L, /* move memory 4, scratcha, state */
-/* 027c */ 0x00000034L,
-/* 0280 */ 0x00000678L,
-/* 0284 */ 0x88880000L, /* call save_state */
-/* 0288 */ 0x00000424L,
-/* 028c */ 0x98180000L, /* intfly 0 */
-/* 0290 */ 0x00000000L,
-/* 0294 */ 0x80880000L, /* jump issue_check */
-/* 0298 */ 0x0000043cL,
-/* 029c */ 0x98080000L, /* int SIR_MSG_REJECT */
-/* 02a0 */ 0x0000000aL,
-/* 02a4 */ 0x60000040L, /* clear ack */
-/* 02a8 */ 0x00000000L,
-/* 02ac */ 0x80880000L, /* jump to_decisions */
-/* 02b0 */ 0x0000037cL,
-/* 02b4 */ 0x60000040L, /* clear ack */
-/* 02b8 */ 0x00000000L,
-/* 02bc */ 0x80880000L, /* jump to_decisions */
-/* 02c0 */ 0x0000036cL,
-/* 02c4 */ 0x60000040L, /* clear ack */
-/* 02c8 */ 0x00000000L,
-/* 02cc */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 02d0 */ 0x00000004L,
-/* 02d4 */ 0x0f000001L, /* move 1, scratcha1, when msg_in */
-/* 02d8 */ 0x00000035L,
-/* 02dc */ 0x808c0003L, /* jump ext_3, if 3 */
-/* 02e0 */ 0x00000030L,
-/* 02e4 */ 0x808c0002L, /* jump ext_2, if 2 */
-/* 02e8 */ 0x00000098L,
-/* 02ec */ 0x98040001L, /* int error_weird_message, if not 1 */
-/* 02f0 */ 0x00000005L,
-/* 02f4 */ 0x60000040L, /* clear ack */
-/* 02f8 */ 0x00000000L,
-/* 02fc */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 0300 */ 0x00000004L,
-/* 0304 */ 0x0f000001L, /* move 1, scratcha1, when msg_in */
-/* 0308 */ 0x00000035L,
-/* 030c */ 0x80880000L, /* jump ext_done */
-/* 0310 */ 0x000000c8L,
-/* 0314 */ 0x60000040L, /* ext_3: clear ack */
-/* 0318 */ 0x00000000L,
-/* 031c */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 0320 */ 0x00000004L,
-/* 0324 */ 0x0f000001L, /* move 1, scratcha1, when msg_in */
-/* 0328 */ 0x00000035L,
-/* 032c */ 0x60000040L, /* clear ack */
-/* 0330 */ 0x00000000L,
-/* 0334 */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 0338 */ 0x00000004L,
-/* 033c */ 0x0f000001L, /* move 1, scratcha2, when msg_in */
-/* 0340 */ 0x00000036L,
-/* 0344 */ 0x60000040L, /* clear ack */
-/* 0348 */ 0x00000000L,
-/* 034c */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 0350 */ 0x00000004L,
-/* 0354 */ 0x0f000001L, /* move 1, scratcha3, when msg_in */
-/* 0358 */ 0x00000037L,
-/* 035c */ 0x72350000L, /* move scratcha1 to sfbr */
-/* 0360 */ 0x00000000L,
-/* 0364 */ 0x80840001L, /* jump ext_done, if not X_MSG_SDTR */
-/* 0368 */ 0x00000070L,
-/* 036c */ 0x98080000L, /* sdtr: int SIR_MSG_SDTR */
-/* 0370 */ 0x0000000bL,
-/* 0374 */ 0x60000040L, /* clear ack */
-/* 0378 */ 0x00000000L,
-/* 037c */ 0x80880000L, /* jump to_decisions */
-/* 0380 */ 0x000002acL,
-/* 0384 */ 0x60000040L, /* ext_2: clear ack */
-/* 0388 */ 0x00000000L,
-/* 038c */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 0390 */ 0x00000004L,
-/* 0394 */ 0x0f000001L, /* move 1, scratcha1, when msg_in */
-/* 0398 */ 0x00000035L,
-/* 039c */ 0x60000040L, /* clear ack */
-/* 03a0 */ 0x00000000L,
-/* 03a4 */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 03a8 */ 0x00000004L,
-/* 03ac */ 0x0f000001L, /* move 1, scratcha2, when msg_in */
-/* 03b0 */ 0x00000036L,
-/* 03b4 */ 0x72350000L, /* move scratcha1 to sfbr */
-/* 03b8 */ 0x00000000L,
-/* 03bc */ 0x80840003L, /* jump ext_done, if not X_MSG_WDTR */
-/* 03c0 */ 0x00000018L,
-/* 03c4 */ 0x98080000L, /* wdtr: int SIR_MSG_WDTR */
-/* 03c8 */ 0x0000000fL,
-/* 03cc */ 0x60000040L, /* clear ack */
-/* 03d0 */ 0x00000000L,
-/* 03d4 */ 0x80880000L, /* jump to_decisions */
-/* 03d8 */ 0x00000254L,
-/* 03dc */ 0x58000008L, /* set atn */
-/* 03e0 */ 0x00000000L,
-/* 03e4 */ 0x60000040L, /* clear ack */
-/* 03e8 */ 0x00000000L,
-/* 03ec */ 0x78340700L, /* move MSG_REJECT to scratcha */
-/* 03f0 */ 0x00000000L,
-/* 03f4 */ 0x9e030000L, /* int error_unexpected_phase, when not msg_out */
-/* 03f8 */ 0x00000004L,
-/* 03fc */ 0x60000008L, /* clear atn */
-/* 0400 */ 0x00000000L,
-/* 0404 */ 0x0e000001L, /* move 1, scratcha, when msg_out */
-/* 0408 */ 0x00000034L,
-/* 040c */ 0x60000040L, /* clear ack */
-/* 0410 */ 0x00000000L,
-/* 0414 */ 0x868b0000L, /* jump reject, when msg_out */
-/* 0418 */ 0x00ffffc0L,
-/* 041c */ 0x80880000L, /* jump to_decisions */
-/* 0420 */ 0x0000020cL,
-/* 0424 */ 0x60000040L, /* clear ack */
-/* 0428 */ 0x00000000L,
-/* 042c */ 0x9f030000L, /* int error_unexpected_phase, when not msg_in */
-/* 0430 */ 0x00000004L,
-/* 0434 */ 0x0f000001L, /* move 1, scratcha1, when msg_in */
-/* 0438 */ 0x00000035L,
-/* 043c */ 0x98080000L, /* int SIR_MSG_IGNORE_WIDE_RESIDUE */
-/* 0440 */ 0x00000010L,
-/* 0444 */ 0x60000040L, /* clear ack */
-/* 0448 */ 0x00000000L,
-/* 044c */ 0x80880000L, /* jump to_decisions */
-/* 0450 */ 0x000001dcL,
-/* 0454 */ 0x58000008L, /* set atn */
-/* 0458 */ 0x00000000L,
-/* 045c */ 0x60000040L, /* clear ack */
-/* 0460 */ 0x00000000L,
-/* 0464 */ 0x9e030000L, /* int error_unexpected_phase, when not msg_out */
-/* 0468 */ 0x00000004L,
-/* 046c */ 0x1e000000L, /* move from msg_out_buf, when msg_out */
-/* 0470 */ 0x00000001L,
-/* 0474 */ 0x868b0000L, /* jump response_repeat, when msg_out */
-/* 0478 */ 0x00fffff0L,
-/* 047c */ 0x878b0000L, /* jump response_msg_in, when msg_in */
-/* 0480 */ 0x00000010L,
-/* 0484 */ 0x98080000L, /* int SIR_EV_RESPONSE_OK */
-/* 0488 */ 0x0000000cL,
-/* 048c */ 0x80880000L, /* jump to_decisions */
-/* 0490 */ 0x0000019cL,
-/* 0494 */ 0x0f000001L, /* move 1, scratcha, when msg_in */
-/* 0498 */ 0x00000034L,
-/* 049c */ 0x808c0007L, /* jump rejected, if MSG_REJECT */
-/* 04a0 */ 0x00fffdf8L,
-/* 04a4 */ 0x98080000L, /* int SIR_EV_RESPONSE_OK */
-/* 04a8 */ 0x0000000cL,
-/* 04ac */ 0x80880000L, /* jump msg_in_not_reject */
-/* 04b0 */ 0x00fffd60L,
-/* 04b4 */ 0x7c027e00L, /* move scntl2&0x7e to scntl2 */
-/* 04b8 */ 0x00000000L,
-/* 04bc */ 0x60000040L, /* clear ack */
-/* 04c0 */ 0x00000000L,
-/* 04c4 */ 0x48000000L, /* wait disconnect */
-/* 04c8 */ 0x00000000L,
-/* 04cc */ 0xc0000004L, /* move memory 4, state, scratcha */
-/* 04d0 */ 0x00000678L,
-/* 04d4 */ 0x00000034L,
-/* 04d8 */ 0x78340300L, /* move STATE_DISCONNECTED to scratcha0 */
-/* 04dc */ 0x00000000L,
-/* 04e0 */ 0xc0000004L, /* move memory 4, scratcha, state */
-/* 04e4 */ 0x00000034L,
-/* 04e8 */ 0x00000678L,
-/* 04ec */ 0x88880000L, /* call save_state */
-/* 04f0 */ 0x000001bcL,
-/* 04f4 */ 0x74020100L, /* move scntl2&0x01 to sfbr */
-/* 04f8 */ 0x00000000L,
-/* 04fc */ 0x98040000L, /* int SIR_NOTIFY_WSR, if not 0 */
-/* 0500 */ 0x00000073L,
-/* 0504 */ 0x80880000L, /* jump issue_check */
-/* 0508 */ 0x000001ccL,
-/* 050c */ 0x98080000L, /* int SIR_NOTIFY_RESELECTED_ON_SELECT */
-/* 0510 */ 0x00000075L,
-/* 0514 */ 0x80880000L, /* jump reselected */
-/* 0518 */ 0x00000008L,
-/* 051c */ 0x54000000L, /* wait reselect sigp_set */
-/* 0520 */ 0x000001acL,
-/* 0524 */ 0x60000200L, /* clear target */
-/* 0528 */ 0x00000000L,
-/* 052c */ 0x9f030000L, /* int SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT, when not msg_in */
-/* 0530 */ 0x00000006L,
-/* 0534 */ 0x0f000001L, /* move 1, scratchb, when msg_in */
-/* 0538 */ 0x0000005cL,
-/* 053c */ 0x98041f80L, /* int error_not_identify_after_reselect, if not MSG_IDENTIFY and mask 0x1f */
-/* 0540 */ 0x00000007L,
-/* 0544 */ 0xc0000004L, /* move memory 4, dsa_head, dsa */
-/* 0548 */ 0x00000008L,
-/* 054c */ 0x00000010L,
-/* 0550 */ 0x72100000L, /* move dsa0 to sfbr */
-/* 0554 */ 0x00000000L,
-/* 0558 */ 0x80840000L, /* jump find_dsa_1, if not 0 */
-/* 055c */ 0x00000030L,
-/* 0560 */ 0x72110000L, /* move dsa1 to sfbr */
-/* 0564 */ 0x00000000L,
-/* 0568 */ 0x80840000L, /* jump find_dsa_1, if not 0 */
-/* 056c */ 0x00000020L,
-/* 0570 */ 0x72120000L, /* move dsa2 to sfbr */
-/* 0574 */ 0x00000000L,
-/* 0578 */ 0x80840000L, /* jump find_dsa_1, if not 0 */
-/* 057c */ 0x00000010L,
-/* 0580 */ 0x72130000L, /* move dsa3 to sfbr */
-/* 0584 */ 0x00000000L,
-/* 0588 */ 0x980c0000L, /* int error_reselected, if 0 */
-/* 058c */ 0x00000003L,
-/* 0590 */ 0x88880000L, /* call load_state */
-/* 0594 */ 0x000000f8L,
-/* 0598 */ 0xc0000004L, /* move memory 4, state, scratcha */
-/* 059c */ 0x00000678L,
-/* 05a0 */ 0x00000034L,
-/* 05a4 */ 0x72340000L, /* move scratcha0 to sfbr */
-/* 05a8 */ 0x00000000L,
-/* 05ac */ 0x80840003L, /* jump find_dsa_next, if not STATE_DISCONNECTED */
-/* 05b0 */ 0x00000038L,
-/* 05b4 */ 0x740a0900L, /* move ssid & ssid_mask to sfbr */
-/* 05b8 */ 0x00000000L,
-/* 05bc */ 0xc0000001L, /* move memory 1, targ, find_dsa_smc1 */
-/* 05c0 */ 0x00000680L,
-/* 05c4 */ 0x000005c8L,
-/* 05c8 */ 0x808400ffL, /* jump find_dsa_next, if not 255 */
-/* 05cc */ 0x0000001cL,
-/* 05d0 */ 0xc0000001L, /* move memory 1, lun, find_dsa_smc2 */
-/* 05d4 */ 0x00000684L,
-/* 05d8 */ 0x000005e4L,
-/* 05dc */ 0x725c0000L, /* move scratchb0 to sfbr */
-/* 05e0 */ 0x00000000L,
-/* 05e4 */ 0x808cf8ffL, /* jump reload_sync, if 255 and mask ~7 */
-/* 05e8 */ 0x00000034L,
-/* 05ec */ 0xc0000004L, /* move memory 4, next, dsa */
-/* 05f0 */ 0x0000068cL,
-/* 05f4 */ 0x00000010L,
-/* 05f8 */ 0x80880000L, /* jump find_dsa_loop */
-/* 05fc */ 0x00ffff50L,
-/* 0600 */ 0x60000008L, /* clear atn */
-/* 0604 */ 0x00000000L,
-/* 0608 */ 0x878b0000L, /* jump msg_in_phase, when msg_in */
-/* 060c */ 0x00fffbf4L,
-/* 0610 */ 0x98080000L, /* int SIR_MSG_REJECT */
-/* 0614 */ 0x0000000aL,
-/* 0618 */ 0x80880000L, /* jump to_decisions */
-/* 061c */ 0x00000010L,
-/* 0620 */ 0x88880000L, /* call load_sync */
-/* 0624 */ 0x00000134L,
-/* 0628 */ 0x60000040L, /* clear ack */
-/* 062c */ 0x00000000L,
-/* 0630 */ 0x818b0000L, /* jump data_in_phase, when data_in */
-/* 0634 */ 0x00fffa20L,
-/* 0638 */ 0x828a0000L, /* jump cmd_phase, if cmd */
-/* 063c */ 0x00fffa00L,
-/* 0640 */ 0x808a0000L, /* jump data_out_phase, if data_out */
-/* 0644 */ 0x00fffaecL,
-/* 0648 */ 0x838a0000L, /* jump status_phase, if status */
-/* 064c */ 0x00fffba4L,
-/* 0650 */ 0x878a0000L, /* jump msg_in_phase, if msg_in */
-/* 0654 */ 0x00fffbacL,
-/* 0658 */ 0x98080000L, /* int error_unexpected_phase */
-/* 065c */ 0x00000004L,
-/* 0660 */ 0x838b0000L, /* jump status_phase, when status */
-/* 0664 */ 0x00fffb8cL,
-/* 0668 */ 0x878a0000L, /* jump msg_in_phase, if msg_in */
-/* 066c */ 0x00fffb94L,
-/* 0670 */ 0x98080000L, /* int error_unexpected_phase */
-/* 0674 */ 0x00000004L,
-/* 0678 */ 0x00000000L, /* state: defw 0 */
-/* 067c */ 0x00000000L, /* dmaaddr: defw 0 */
-/* 0680 */ 0x00000000L, /* targ: defw 0 */
-/* 0684 */ 0x00000000L, /* lun: defw 0 */
-/* 0688 */ 0x00000000L, /* sync: defw 0 */
-/* 068c */ 0x00000000L, /* next: defw 0 */
- /* dsa_load_len = dsa_load_end - dsa_copy */
- /* dsa_save_len = dsa_save_end - dsa_copy */
-/* 0690 */ 0xc0000004L, /* move memory 4, dsa, load_state_smc0 + 4 */
-/* 0694 */ 0x00000010L,
-/* 0698 */ 0x000006a0L,
-/* 069c */ 0xc0000018L, /* move memory dsa_load_len, 0, dsa_copy */
-/* 06a0 */ 0x00000000L,
-/* 06a4 */ 0x00000678L,
-/* 06a8 */ 0x90080000L, /* return */
-/* 06ac */ 0x00000000L,
-/* 06b0 */ 0xc0000004L, /* move memory 4, dsa, save_state_smc0 + 8 */
-/* 06b4 */ 0x00000010L,
-/* 06b8 */ 0x000006c4L,
-/* 06bc */ 0xc0000008L, /* move memory dsa_save_len, dsa_copy, 0 */
-/* 06c0 */ 0x00000678L,
-/* 06c4 */ 0x00000000L,
-/* 06c8 */ 0x90080000L, /* return */
-/* 06cc */ 0x00000000L,
-/* 06d0 */ 0x721a0000L, /* move ctest2 to sfbr */
-/* 06d4 */ 0x00000000L,
-/* 06d8 */ 0xc0000004L, /* move memory 4, dsa_head, dsa */
-/* 06dc */ 0x00000008L,
-/* 06e0 */ 0x00000010L,
-/* 06e4 */ 0x72100000L, /* move dsa0 to sfbr */
-/* 06e8 */ 0x00000000L,
-/* 06ec */ 0x80840000L, /* jump issue_check_1, if not 0 */
-/* 06f0 */ 0x00000030L,
-/* 06f4 */ 0x72110000L, /* move dsa1 to sfbr */
-/* 06f8 */ 0x00000000L,
-/* 06fc */ 0x80840000L, /* jump issue_check_1, if not 0 */
-/* 0700 */ 0x00000020L,
-/* 0704 */ 0x72120000L, /* move dsa2 to sfbr */
-/* 0708 */ 0x00000000L,
-/* 070c */ 0x80840000L, /* jump issue_check_1, if not 0 */
-/* 0710 */ 0x00000010L,
-/* 0714 */ 0x72130000L, /* move dsa3 to sfbr */
-/* 0718 */ 0x00000000L,
-/* 071c */ 0x808c0000L, /* jump wait_for_reselection, if 0 */
-/* 0720 */ 0x00fffdf8L,
-/* 0724 */ 0x88880000L, /* call load_state */
-/* 0728 */ 0x00ffff64L,
-/* 072c */ 0xc0000004L, /* move memory 4, state, scratcha */
-/* 0730 */ 0x00000678L,
-/* 0734 */ 0x00000034L,
-/* 0738 */ 0x72340000L, /* move scratcha0 to sfbr */
-/* 073c */ 0x00000000L,
-/* 0740 */ 0x808c0002L, /* jump start, if STATE_ISSUE */
-/* 0744 */ 0x00fff8c0L,
-/* 0748 */ 0xc0000004L, /* move memory 4, next, dsa */
-/* 074c */ 0x0000068cL,
-/* 0750 */ 0x00000010L,
-/* 0754 */ 0x80880000L, /* jump issue_check_loop */
-/* 0758 */ 0x00ffff88L,
-/* 075c */ 0xc0000004L, /* move memory 4, sync, scratcha */
-/* 0760 */ 0x00000688L,
-/* 0764 */ 0x00000034L,
-/* 0768 */ 0x72340000L, /* move scratcha0 to sfbr */
-/* 076c */ 0x00000000L,
-/* 0770 */ 0x6a030000L, /* move sfbr to scntl3 */
-/* 0774 */ 0x00000000L,
-/* 0778 */ 0x72350000L, /* move scratcha1 to sfbr */
-/* 077c */ 0x00000000L,
-/* 0780 */ 0x6a050000L, /* move sfbr to sxfer */
-/* 0784 */ 0x00000000L,
-/* 0788 */ 0x90080000L, /* return */
-/* 078c */ 0x00000000L,
-};
-
-#define NA_SCRIPT_SIZE 484
-
-struct na_patch na_patches[] = {
- { 0x0006, 5 }, /* 00000018 */
- { 0x000b, 4 }, /* 0000002c */
- { 0x0013, 4 }, /* 0000004c */
- { 0x0017, 1 }, /* 0000005c */
- { 0x0018, 2 }, /* 00000060 */
- { 0x001a, 1 }, /* 00000068 */
- { 0x001b, 2 }, /* 0000006c */
- { 0x0021, 1 }, /* 00000084 */
- { 0x002b, 2 }, /* 000000ac */
- { 0x002c, 1 }, /* 000000b0 */
- { 0x0030, 2 }, /* 000000c0 */
- { 0x0031, 1 }, /* 000000c4 */
- { 0x0037, 2 }, /* 000000dc */
- { 0x0038, 1 }, /* 000000e0 */
- { 0x003a, 2 }, /* 000000e8 */
- { 0x003b, 1 }, /* 000000ec */
- { 0x0043, 4 }, /* 0000010c */
- { 0x0047, 2 }, /* 0000011c */
- { 0x0048, 1 }, /* 00000120 */
- { 0x004e, 1 }, /* 00000138 */
- { 0x004f, 2 }, /* 0000013c */
- { 0x0051, 1 }, /* 00000144 */
- { 0x0052, 2 }, /* 00000148 */
- { 0x0058, 1 }, /* 00000160 */
- { 0x0059, 2 }, /* 00000164 */
- { 0x005b, 1 }, /* 0000016c */
- { 0x0065, 2 }, /* 00000194 */
- { 0x0066, 1 }, /* 00000198 */
- { 0x006a, 2 }, /* 000001a8 */
- { 0x006b, 1 }, /* 000001ac */
- { 0x0073, 4 }, /* 000001cc */
- { 0x0077, 2 }, /* 000001dc */
- { 0x0078, 1 }, /* 000001e0 */
- { 0x007e, 4 }, /* 000001f8 */
- { 0x0082, 2 }, /* 00000208 */
- { 0x0098, 1 }, /* 00000260 */
- { 0x0099, 2 }, /* 00000264 */
- { 0x009f, 2 }, /* 0000027c */
- { 0x00a0, 1 }, /* 00000280 */
- { 0x00b6, 2 }, /* 000002d8 */
- { 0x00c2, 2 }, /* 00000308 */
- { 0x00ca, 2 }, /* 00000328 */
- { 0x00d0, 2 }, /* 00000340 */
- { 0x00d6, 2 }, /* 00000358 */
- { 0x00e6, 2 }, /* 00000398 */
- { 0x00ec, 2 }, /* 000003b0 */
- { 0x0102, 2 }, /* 00000408 */
- { 0x010e, 2 }, /* 00000438 */
- { 0x011c, 4 }, /* 00000470 */
- { 0x0126, 2 }, /* 00000498 */
- { 0x0134, 1 }, /* 000004d0 */
- { 0x0135, 2 }, /* 000004d4 */
- { 0x0139, 2 }, /* 000004e4 */
- { 0x013a, 1 }, /* 000004e8 */
- { 0x014e, 2 }, /* 00000538 */
- { 0x0152, 4 }, /* 00000548 */
- { 0x0153, 2 }, /* 0000054c */
- { 0x0167, 1 }, /* 0000059c */
- { 0x0168, 2 }, /* 000005a0 */
- { 0x016d, 3 }, /* 000005b4 */
- { 0x0170, 1 }, /* 000005c0 */
- { 0x0171, 1 }, /* 000005c4 */
- { 0x0175, 1 }, /* 000005d4 */
- { 0x0176, 1 }, /* 000005d8 */
- { 0x017c, 1 }, /* 000005f0 */
- { 0x017d, 2 }, /* 000005f4 */
- { 0x01a5, 2 }, /* 00000694 */
- { 0x01a6, 1 }, /* 00000698 */
- { 0x01a9, 1 }, /* 000006a4 */
- { 0x01ad, 2 }, /* 000006b4 */
- { 0x01ae, 1 }, /* 000006b8 */
- { 0x01b0, 1 }, /* 000006c0 */
- { 0x01b7, 4 }, /* 000006dc */
- { 0x01b8, 2 }, /* 000006e0 */
- { 0x01cc, 1 }, /* 00000730 */
- { 0x01cd, 2 }, /* 00000734 */
- { 0x01d3, 1 }, /* 0000074c */
- { 0x01d4, 2 }, /* 00000750 */
- { 0x01d8, 1 }, /* 00000760 */
- { 0x01d9, 2 }, /* 00000764 */
-};
-#define NA_PATCHES 80
-
-enum na_external {
- X_scsi_id_buf,
- X_msg_out_buf,
- X_cmd_buf,
- X_data_buf,
- X_status_buf,
- X_msgin_buf,
- X_dsa_0,
- X_dsa_1,
- X_dsa_head,
- X_ssid_mask,
-};
-
-enum {
- E_issue_check_next = 1864,
- E_issue_check_1 = 1828,
- E_issue_check_loop = 1764,
- E_save_state_smc0 = 1724,
- E_load_state_smc0 = 1692,
- E_dsa_load_end = 1680,
- E_sync = 1672,
- E_dsa_save_end = 1664,
- E_dsa_copy = 1656,
- E_id_out_mismatch_recover = 1536,
- E_next = 1676,
- E_reload_sync = 1568,
- E_find_dsa_smc2 = 1508,
- E_lun = 1668,
- E_find_dsa_smc1 = 1480,
- E_targ = 1664,
- E_find_dsa_next = 1516,
- E_load_state = 1680,
- E_find_dsa_1 = 1424,
- E_find_dsa_loop = 1360,
- E_find_dsa = 1348,
- E_sigp_set = 1744,
- E_reselected = 1316,
- E_wsr_check = 1268,
- E_response_msg_in = 1172,
- E_response_repeat = 1132,
- E_response = 1108,
- E_reject = 988,
- E_wdtr = 964,
- E_sdtr = 876,
- E_ext_done = 988,
- E_ext_1 = 756,
- E_ext_2 = 900,
- E_ext_3 = 788,
- E_issue_check = 1752,
- E_extended = 708,
- E_ignore_wide = 1060,
- E_msg_in_skip = 692,
- E_disconnected = 1204,
- E_msg_in_not_reject = 532,
- E_rejected = 668,
- E_msg_in_phase = 516,
- E_status_phase = 500,
- E_data_out_mismatch = 464,
- E_data_out_block_mismatch = 368,
- E_data_out_normal = 440,
- E_data_out_block_loop = 332,
- E_data_out_phase = 308,
- E_post_data_to_decisions = 1632,
- E_data_in_mismatch = 272,
- E_data_mismatch_recover = 228,
- E_data_block_mismatch_recover = 216,
- E_save_state = 1712,
- E_data_in_block_mismatch = 136,
- E_data_in_normal = 248,
- E_data_in_block_loop = 112,
- E_dmaaddr = 1660,
- E_state = 1656,
- E_data_in_phase = 88,
- E_cmd_out_mismatch = 80,
- E_cmd_phase = 64,
- E_to_decisions = 1584,
- E_id_out_mismatch = 48,
- E_start1 = 40,
- E_reselected_on_select = 1292,
- E_load_sync = 1884,
- E_start = 8,
- E_wait_for_reselection = 1308,
- E_idle = 0,
-};
-#define A_dsa_save_len 8
-#define A_dsa_load_len 24
-#define A_BSIZE 512
-#define A_MSG_REJECT 7
-#define A_X_MSG_WDTR 3
-#define A_X_MSG_SDTR 1
-#define A_X_MSG 1
-#define A_MSG_IGNORE_WIDE_RESIDUE 35
-#define A_MSG_RESTORE_POINTERS 3
-#define A_MSG_SAVE_DATA_POINTER 2
-#define A_MSG_DISCONNECT 4
-#define A_MSG_IDENTIFY 128
-#define A_RESULT_OK 0
-#define A_STATE_DONE 4
-#define A_STATE_DISCONNECTED 3
-#define A_STATE_ISSUE 2
-#define A_STATE_ALLOCATED 1
-#define A_STATE_FREE 0
-#define A_SIR_NOTIFY_RESELECTED_ON_SELECT 117
-#define A_SIR_NOTIFY_LOAD_SYNC 116
-#define A_SIR_NOTIFY_WSR 115
-#define A_SIR_NOTIFY_BLOCK_DATA_IN 114
-#define A_SIR_NOTIFY_DATA_OUT 113
-#define A_SIR_NOTIFY_DATA_IN 112
-#define A_SIR_NOTIFY_COMMAND 111
-#define A_SIR_NOTIFY_DUMP_NEXT_CODE 110
-#define A_SIR_NOTIFY_ISSUE_CHECK 109
-#define A_SIR_NOTIFY_WAIT_RESELECT 108
-#define A_SIR_NOTIFY_ISSUE 107
-#define A_SIR_NOTIFY_SIGP 106
-#define A_SIR_NOTIFY_DUMP2 105
-#define A_SIR_NOTIFY_DUMP 104
-#define A_SIR_NOTIFY_STATUS 103
-#define A_SIR_NOTIFY_MSG_IN 102
-#define A_SIR_NOTIFY_RESELECT 101
-#define A_SIR_NOTIFY_DISC 100
-#define A_SIR_MSG_IGNORE_WIDE_RESIDUE 16
-#define A_SIR_MSG_WDTR 15
-#define A_SIR_EV_PHASE_SWITCH_AFTER_ID 14
-#define A_error_sigp_set 13
-#define A_SIR_EV_RESPONSE_OK 12
-#define A_SIR_MSG_SDTR 11
-#define A_SIR_MSG_REJECT 10
-#define A_error_too_little_data 9
-#define A_error_too_much_data 8
-#define A_error_not_identify_after_reselect 7
-#define A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT 6
-#define A_error_weird_message 5
-#define A_error_unexpected_phase 4
-#define A_error_reselected 3
-#define A_error_disconnected 2
-#define A_error_not_cmd_complete 1
-#define A_SIR_MSG_IO_COMPLETE 0
diff --git a/os/pc/sd53c8xx.n b/os/pc/sd53c8xx.n
deleted file mode 100644
index d9dc2fa1..00000000
--- a/os/pc/sd53c8xx.n
+++ /dev/null
@@ -1,448 +0,0 @@
-// NCR 53c8xx driver for Plan 9
-// Nigel Roles (nigel@9fs.org)
-//
-// Microcode
-//
-// 27/5/02 Fixed problems with transfers >= 256 * 512
-//
-// 13/3/01 Fixed microcode to support targets > 7
-//
-
-extern scsi_id_buf
-extern msg_out_buf
-extern cmd_buf
-extern data_buf
-extern status_buf
-extern msgin_buf
-extern dsa_0
-extern dsa_1
-extern dsa_head
-extern ssid_mask
-
-SIR_MSG_IO_COMPLETE = 0
-error_not_cmd_complete = 1
-error_disconnected = 2
-error_reselected = 3
-error_unexpected_phase = 4
-error_weird_message = 5
-SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT = 6
-error_not_identify_after_reselect = 7
-error_too_much_data = 8
-error_too_little_data = 9
-SIR_MSG_REJECT = 10
-SIR_MSG_SDTR = 11
-SIR_EV_RESPONSE_OK = 12
-error_sigp_set = 13
-SIR_EV_PHASE_SWITCH_AFTER_ID = 14
-SIR_MSG_WDTR = 15
-SIR_MSG_IGNORE_WIDE_RESIDUE = 16
-SIR_NOTIFY_DISC = 100
-SIR_NOTIFY_RESELECT = 101
-SIR_NOTIFY_MSG_IN = 102
-SIR_NOTIFY_STATUS = 103
-SIR_NOTIFY_DUMP = 104
-SIR_NOTIFY_DUMP2 = 105
-SIR_NOTIFY_SIGP = 106
-SIR_NOTIFY_ISSUE = 107
-SIR_NOTIFY_WAIT_RESELECT = 108
-SIR_NOTIFY_ISSUE_CHECK = 109
-SIR_NOTIFY_DUMP_NEXT_CODE = 110
-SIR_NOTIFY_COMMAND = 111
-SIR_NOTIFY_DATA_IN = 112
-SIR_NOTIFY_DATA_OUT = 113
-SIR_NOTIFY_BLOCK_DATA_IN = 114
-SIR_NOTIFY_WSR = 115
-SIR_NOTIFY_LOAD_SYNC = 116
-SIR_NOTIFY_RESELECTED_ON_SELECT = 117
-
-STATE_FREE = 0
-STATE_ALLOCATED = 1
-STATE_ISSUE = 2
-STATE_DISCONNECTED = 3
-STATE_DONE = 4
-
-RESULT_OK = 0
-
-MSG_IDENTIFY = 0x80
-MSG_DISCONNECT = 0x04
-MSG_SAVE_DATA_POINTER = 0x02
-MSG_RESTORE_POINTERS = 0x03
-MSG_IGNORE_WIDE_RESIDUE = 0x23
-X_MSG = 0x01
-X_MSG_SDTR = 0x01
-X_MSG_WDTR = 0x03
-MSG_REJECT = 0x07
-
-BSIZE = 512
-//BSIZE=4096
-
-idle:
- jump wait_for_reselection
-start:
- call load_sync
-// move 13 to ctest0
-// int SIR_NOTIFY_ISSUE
- clear target
- select atn from scsi_id_buf, reselected_on_select // do I need to clear ATN here?
- jump start1, when msg_in
-start1:
-// move 14 to ctest0
- move from msg_out_buf, when msg_out
-id_out_mismatch:
- jump start1, when msg_out // repeat on parity grounds
- jump to_decisions, when not cmd
-cmd_phase:
-// int SIR_NOTIFY_COMMAND
- clear atn
- move from cmd_buf, when cmd
-cmd_out_mismatch:
- jump to_decisions, when not data_in
-data_in_phase:
- move memory 4, state, scratcha
- move memory 4, dmaaddr, scratchb
-// int SIR_NOTIFY_DATA_IN
-data_in_block_loop:
- move scratcha2 to sfbr
- jump data_in_normal, if 0
-// int SIR_NOTIFY_BLOCK_DATA_IN
- move BSIZE, ptr dmaaddr, when data_in // transfer BSIZE bytes
-data_in_block_mismatch:
- move scratchb1 + BSIZE / 256 to scratchb1 // add BSIZE to scratchb
- move scratchb2 + 0 to scratchb2 with carry
- move scratchb3 + 0 to scratchb3 with carry
- move scratcha2 + 255 to scratcha2 // sub one from block count
- move memory 4, scratchb, dmaaddr // save latest dmaddr
- jump data_in_block_loop, when data_in
- move memory 4, scratcha, state // save latest state
- call save_state
- jump to_decisions
-data_block_mismatch_recover:
- move memory 4, scratchb, dmaaddr // save latest dmaddr
-data_mismatch_recover:
- move memory 4, scratcha, state // save latest state
- jump to_decisions // no need to save
- // as interrupt routine
- // did this
-data_in_normal:
- move scratcha3 to sfbr
- int error_too_much_data, if not 0
- move from data_buf, when data_in
-data_in_mismatch:
- move 2 to scratcha3
- move memory 4, scratcha, state
- call save_state
- jump post_data_to_decisions
-data_out_phase:
-// int SIR_NOTIFY_DATA_OUT
- move memory 4, state, scratcha
- move memory 4, dmaaddr, scratchb
-data_out_block_loop:
- move scratcha2 to sfbr
- jump data_out_normal, if 0
- move memory 4, dmaaddr, scratchb
- move BSIZE, ptr dmaaddr, when data_out // transfer BSIZE bytes
-data_out_block_mismatch:
- move scratchb1 + BSIZE / 256 to scratchb1 // add BSIZE to scratchb
- move scratchb2 + 0 to scratchb2 with carry
- move scratchb3 + 0 to scratchb3 with carry
- move scratcha2 + 255 to scratcha2 // sub one from block count
- move memory 4, scratchb, dmaaddr // save latest dmaddr
- jump data_out_block_loop, when data_out
- move memory 4, scratcha, state // save latest state
- jump to_decisions
-data_out_normal:
- move scratcha3 to sfbr
- int error_too_little_data, if not 0
- move from data_buf, when data_out
-data_out_mismatch:
- move 2 to scratcha3
- move memory 4, scratcha, state
- call save_state
- jump post_data_to_decisions
-status_phase:
- move from status_buf, when status
-// int SIR_NOTIFY_STATUS
- int error_unexpected_phase, when not msg_in
-msg_in_phase:
- move 1, scratcha, when msg_in
-// int SIR_NOTIFY_MSG_IN
- jump rejected, if MSG_REJECT
-msg_in_not_reject:
- jump disconnected, if MSG_DISCONNECT
- jump msg_in_skip, if MSG_SAVE_DATA_POINTER
- jump msg_in_skip, if MSG_RESTORE_POINTERS
- jump ignore_wide, if MSG_IGNORE_WIDE_RESIDUE
- jump extended, if X_MSG
- int error_not_cmd_complete, if not 0
- move scntl2&0x7e to scntl2 // take care not to clear WSR
- clear ack
- wait disconnect
- // update state
- move memory 4, state, scratcha
- move STATE_DONE to scratcha0
- move RESULT_OK to scratcha1
- move memory 4, scratcha, state
- call save_state
-// int SIR_MSG_IO_COMPLETE
- intfly 0
- jump issue_check
-
-rejected:
- int SIR_MSG_REJECT
- clear ack
- jump to_decisions
-msg_in_skip:
- clear ack
- jump to_decisions
-
-extended:
- clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha1, when msg_in
- jump ext_3, if 3
- jump ext_2, if 2
- int error_weird_message, if not 1
-ext_1:
- clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha1, when msg_in
- jump ext_done
-
-ext_3: clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha1, when msg_in
- clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha2, when msg_in
- clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha3, when msg_in
- move scratcha1 to sfbr
- jump ext_done, if not X_MSG_SDTR
-
-// the target sent SDTR - leave ACK asserted and signal kernel
-// kernel will either restart at reject, or continue
-sdtr: int SIR_MSG_SDTR
- clear ack
- jump to_decisions
-
-ext_2: clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha1, when msg_in
- clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha2, when msg_in
- move scratcha1 to sfbr
- jump ext_done, if not X_MSG_WDTR
-
-wdtr: int SIR_MSG_WDTR
- clear ack
- jump to_decisions
-
-ext_done:
-// ought to check message here, but instead reject all
-// NB ATN set
-reject:
- set atn // get target's ATN
- clear ack // finish ACK
- move MSG_REJECT to scratcha // prepare message
- int error_unexpected_phase, when not msg_out// didn't get ATN
- clear atn // last byte coming
- move 1, scratcha, when msg_out // send byte
- clear ack // finish ACK
- jump reject, when msg_out // parity error
- jump to_decisions
-
-ignore_wide:
- clear ack
- int error_unexpected_phase, when not msg_in
- move 1, scratcha1, when msg_in
- int SIR_MSG_IGNORE_WIDE_RESIDUE
- clear ack
- jump to_decisions
-
-// sends a response to a message
-response:
- set atn
- clear ack
- int error_unexpected_phase, when not msg_out
-response_repeat:
- move from msg_out_buf, when msg_out
- jump response_repeat, when msg_out // repeat on parity grounds
-// now look for response
-// msg_in could be a REJECT
-// anything other message is something else so signal kernel first
- jump response_msg_in, when msg_in
- int SIR_EV_RESPONSE_OK // not a MSG_IN so OK
- jump to_decisions
-
-response_msg_in:
- move 1, scratcha, when msg_in
- jump rejected, if MSG_REJECT // go and generate rej interrupt
- int SIR_EV_RESPONSE_OK // not a REJECT so OK
- jump msg_in_not_reject // try others
-
-disconnected:
-// move 5 to ctest0
- move scntl2&0x7e to scntl2 // don't clear WSR
- clear ack
- wait disconnect
- // UPDATE state to disconnected
- move memory 4, state, scratcha
- move STATE_DISCONNECTED to scratcha0
- move memory 4, scratcha, state
- call save_state
-wsr_check:
- move scntl2&0x01 to sfbr
- int SIR_NOTIFY_WSR, if not 0
-// int SIR_NOTIFY_DISC
- jump issue_check
-
-reselected_on_select:
- int SIR_NOTIFY_RESELECTED_ON_SELECT
- jump reselected
-
-wait_for_reselection:
-// move 11 to ctest0
-// int SIR_NOTIFY_WAIT_RESELECT
- wait reselect sigp_set
-reselected:
-// move 12 to ctest0
- clear target
- int SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT, when not msg_in
- move 1, scratchb, when msg_in
- int error_not_identify_after_reselect, if not MSG_IDENTIFY and mask 0x1f
-// int SIR_NOTIFY_RESELECT
- // now locate the right DSA - note do not clear ACK, so target doesn't start
- // synchronous transfer until we are ready
-find_dsa:
-// move 6 to ctest0
- move memory 4, dsa_head, dsa
-find_dsa_loop:
-// move 7 to ctest0
- move dsa0 to sfbr
- jump find_dsa_1, if not 0
- move dsa1 to sfbr
- jump find_dsa_1, if not 0
- move dsa2 to sfbr
- jump find_dsa_1, if not 0
- move dsa3 to sfbr
- int error_reselected, if 0 // couldn't match dsa (panic)
-find_dsa_1:
-// move 8 to ctest0
- // load state from DSA into dsa_copy
- call load_state
- move memory 4, state, scratcha // get dsastate in scratcha
- move scratcha0 to sfbr // and state variable in sfbr
- jump find_dsa_next, if not STATE_DISCONNECTED // wrong state
- move ssid & ssid_mask to sfbr // get target ID
- move memory 1, targ, find_dsa_smc1 // forge target comparison instruction
-find_dsa_smc1:
- jump find_dsa_next, if not 255 // jump if not matched
- move memory 1, lun, find_dsa_smc2 // forge lun comparison instruction
- move scratchb0 to sfbr // recover IDENTIFY message
-find_dsa_smc2:
- jump reload_sync, if 255 and mask ~7 // off we jolly well go
-find_dsa_next:
- move memory 4, next, dsa // find next
- jump find_dsa_loop
-
-// id_out terminated early
-// most likely the message wasn't recognised
-// clear ATN and accept the message in
-id_out_mismatch_recover:
- clear atn
- jump msg_in_phase, when msg_in
- int SIR_MSG_REJECT
- jump to_decisions
-
-// Reload synchronous registers after a reconnect. If the transfer is a synchronous read, then
-// as soon as we clear ACK, the target will switch to data_in and start blasting data into the
-// fifo. We need to be executing the 'jump when data_in' instruction before the target stops REQing
-// since it is the REQ which latches the 'when'. The target will do 16 REQs before stopping, so
-// we have 16 bytes (160uS) plus delays to do this after clearing ACK. Once the jump is executing,
-// the target will wait, so as much debugging as you like can happen in data_in_phase, just don't
-// stick any delays between 'clear ack' and 'jump data_in_phase, when data_in'.
-
-reload_sync:
- call load_sync
- clear ack
-to_decisions:
- jump data_in_phase, when data_in
- jump cmd_phase, if cmd
- jump data_out_phase, if data_out
- jump status_phase, if status
- jump msg_in_phase, if msg_in
- int error_unexpected_phase
-post_data_to_decisions:
- jump status_phase, when status
- jump msg_in_phase, if msg_in
- int error_unexpected_phase
-
-//
-// MULTI_TARGET
-//
-// following must mirror top of dsa structure
-// the first section is loaded and saved, the
-// second section loaded only
-dsa_copy:
-state: defw 0 // a0 is state, a1 result, a2 dma block count
-dmaaddr: defw 0 // dma address for block moves
-dsa_save_end:
-targ: defw 0 // lsb is target
-lun: defw 0 // lsb is lun
-sync: defw 0 // lsb is scntl3, sxfer
-next: defw 0
-dsa_load_end:
-dsa_load_len = dsa_load_end - dsa_copy
-dsa_save_len = dsa_save_end - dsa_copy
-
-load_state:
- // load state from DSA into dsa_copy
-// move 9 to ctest0
- move memory 4, dsa, load_state_smc0 + 4
-load_state_smc0:
- move memory dsa_load_len, 0, dsa_copy
-// move 20 to ctest0
- return
-save_state:
- move memory 4, dsa, save_state_smc0 + 8
-save_state_smc0:
- move memory dsa_save_len, dsa_copy, 0
- return
-
-sigp_set:
-// int SIR_NOTIFY_SIGP
- move ctest2 to sfbr // clear SIGP
-issue_check:
-// int SIR_NOTIFY_ISSUE_CHECK
-// move 1 to ctest0
- move memory 4, dsa_head, dsa
-issue_check_loop:
-// move 2 to ctest0
- move dsa0 to sfbr
- jump issue_check_1, if not 0
- move dsa1 to sfbr
- jump issue_check_1, if not 0
- move dsa2 to sfbr
- jump issue_check_1, if not 0
- move dsa3 to sfbr
- jump wait_for_reselection, if 0 // nothing to do
-issue_check_1:
-// move 3 to ctest0
- call load_state
- move memory 4, state, scratcha // get dsastate in scratcha
- move scratcha0 to sfbr // and state variable in sfbr
- jump start, if STATE_ISSUE // right state
-issue_check_next:
-// move 4 to ctest0
- move memory 4, next, dsa // find next
- jump issue_check_loop
-load_sync:
- move memory 4, sync, scratcha // load the sync stuff
- move scratcha0 to sfbr // assuming load_state has been called
- move sfbr to scntl3
- move scratcha1 to sfbr
- move sfbr to sxfer
-// int SIR_NOTIFY_LOAD_SYNC
- return
diff --git a/os/pc/sdata.c b/os/pc/sdata.c
deleted file mode 100644
index 1e438986..00000000
--- a/os/pc/sdata.c
+++ /dev/null
@@ -1,2206 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-#include "../port/sd.h"
-
-extern SDifc sdataifc;
-
-enum {
- DbgCONFIG = 0x0001, /* detected drive config info */
- DbgIDENTIFY = 0x0002, /* detected drive identify info */
- DbgSTATE = 0x0004, /* dump state on panic */
- DbgPROBE = 0x0008, /* trace device probing */
- DbgDEBUG = 0x0080, /* the current problem... */
- DbgINL = 0x0100, /* That Inil20+ message we hate */
- Dbg48BIT = 0x0200, /* 48-bit LBA */
- DbgBsy = 0x0400, /* interrupt but Bsy (shared IRQ) */
-};
-#define DEBUG (DbgDEBUG|DbgSTATE)
-
-enum { /* I/O ports */
- Data = 0,
- Error = 1, /* (read) */
- Features = 1, /* (write) */
- Count = 2, /* sector count<7-0>, sector count<15-8> */
- Ir = 2, /* interrupt reason (PACKET) */
- Sector = 3, /* sector number */
- Lbalo = 3, /* LBA<7-0>, LBA<31-24> */
- Cyllo = 4, /* cylinder low */
- Bytelo = 4, /* byte count low (PACKET) */
- Lbamid = 4, /* LBA<15-8>, LBA<39-32> */
- Cylhi = 5, /* cylinder high */
- Bytehi = 5, /* byte count hi (PACKET) */
- Lbahi = 5, /* LBA<23-16>, LBA<47-40> */
- Dh = 6, /* Device/Head, LBA<32-14> */
- Status = 7, /* (read) */
- Command = 7, /* (write) */
-
- As = 2, /* Alternate Status (read) */
- Dc = 2, /* Device Control (write) */
-};
-
-enum { /* Error */
- Med = 0x01, /* Media error */
- Ili = 0x01, /* command set specific (PACKET) */
- Nm = 0x02, /* No Media */
- Eom = 0x02, /* command set specific (PACKET) */
- Abrt = 0x04, /* Aborted command */
- Mcr = 0x08, /* Media Change Request */
- Idnf = 0x10, /* no user-accessible address */
- Mc = 0x20, /* Media Change */
- Unc = 0x40, /* Uncorrectable data error */
- Wp = 0x40, /* Write Protect */
- Icrc = 0x80, /* Interface CRC error */
-};
-
-enum { /* Features */
- Dma = 0x01, /* data transfer via DMA (PACKET) */
- Ovl = 0x02, /* command overlapped (PACKET) */
-};
-
-enum { /* Interrupt Reason */
- Cd = 0x01, /* Command/Data */
- Io = 0x02, /* I/O direction */
- Rel = 0x04, /* Bus Release */
-};
-
-enum { /* Device/Head */
- Dev0 = 0xA0, /* Master */
- Dev1 = 0xB0, /* Slave */
- Lba = 0x40, /* LBA mode */
-};
-
-enum { /* internal flags */
- Lba48 = 0x1, /* LBA48 mode */
- Lba48always = 0x2, /* ... */
-};
-
-enum { /* Status, Alternate Status */
- Err = 0x01, /* Error */
- Chk = 0x01, /* Check error (PACKET) */
- Drq = 0x08, /* Data Request */
- Dsc = 0x10, /* Device Seek Complete */
- Serv = 0x10, /* Service */
- Df = 0x20, /* Device Fault */
- Dmrd = 0x20, /* DMA ready (PACKET) */
- Drdy = 0x40, /* Device Ready */
- Bsy = 0x80, /* Busy */
-};
-
-enum { /* Command */
- Cnop = 0x00, /* NOP */
- Cdr = 0x08, /* Device Reset */
- Crs = 0x20, /* Read Sectors */
- Crs48 = 0x24, /* Read Sectors Ext */
- Crd48 = 0x25, /* Read w/ DMA Ext */
- Crdq48 = 0x26, /* Read w/ DMA Queued Ext */
- Crsm48 = 0x29, /* Read Multiple Ext */
- Cws = 0x30, /* Write Sectors */
- Cws48 = 0x34, /* Write Sectors Ext */
- Cwd48 = 0x35, /* Write w/ DMA Ext */
- Cwdq48 = 0x36, /* Write w/ DMA Queued Ext */
- Cwsm48 = 0x39, /* Write Multiple Ext */
- Cedd = 0x90, /* Execute Device Diagnostics */
- Cpkt = 0xA0, /* Packet */
- Cidpkt = 0xA1, /* Identify Packet Device */
- Crsm = 0xC4, /* Read Multiple */
- Cwsm = 0xC5, /* Write Multiple */
- Csm = 0xC6, /* Set Multiple */
- Crdq = 0xC7, /* Read DMA queued */
- Crd = 0xC8, /* Read DMA */
- Cwd = 0xCA, /* Write DMA */
- Cwdq = 0xCC, /* Write DMA queued */
- Cstandby = 0xE2, /* Standby */
- Cid = 0xEC, /* Identify Device */
- Csf = 0xEF, /* Set Features */
-};
-
-enum { /* Device Control */
- Nien = 0x02, /* (not) Interrupt Enable */
- Srst = 0x04, /* Software Reset */
- Hob = 0x80, /* High Order Bit [sic] */
-};
-
-enum { /* PCI Configuration Registers */
- Bmiba = 0x20, /* Bus Master Interface Base Address */
- Idetim = 0x40, /* IE Timing */
- Sidetim = 0x44, /* Slave IE Timing */
- Udmactl = 0x48, /* Ultra DMA/33 Control */
- Udmatim = 0x4A, /* Ultra DMA/33 Timing */
-};
-
-enum { /* Bus Master IDE I/O Ports */
- Bmicx = 0, /* Command */
- Bmisx = 2, /* Status */
- Bmidtpx = 4, /* Descriptor Table Pointer */
-};
-
-enum { /* Bmicx */
- Ssbm = 0x01, /* Start/Stop Bus Master */
- Rwcon = 0x08, /* Read/Write Control */
-};
-
-enum { /* Bmisx */
- Bmidea = 0x01, /* Bus Master IDE Active */
- Idedmae = 0x02, /* IDE DMA Error (R/WC) */
- Ideints = 0x04, /* IDE Interrupt Status (R/WC) */
- Dma0cap = 0x20, /* Drive 0 DMA Capable */
- Dma1cap = 0x40, /* Drive 0 DMA Capable */
-};
-enum { /* Physical Region Descriptor */
- PrdEOT = 0x80000000, /* Bus Master IDE Active */
-};
-
-enum { /* offsets into the identify info. */
- Iconfig = 0, /* general configuration */
- Ilcyl = 1, /* logical cylinders */
- Ilhead = 3, /* logical heads */
- Ilsec = 6, /* logical sectors per logical track */
- Iserial = 10, /* serial number */
- Ifirmware = 23, /* firmware revision */
- Imodel = 27, /* model number */
- Imaxrwm = 47, /* max. read/write multiple sectors */
- Icapabilities = 49, /* capabilities */
- Istandby = 50, /* device specific standby timer */
- Ipiomode = 51, /* PIO data transfer mode number */
- Ivalid = 53,
- Iccyl = 54, /* cylinders if (valid&0x01) */
- Ichead = 55, /* heads if (valid&0x01) */
- Icsec = 56, /* sectors if (valid&0x01) */
- Iccap = 57, /* capacity if (valid&0x01) */
- Irwm = 59, /* read/write multiple */
- Ilba = 60, /* LBA size */
- Imwdma = 63, /* multiword DMA mode */
- Iapiomode = 64, /* advanced PIO modes supported */
- Iminmwdma = 65, /* min. multiword DMA cycle time */
- Irecmwdma = 66, /* rec. multiword DMA cycle time */
- Iminpio = 67, /* min. PIO cycle w/o flow control */
- Iminiordy = 68, /* min. PIO cycle with IORDY */
- Ipcktbr = 71, /* time from PACKET to bus release */
- Iserbsy = 72, /* time from SERVICE to !Bsy */
- Iqdepth = 75, /* max. queue depth */
- Imajor = 80, /* major version number */
- Iminor = 81, /* minor version number */
- Icsfs = 82, /* command set/feature supported */
- Icsfe = 85, /* command set/feature enabled */
- Iudma = 88, /* ultra DMA mode */
- Ierase = 89, /* time for security erase */
- Ieerase = 90, /* time for enhanced security erase */
- Ipower = 91, /* current advanced power management */
- Ilba48 = 100, /* 48-bit LBA size (64 bits in 100-103) */
- Irmsn = 127, /* removable status notification */
- Isecstat = 128, /* security status */
- Icfapwr = 160, /* CFA power mode */
- Imediaserial = 176, /* current media serial number */
- Icksum = 255, /* checksum */
-};
-
-enum { /* bit masks for config identify info */
- Mpktsz = 0x0003, /* packet command size */
- Mincomplete = 0x0004, /* incomplete information */
- Mdrq = 0x0060, /* DRQ type */
- Mrmdev = 0x0080, /* device is removable */
- Mtype = 0x1F00, /* device type */
- Mproto = 0x8000, /* command protocol */
-};
-
-enum { /* bit masks for capabilities identify info */
- Mdma = 0x0100, /* DMA supported */
- Mlba = 0x0200, /* LBA supported */
- Mnoiordy = 0x0400, /* IORDY may be disabled */
- Miordy = 0x0800, /* IORDY supported */
- Msoftrst = 0x1000, /* needs soft reset when Bsy */
- Mstdby = 0x2000, /* standby supported */
- Mqueueing = 0x4000, /* queueing overlap supported */
- Midma = 0x8000, /* interleaved DMA supported */
-};
-
-enum { /* bit masks for supported/enabled features */
- Msmart = 0x0001,
- Msecurity = 0x0002,
- Mrmmedia = 0x0004,
- Mpwrmgmt = 0x0008,
- Mpkt = 0x0010,
- Mwcache = 0x0020,
- Mlookahead = 0x0040,
- Mrelirq = 0x0080,
- Msvcirq = 0x0100,
- Mreset = 0x0200,
- Mprotected = 0x0400,
- Mwbuf = 0x1000,
- Mrbuf = 0x2000,
- Mnop = 0x4000,
- Mmicrocode = 0x0001,
- Mqueued = 0x0002,
- Mcfa = 0x0004,
- Mapm = 0x0008,
- Mnotify = 0x0010,
- Mstandby = 0x0020,
- Mspinup = 0x0040,
- Mmaxsec = 0x0100,
- Mautoacoustic = 0x0200,
- Maddr48 = 0x0400,
- Mdevconfov = 0x0800,
- Mflush = 0x1000,
- Mflush48 = 0x2000,
- Msmarterror = 0x0001,
- Msmartselftest = 0x0002,
- Mmserial = 0x0004,
- Mmpassthru = 0x0008,
- Mlogging = 0x0020,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Drive Drive;
-
-typedef struct Prd {
- ulong pa; /* Physical Base Address */
- int count;
-} Prd;
-
-enum {
- Nprd = SDmaxio/(64*1024)+2,
-};
-
-typedef struct Ctlr {
- int cmdport;
- int ctlport;
- int irq;
- int tbdf;
- int bmiba; /* bus master interface base address */
-
- Pcidev* pcidev;
- void (*ienable)(Ctlr*);
- void (*idisable)(Ctlr*);
- SDev* sdev;
-
- Drive* drive[2];
-
- Prd* prdt; /* physical region descriptor table */
- void* prdtbase;
-
- QLock; /* current command */
- Drive* curdrive;
- int command; /* last command issued (debugging) */
- Rendez;
- int done;
-
- Lock; /* register access */
-} Ctlr;
-
-typedef struct Drive {
- Ctlr* ctlr;
-
- int dev;
- ushort info[256];
- int c; /* cylinder */
- int h; /* head */
- int s; /* sector */
- vlong sectors; /* total */
- int secsize; /* sector size */
-
- int dma; /* DMA R/W possible */
- int dmactl;
- int rwm; /* read/write multiple possible */
- int rwmctl;
-
- int pkt; /* PACKET device, length of pktcmd */
- uchar pktcmd[16];
- int pktdma; /* this PACKET command using dma */
-
- uchar sense[18];
- uchar inquiry[48];
-
- QLock; /* drive access */
- int command; /* current command */
- int write;
- uchar* data;
- int dlen;
- uchar* limit;
- int count; /* sectors */
- int block; /* R/W bytes per block */
- int status;
- int error;
- int flags; /* internal flags */
-} Drive;
-
-static void
-pc87415ienable(Ctlr* ctlr)
-{
- Pcidev *p;
- int x;
-
- p = ctlr->pcidev;
- if(p == nil)
- return;
-
- x = pcicfgr32(p, 0x40);
- if(ctlr->cmdport == p->mem[0].bar)
- x &= ~0x00000100;
- else
- x &= ~0x00000200;
- pcicfgw32(p, 0x40, x);
-}
-
-static void
-atadumpstate(Drive* drive, uchar* cmd, vlong lba, int count)
-{
- Prd *prd;
- Pcidev *p;
- Ctlr *ctlr;
- int i, bmiba;
-
- if(!(DEBUG & DbgSTATE)){
- USED(drive, cmd, lba, count);
- return;
- }
-
- ctlr = drive->ctlr;
- print("command %2.2uX\n", ctlr->command);
- print("data %8.8p limit %8.8p dlen %d status %uX error %uX\n",
- drive->data, drive->limit, drive->dlen,
- drive->status, drive->error);
- if(cmd != nil){
- print("lba %d -> %lld, count %d -> %d (%d)\n",
- (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5], lba,
- (cmd[7]<<8)|cmd[8], count, drive->count);
- }
- if(!(inb(ctlr->ctlport+As) & Bsy)){
- for(i = 1; i < 7; i++)
- print(" 0x%2.2uX", inb(ctlr->cmdport+i));
- print(" 0x%2.2uX\n", inb(ctlr->ctlport+As));
- }
- if(drive->command == Cwd || drive->command == Crd){
- bmiba = ctlr->bmiba;
- prd = ctlr->prdt;
- print("bmicx %2.2uX bmisx %2.2uX prdt %8.8p\n",
- inb(bmiba+Bmicx), inb(bmiba+Bmisx), prd);
- for(;;){
- print("pa 0x%8.8luX count %8.8uX\n",
- prd->pa, prd->count);
- if(prd->count & PrdEOT)
- break;
- prd++;
- }
- }
- if(ctlr->pcidev && ctlr->pcidev->vid == 0x8086){
- p = ctlr->pcidev;
- print("0x40: %4.4uX 0x42: %4.4uX",
- pcicfgr16(p, 0x40), pcicfgr16(p, 0x42));
- print("0x48: %2.2uX\n", pcicfgr8(p, 0x48));
- print("0x4A: %4.4uX\n", pcicfgr16(p, 0x4A));
- }
-}
-
-static int
-atadebug(int cmdport, int ctlport, char* fmt, ...)
-{
- int i, n;
- va_list arg;
- char buf[PRINTSIZE];
-
- if(!(DEBUG & DbgPROBE)){
- USED(cmdport, ctlport, fmt);
- return 0;
- }
-
- va_start(arg, fmt);
- n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
- va_end(arg);
-
- if(cmdport){
- if(buf[n-1] == '\n')
- n--;
- n += snprint(buf+n, PRINTSIZE-n, " ataregs 0x%uX:",
- cmdport);
- for(i = Features; i < Command; i++)
- n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
- inb(cmdport+i));
- if(ctlport)
- n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
- inb(ctlport+As));
- n += snprint(buf+n, PRINTSIZE-n, "\n");
- }
- putstrn(buf, n);
-
- return n;
-}
-
-static int
-ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro)
-{
- int as;
-
- atadebug(cmdport, ctlport, "ataready: dev %uX reset %uX ready %uX",
- dev, reset, ready);
-
- for(;;){
- /*
- * Wait for the controller to become not busy and
- * possibly for a status bit to become true (usually
- * Drdy). Must change to the appropriate device
- * register set if necessary before testing for ready.
- * Always run through the loop at least once so it
- * can be used as a test for !Bsy.
- */
- as = inb(ctlport+As);
- if(as & reset){
- /* nothing to do */
- }
- else if(dev){
- outb(cmdport+Dh, dev);
- dev = 0;
- }
- else if(ready == 0 || (as & ready)){
- atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
- return as;
- }
-
- if(micro-- <= 0){
- atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
- break;
- }
- microdelay(1);
- }
- atadebug(cmdport, ctlport, "ataready: timeout");
-
- return -1;
-}
-
-/*
-static int
-atacsf(Drive* drive, vlong csf, int supported)
-{
- ushort *info;
- int cmdset, i, x;
-
- if(supported)
- info = &drive->info[Icsfs];
- else
- info = &drive->info[Icsfe];
-
- for(i = 0; i < 3; i++){
- x = (csf>>(16*i)) & 0xFFFF;
- if(x == 0)
- continue;
- cmdset = info[i];
- if(cmdset == 0 || cmdset == 0xFFFF)
- return 0;
- return cmdset & x;
- }
-
- return 0;
-}
-*/
-
-static int
-atadone(void* arg)
-{
- return ((Ctlr*)arg)->done;
-}
-
-static int
-atarwmmode(Drive* drive, int cmdport, int ctlport, int dev)
-{
- int as, maxrwm, rwm;
-
- maxrwm = (drive->info[Imaxrwm] & 0xFF);
- if(maxrwm == 0)
- return 0;
-
- /*
- * Sometimes drives come up with the current count set
- * to 0; if so, set a suitable value, otherwise believe
- * the value in Irwm if the 0x100 bit is set.
- */
- if(drive->info[Irwm] & 0x100)
- rwm = (drive->info[Irwm] & 0xFF);
- else
- rwm = 0;
- if(rwm == 0)
- rwm = maxrwm;
- if(rwm > 16)
- rwm = 16;
- if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 102*1000) < 0)
- return 0;
- outb(cmdport+Count, rwm);
- outb(cmdport+Command, Csm);
- microdelay(1);
- as = ataready(cmdport, ctlport, 0, Bsy, Drdy|Df|Err, 1000);
- inb(cmdport+Status);
- if(as < 0 || (as & (Df|Err)))
- return 0;
-
- drive->rwm = rwm;
-
- return rwm;
-}
-
-static int
-atadmamode(Drive* drive)
-{
- int dma;
-
- /*
- * Check if any DMA mode enabled.
- * Assumes the BIOS has picked and enabled the best.
- * This is completely passive at the moment, no attempt is
- * made to ensure the hardware is correctly set up.
- */
- dma = drive->info[Imwdma] & 0x0707;
- drive->dma = (dma>>8) & dma;
- if(drive->dma == 0 && (drive->info[Ivalid] & 0x04)){
- dma = drive->info[Iudma] & 0x7F7F;
- drive->dma = (dma>>8) & dma;
- if(drive->dma)
- drive->dma |= 'U'<<16;
- }
-
- return dma;
-}
-
-static int
-ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info)
-{
- int as, command, drdy;
-
- if(pkt){
- command = Cidpkt;
- drdy = 0;
- }
- else{
- command = Cid;
- drdy = Drdy;
- }
- as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000);
- if(as < 0)
- return as;
- outb(cmdport+Command, command);
- microdelay(1);
-
- as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000);
- if(as < 0)
- return -1;
- if(as & Err)
- return as;
-
- memset(info, 0, 512);
- inss(cmdport+Data, info, 256);
- inb(cmdport+Status);
-
- if(DEBUG & DbgIDENTIFY){
- int i;
- ushort *sp;
-
- sp = (ushort*)info;
- for(i = 0; i < 256; i++){
- if(i && (i%16) == 0)
- print("\n");
- print(" %4.4uX", *sp);
- sp++;
- }
- print("\n");
- }
-
- return 0;
-}
-
-static Drive*
-atadrive(int cmdport, int ctlport, int dev)
-{
- Drive *drive;
- int as, i, pkt;
- uchar buf[512], *p;
- ushort iconfig, *sp;
-
- atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
- pkt = 1;
-retry:
- as = ataidentify(cmdport, ctlport, dev, pkt, buf);
- if(as < 0)
- return nil;
- if(as & Err){
- if(pkt == 0)
- return nil;
- pkt = 0;
- goto retry;
- }
-
- if((drive = malloc(sizeof(Drive))) == nil)
- return nil;
- drive->dev = dev;
- memmove(drive->info, buf, sizeof(drive->info));
- drive->sense[0] = 0x70;
- drive->sense[7] = sizeof(drive->sense)-7;
-
- drive->inquiry[2] = 2;
- drive->inquiry[3] = 2;
- drive->inquiry[4] = sizeof(drive->inquiry)-4;
- p = &drive->inquiry[8];
- sp = &drive->info[Imodel];
- for(i = 0; i < 20; i++){
- *p++ = *sp>>8;
- *p++ = *sp++;
- }
-
- drive->secsize = 512;
-
- /*
- * Beware the CompactFlash Association feature set.
- * Now, why this value in Iconfig just walks all over the bit
- * definitions used in the other parts of the ATA/ATAPI standards
- * is a mystery and a sign of true stupidity on someone's part.
- * Anyway, the standard says if this value is 0x848A then it's
- * CompactFlash and it's NOT a packet device.
- */
- iconfig = drive->info[Iconfig];
- if(iconfig != 0x848A && (iconfig & 0xC000) == 0x8000){
- if(iconfig & 0x01)
- drive->pkt = 16;
- else
- drive->pkt = 12;
- }
- else{
- if(drive->info[Ivalid] & 0x0001){
- drive->c = drive->info[Iccyl];
- drive->h = drive->info[Ichead];
- drive->s = drive->info[Icsec];
- }else{
- drive->c = drive->info[Ilcyl];
- drive->h = drive->info[Ilhead];
- drive->s = drive->info[Ilsec];
- }
- if(drive->info[Icapabilities] & Mlba){
- if(drive->info[Icsfs+1] & Maddr48){
- drive->sectors = drive->info[Ilba48]
- | (drive->info[Ilba48+1]<<16)
- | ((vlong)drive->info[Ilba48+2]<<32);
- drive->flags |= Lba48;
- }else{
- drive->sectors = (drive->info[Ilba+1]<<16)
- |drive->info[Ilba];
- }
- drive->dev |= Lba;
- }else
- drive->sectors = drive->c*drive->h*drive->s;
- atarwmmode(drive, cmdport, ctlport, dev);
- }
- atadmamode(drive);
-
- if(DEBUG & DbgCONFIG){
- print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
- dev, cmdport, iconfig, drive->info[Icapabilities]);
- print(" mwdma %4.4uX", drive->info[Imwdma]);
- if(drive->info[Ivalid] & 0x04)
- print(" udma %4.4uX", drive->info[Iudma]);
- print(" dma %8.8uX rwm %ud\n", drive->dma, drive->rwm);
- if(drive->flags&Lba48)
- print("\tLLBA sectors %lld\n", drive->sectors);
- }
-
- return drive;
-}
-
-static void
-atasrst(int ctlport)
-{
- /*
- * Srst is a big stick and may cause problems if further
- * commands are tried before the drives become ready again.
- * Also, there will be problems here if overlapped commands
- * are ever supported.
- */
- microdelay(5);
- outb(ctlport+Dc, Srst);
- microdelay(5);
- outb(ctlport+Dc, 0);
- microdelay(2*1000);
-}
-
-static SDev*
-ataprobe(int cmdport, int ctlport, int irq)
-{
- Ctlr* ctlr;
- SDev *sdev;
- Drive *drive;
- int dev, error, rhi, rlo;
-
- if(ioalloc(cmdport, 8, 0, "atacmd") < 0) {
- print("ataprobe: Cannot allocate %X\n", cmdport);
- return nil;
- }
- if(ioalloc(ctlport+As, 1, 0, "atactl") < 0){
- print("ataprobe: Cannot allocate %X\n", ctlport + As);
- iofree(cmdport);
- return nil;
- }
-
- /*
- * Try to detect a floating bus.
- * Bsy should be cleared. If not, see if the cylinder registers
- * are read/write capable.
- * If the master fails, try the slave to catch slave-only
- * configurations.
- * There's no need to restore the tested registers as they will
- * be reset on any detected drives by the Cedd command.
- * All this indicates is that there is at least one drive on the
- * controller; when the non-existent drive is selected in a
- * single-drive configuration the registers of the existing drive
- * are often seen, only command execution fails.
- */
- dev = Dev0;
- if(inb(ctlport+As) & Bsy){
- outb(cmdport+Dh, dev);
- microdelay(1);
-trydev1:
- atadebug(cmdport, ctlport, "ataprobe bsy");
- outb(cmdport+Cyllo, 0xAA);
- outb(cmdport+Cylhi, 0x55);
- outb(cmdport+Sector, 0xFF);
- rlo = inb(cmdport+Cyllo);
- rhi = inb(cmdport+Cylhi);
- if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)){
- if(dev == Dev1){
-release:
- iofree(cmdport);
- iofree(ctlport+As);
- return nil;
- }
- dev = Dev1;
- if(ataready(cmdport, ctlport, dev, Bsy, 0, 20*1000) < 0)
- goto trydev1;
- }
- }
-
- /*
- * Disable interrupts on any detected controllers.
- */
- outb(ctlport+Dc, Nien);
-tryedd1:
- if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 105*1000) < 0){
- /*
- * There's something there, but it didn't come up clean,
- * so try hitting it with a big stick. The timing here is
- * wrong but this is a last-ditch effort and it sometimes
- * gets some marginal hardware back online.
- */
- atasrst(ctlport);
- if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 106*1000) < 0)
- goto release;
- }
-
- /*
- * Can only get here if controller is not busy.
- * If there are drives Bsy will be set within 400nS,
- * must wait 2mS before testing Status.
- * Wait for the command to complete (6 seconds max).
- */
- outb(cmdport+Command, Cedd);
- delay(2);
- if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 6*1000*1000) < 0)
- goto release;
-
- /*
- * If bit 0 of the error register is set then the selected drive
- * exists. This is enough to detect single-drive configurations.
- * However, if the master exists there is no way short of executing
- * a command to determine if a slave is present.
- * It appears possible to get here testing Dev0 although it doesn't
- * exist and the EDD won't take, so try again with Dev1.
- */
- error = inb(cmdport+Error);
- atadebug(cmdport, ctlport, "ataprobe: dev %uX", dev);
- if((error & ~0x80) != 0x01){
- if(dev == Dev1)
- goto release;
- dev = Dev1;
- goto tryedd1;
- }
-
- /*
- * At least one drive is known to exist, try to
- * identify it. If that fails, don't bother checking
- * any further.
- * If the one drive found is Dev0 and the EDD command
- * didn't indicate Dev1 doesn't exist, check for it.
- */
- if((drive = atadrive(cmdport, ctlport, dev)) == nil)
- goto release;
- if((ctlr = malloc(sizeof(Ctlr))) == nil){
- free(drive);
- goto release;
- }
- memset(ctlr, 0, sizeof(Ctlr));
- if((sdev = malloc(sizeof(SDev))) == nil){
- free(ctlr);
- free(drive);
- goto release;
- }
- memset(sdev, 0, sizeof(SDev));
- drive->ctlr = ctlr;
- if(dev == Dev0){
- ctlr->drive[0] = drive;
- if(!(error & 0x80)){
- /*
- * Always leave Dh pointing to a valid drive,
- * otherwise a subsequent call to ataready on
- * this controller may try to test a bogus Status.
- * Ataprobe is the only place possibly invalid
- * drives should be selected.
- */
- drive = atadrive(cmdport, ctlport, Dev1);
- if(drive != nil){
- drive->ctlr = ctlr;
- ctlr->drive[1] = drive;
- }
- else{
- outb(cmdport+Dh, Dev0);
- microdelay(1);
- }
- }
- }
- else
- ctlr->drive[1] = drive;
-
- ctlr->cmdport = cmdport;
- ctlr->ctlport = ctlport;
- ctlr->irq = irq;
- ctlr->tbdf = BUSUNKNOWN;
- ctlr->command = Cedd; /* debugging */
-
- sdev->ifc = &sdataifc;
- sdev->ctlr = ctlr;
- sdev->nunit = 2;
- ctlr->sdev = sdev;
-
- return sdev;
-}
-
-static void
-ataclear(SDev *sdev)
-{
- Ctlr* ctlr;
-
- ctlr = sdev->ctlr;
- iofree(ctlr->cmdport);
- iofree(ctlr->ctlport + As);
-
- if (ctlr->drive[0])
- free(ctlr->drive[0]);
- if (ctlr->drive[1])
- free(ctlr->drive[1]);
- if (sdev->name)
- free(sdev->name);
- if (sdev->unitflg)
- free(sdev->unitflg);
- if (sdev->unit)
- free(sdev->unit);
- free(ctlr);
- free(sdev);
-}
-
-static char *
-atastat(SDev *sdev, char *p, char *e)
-{
- Ctlr *ctlr = sdev->ctlr;
-
- return seprint(p, e, "%s ata port %X ctl %X irq %d\n",
- sdev->name, ctlr->cmdport, ctlr->ctlport, ctlr->irq);
-}
-
-static SDev*
-ataprobew(DevConf *cf)
-{
- if (cf->nports != 2)
- error(Ebadarg);
-
- return ataprobe(cf->ports[0].port, cf->ports[1].port, cf->intnum);
-}
-
-static int
-atasetsense(Drive* drive, int status, int key, int asc, int ascq)
-{
- drive->sense[2] = key;
- drive->sense[12] = asc;
- drive->sense[13] = ascq;
-
- return status;
-}
-
-static int
-atastandby(Drive* drive, int period)
-{
- Ctlr* ctlr;
- int cmdport, done;
-
- ctlr = drive->ctlr;
- drive->command = Cstandby;
- qlock(ctlr);
-
- cmdport = ctlr->cmdport;
- ilock(ctlr);
- outb(cmdport+Count, period);
- outb(cmdport+Dh, drive->dev);
- ctlr->done = 0;
- ctlr->curdrive = drive;
- ctlr->command = Cstandby; /* debugging */
- outb(cmdport+Command, Cstandby);
- iunlock(ctlr);
-
- while(waserror())
- ;
- tsleep(ctlr, atadone, ctlr, 30*1000);
- poperror();
-
- done = ctlr->done;
- qunlock(ctlr);
-
- if(!done || (drive->status & Err))
- return atasetsense(drive, SDcheck, 4, 8, drive->error);
- return SDok;
-}
-
-static int
-atamodesense(Drive* drive, uchar* cmd)
-{
- int len;
-
- /*
- * Fake a vendor-specific request with page code 0,
- * return the drive info.
- */
- if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
- return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
- len = (cmd[7]<<8)|cmd[8];
- if(len == 0)
- return SDok;
- if(len < 8+sizeof(drive->info))
- return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
- if(drive->data == nil || drive->dlen < len)
- return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
- memset(drive->data, 0, 8);
- drive->data[0] = sizeof(drive->info)>>8;
- drive->data[1] = sizeof(drive->info);
- memmove(drive->data+8, drive->info, sizeof(drive->info));
- drive->data += 8+sizeof(drive->info);
-
- return SDok;
-}
-
-static void
-atanop(Drive* drive, int subcommand)
-{
- Ctlr* ctlr;
- int as, cmdport, ctlport, timeo;
-
- /*
- * Attempt to abort a command by using NOP.
- * In response, the drive is supposed to set Abrt
- * in the Error register, set (Drdy|Err) in Status
- * and clear Bsy when done. However, some drives
- * (e.g. ATAPI Zip) just go Bsy then clear Status
- * when done, hence the timeout loop only on Bsy
- * and the forced setting of drive->error.
- */
- ctlr = drive->ctlr;
- cmdport = ctlr->cmdport;
- outb(cmdport+Features, subcommand);
- outb(cmdport+Dh, drive->dev);
- ctlr->command = Cnop; /* debugging */
- outb(cmdport+Command, Cnop);
-
- microdelay(1);
- ctlport = ctlr->ctlport;
- for(timeo = 0; timeo < 1000; timeo++){
- as = inb(ctlport+As);
- if(!(as & Bsy))
- break;
- microdelay(1);
- }
- drive->error |= Abrt;
-}
-
-static void
-ataabort(Drive* drive, int dolock)
-{
- /*
- * If NOP is available (packet commands) use it otherwise
- * must try a software reset.
- */
- if(dolock)
- ilock(drive->ctlr);
- if(drive->info[Icsfs] & Mnop)
- atanop(drive, 0);
- else{
- atasrst(drive->ctlr->ctlport);
- drive->error |= Abrt;
- }
- if(dolock)
- iunlock(drive->ctlr);
-}
-
-static int
-atadmasetup(Drive* drive, int len)
-{
- Prd *prd;
- ulong pa;
- Ctlr *ctlr;
- int bmiba, bmisx, count;
-
- pa = PCIWADDR(drive->data);
- if(pa & 0x03)
- return -1;
- ctlr = drive->ctlr;
- prd = ctlr->prdt;
-
- /*
- * Sometimes drives identify themselves as being DMA capable
- * although they are not on a busmastering controller.
- */
- if(prd == nil){
- drive->dmactl = 0;
- print("disabling dma: not on a busmastering controller\n");
- return -1;
- }
-
- for(;;){
- prd->pa = pa;
- count = 64*1024 - (pa & 0xFFFF);
- if(count >= len){
- prd->count = PrdEOT|(len & 0xFFFF);
- break;
- }
- prd->count = count;
- len -= count;
- pa += count;
- prd++;
- }
-
- bmiba = ctlr->bmiba;
- outl(bmiba+Bmidtpx, PCIWADDR(ctlr->prdt));
- if(drive->write)
- outb(ctlr->bmiba+Bmicx, 0);
- else
- outb(ctlr->bmiba+Bmicx, Rwcon);
- bmisx = inb(bmiba+Bmisx);
- outb(bmiba+Bmisx, bmisx|Ideints|Idedmae);
-
- return 0;
-}
-
-static void
-atadmastart(Ctlr* ctlr, int write)
-{
- if(write)
- outb(ctlr->bmiba+Bmicx, Ssbm);
- else
- outb(ctlr->bmiba+Bmicx, Rwcon|Ssbm);
-}
-
-static int
-atadmastop(Ctlr* ctlr)
-{
- int bmiba;
-
- bmiba = ctlr->bmiba;
- outb(bmiba+Bmicx, inb(bmiba+Bmicx) & ~Ssbm);
-
- return inb(bmiba+Bmisx);
-}
-
-static void
-atadmainterrupt(Drive* drive, int count)
-{
- Ctlr* ctlr;
- int bmiba, bmisx;
-
- ctlr = drive->ctlr;
- bmiba = ctlr->bmiba;
- bmisx = inb(bmiba+Bmisx);
- switch(bmisx & (Ideints|Idedmae|Bmidea)){
- case Bmidea:
- /*
- * Data transfer still in progress, nothing to do
- * (this should never happen).
- */
- return;
-
- case Ideints:
- case Ideints|Bmidea:
- /*
- * Normal termination, tidy up.
- */
- drive->data += count;
- break;
-
- default:
- /*
- * What's left are error conditions (memory transfer
- * problem) and the device is not done but the PRD is
- * exhausted. For both cases must somehow tell the
- * drive to abort.
- */
- ataabort(drive, 0);
- break;
- }
- atadmastop(ctlr);
- ctlr->done = 1;
-}
-
-static void
-atapktinterrupt(Drive* drive)
-{
- Ctlr* ctlr;
- int cmdport, len;
-
- ctlr = drive->ctlr;
- cmdport = ctlr->cmdport;
- switch(inb(cmdport+Ir) & (/*Rel|*/Io|Cd)){
- case Cd:
- outss(cmdport+Data, drive->pktcmd, drive->pkt/2);
- break;
-
- case 0:
- len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
- if(drive->data+len > drive->limit){
- atanop(drive, 0);
- break;
- }
- outss(cmdport+Data, drive->data, len/2);
- drive->data += len;
- break;
-
- case Io:
- len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
- if(drive->data+len > drive->limit){
- atanop(drive, 0);
- break;
- }
- inss(cmdport+Data, drive->data, len/2);
- drive->data += len;
- break;
-
- case Io|Cd:
- if(drive->pktdma)
- atadmainterrupt(drive, drive->dlen);
- else
- ctlr->done = 1;
- break;
- }
-}
-
-static int
-atapktio(Drive* drive, uchar* cmd, int clen)
-{
- Ctlr *ctlr;
- int as, cmdport, ctlport, len, r, timeo;
-
- if(cmd[0] == 0x5A && (cmd[2] & 0x3F) == 0)
- return atamodesense(drive, cmd);
-
- r = SDok;
-
- drive->command = Cpkt;
- memmove(drive->pktcmd, cmd, clen);
- memset(drive->pktcmd+clen, 0, drive->pkt-clen);
- drive->limit = drive->data+drive->dlen;
-
- ctlr = drive->ctlr;
- cmdport = ctlr->cmdport;
- ctlport = ctlr->ctlport;
-
- qlock(ctlr);
-
- if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 107*1000) < 0){
- qunlock(ctlr);
- return -1;
- }
-
- ilock(ctlr);
- if(drive->dlen && drive->dmactl && !atadmasetup(drive, drive->dlen))
- drive->pktdma = Dma;
- else
- drive->pktdma = 0;
-
- outb(cmdport+Features, drive->pktdma);
- outb(cmdport+Count, 0);
- outb(cmdport+Sector, 0);
- len = 16*drive->secsize;
- outb(cmdport+Bytelo, len);
- outb(cmdport+Bytehi, len>>8);
- outb(cmdport+Dh, drive->dev);
- ctlr->done = 0;
- ctlr->curdrive = drive;
- ctlr->command = Cpkt; /* debugging */
- if(drive->pktdma)
- atadmastart(ctlr, drive->write);
- outb(cmdport+Command, Cpkt);
-
- if((drive->info[Iconfig] & Mdrq) != 0x0020){
- microdelay(1);
- as = ataready(cmdport, ctlport, 0, Bsy, Drq|Chk, 4*1000);
- if(as < 0)
- r = SDtimeout;
- else if(as & Chk)
- r = SDcheck;
- else
- atapktinterrupt(drive);
- }
- iunlock(ctlr);
-
- while(waserror())
- ;
- if(!drive->pktdma)
- sleep(ctlr, atadone, ctlr);
- else for(timeo = 0; !ctlr->done; timeo++){
- tsleep(ctlr, atadone, ctlr, 1000);
- if(ctlr->done)
- break;
- ilock(ctlr);
- atadmainterrupt(drive, 0);
- if(!drive->error && timeo > 10){
- ataabort(drive, 0);
- atadmastop(ctlr);
- drive->dmactl = 0;
- drive->error |= Abrt;
- }
- if(drive->error){
- drive->status |= Chk;
- ctlr->curdrive = nil;
- }
- iunlock(ctlr);
- }
- poperror();
-
- qunlock(ctlr);
-
- if(drive->status & Chk)
- r = SDcheck;
-
- return r;
-}
-
-static uchar cmd48[256] = {
- [Crs] Crs48,
- [Crd] Crd48,
- [Crdq] Crdq48,
- [Crsm] Crsm48,
- [Cws] Cws48,
- [Cwd] Cwd48,
- [Cwdq] Cwdq48,
- [Cwsm] Cwsm48,
-};
-
-static int
-atageniostart(Drive* drive, vlong lba)
-{
- Ctlr *ctlr;
- uchar cmd;
- int as, c, cmdport, ctlport, h, len, s, use48;
-
- use48 = 0;
- if((drive->flags&Lba48always) || (lba>>28) || drive->count > 256){
- if(!(drive->flags & Lba48))
- return -1;
- use48 = 1;
- c = h = s = 0;
- }else if(drive->dev & Lba){
- c = (lba>>8) & 0xFFFF;
- h = (lba>>24) & 0x0F;
- s = lba & 0xFF;
- }else{
- c = lba/(drive->s*drive->h);
- h = ((lba/drive->s) % drive->h);
- s = (lba % drive->s) + 1;
- }
-
- ctlr = drive->ctlr;
- cmdport = ctlr->cmdport;
- ctlport = ctlr->ctlport;
- if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 101*1000) < 0)
- return -1;
-
- ilock(ctlr);
- if(drive->dmactl && !atadmasetup(drive, drive->count*drive->secsize)){
- if(drive->write)
- drive->command = Cwd;
- else
- drive->command = Crd;
- }
- else if(drive->rwmctl){
- drive->block = drive->rwm*drive->secsize;
- if(drive->write)
- drive->command = Cwsm;
- else
- drive->command = Crsm;
- }
- else{
- drive->block = drive->secsize;
- if(drive->write)
- drive->command = Cws;
- else
- drive->command = Crs;
- }
- drive->limit = drive->data + drive->count*drive->secsize;
- cmd = drive->command;
- if(use48){
- outb(cmdport+Count, (drive->count>>8) & 0xFF);
- outb(cmdport+Count, drive->count & 0XFF);
- outb(cmdport+Lbalo, (lba>>24) & 0xFF);
- outb(cmdport+Lbalo, lba & 0xFF);
- outb(cmdport+Lbamid, (lba>>32) & 0xFF);
- outb(cmdport+Lbamid, (lba>>8) & 0xFF);
- outb(cmdport+Lbahi, (lba>>40) & 0xFF);
- outb(cmdport+Lbahi, (lba>>16) & 0xFF);
- outb(cmdport+Dh, drive->dev|Lba);
- cmd = cmd48[cmd];
-
- if(DEBUG & Dbg48BIT)
- print("using 48-bit commands\n");
- }else{
- outb(cmdport+Count, drive->count);
- outb(cmdport+Sector, s);
- outb(cmdport+Cyllo, c);
- outb(cmdport+Cylhi, c>>8);
- outb(cmdport+Dh, drive->dev|h);
- }
- ctlr->done = 0;
- ctlr->curdrive = drive;
- ctlr->command = drive->command; /* debugging */
- outb(cmdport+Command, cmd);
-
- switch(drive->command){
- case Cws:
- case Cwsm:
- microdelay(1);
- as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 1000);
- if(as < 0 || (as & Err)){
- iunlock(ctlr);
- return -1;
- }
- len = drive->block;
- if(drive->data+len > drive->limit)
- len = drive->limit-drive->data;
- outss(cmdport+Data, drive->data, len/2);
- break;
-
- case Crd:
- case Cwd:
- atadmastart(ctlr, drive->write);
- break;
- }
- iunlock(ctlr);
-
- return 0;
-}
-
-static int
-atagenioretry(Drive* drive)
-{
- if(drive->dmactl){
- drive->dmactl = 0;
- print("atagenioretry: disabling dma\n");
- }
- else if(drive->rwmctl)
- drive->rwmctl = 0;
- else
- return atasetsense(drive, SDcheck, 4, 8, drive->error);
-
- return SDretry;
-}
-
-static int
-atagenio(Drive* drive, uchar* cmd, int)
-{
- uchar *p;
- Ctlr *ctlr;
- int count, max;
- vlong lba, len;
-
- /*
- * Map SCSI commands into ATA commands for discs.
- * Fail any command with a LUN except INQUIRY which
- * will return 'logical unit not supported'.
- */
- if((cmd[1]>>5) && cmd[0] != 0x12)
- return atasetsense(drive, SDcheck, 0x05, 0x25, 0);
-
- switch(cmd[0]){
- default:
- return atasetsense(drive, SDcheck, 0x05, 0x20, 0);
-
- case 0x00: /* test unit ready */
- return SDok;
-
- case 0x03: /* request sense */
- if(cmd[4] < sizeof(drive->sense))
- len = cmd[4];
- else
- len = sizeof(drive->sense);
- if(drive->data && drive->dlen >= len){
- memmove(drive->data, drive->sense, len);
- drive->data += len;
- }
- return SDok;
-
- case 0x12: /* inquiry */
- if(cmd[4] < sizeof(drive->inquiry))
- len = cmd[4];
- else
- len = sizeof(drive->inquiry);
- if(drive->data && drive->dlen >= len){
- memmove(drive->data, drive->inquiry, len);
- drive->data += len;
- }
- return SDok;
-
- case 0x1B: /* start/stop unit */
- /*
- * NOP for now, can use the power management feature
- * set later.
- */
- return SDok;
-
- case 0x25: /* read capacity */
- if((cmd[1] & 0x01) || cmd[2] || cmd[3])
- return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
- if(drive->data == nil || drive->dlen < 8)
- return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
- /*
- * Read capacity returns the LBA of the last sector.
- */
- len = drive->sectors-1;
- p = drive->data;
- *p++ = len>>24;
- *p++ = len>>16;
- *p++ = len>>8;
- *p++ = len;
- len = drive->secsize;
- *p++ = len>>24;
- *p++ = len>>16;
- *p++ = len>>8;
- *p = len;
- drive->data += 8;
- return SDok;
-
- case 0x9E: /* long read capacity */
- if((cmd[1] & 0x01) || cmd[2] || cmd[3])
- return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
- if(drive->data == nil || drive->dlen < 8)
- return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
- /*
- * Read capacity returns the LBA of the last sector.
- */
- len = drive->sectors-1;
- p = drive->data;
- *p++ = len>>56;
- *p++ = len>>48;
- *p++ = len>>40;
- *p++ = len>>32;
- *p++ = len>>24;
- *p++ = len>>16;
- *p++ = len>>8;
- *p++ = len;
- len = drive->secsize;
- *p++ = len>>24;
- *p++ = len>>16;
- *p++ = len>>8;
- *p = len;
- drive->data += 8;
- return SDok;
-
- case 0x28: /* read */
- case 0x2A: /* write */
- break;
-
- case 0x5A:
- return atamodesense(drive, cmd);
- }
-
- ctlr = drive->ctlr;
- lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
- count = (cmd[7]<<8)|cmd[8];
- if(drive->data == nil)
- return SDok;
- if(drive->dlen < count*drive->secsize)
- count = drive->dlen/drive->secsize;
- qlock(ctlr);
- while(count){
- max = (drive->flags&Lba48) ? 65536 : 256;
- if(count > max)
- drive->count = max;
- else
- drive->count = count;
- if(atageniostart(drive, lba)){
- ilock(ctlr);
- atanop(drive, 0);
- iunlock(ctlr);
- qunlock(ctlr);
- return atagenioretry(drive);
- }
-
- while(waserror())
- ;
- tsleep(ctlr, atadone, ctlr, 30*1000);
- poperror();
- if(!ctlr->done){
- /*
- * What should the above timeout be? In
- * standby and sleep modes it could take as
- * long as 30 seconds for a drive to respond.
- * Very hard to get out of this cleanly.
- */
- atadumpstate(drive, cmd, lba, count);
- ataabort(drive, 1);
- qunlock(ctlr);
- return atagenioretry(drive);
- }
-
- if(drive->status & Err){
- qunlock(ctlr);
- return atasetsense(drive, SDcheck, 4, 8, drive->error);
- }
- count -= drive->count;
- lba += drive->count;
- }
- qunlock(ctlr);
-
- return SDok;
-}
-
-static int
-atario(SDreq* r)
-{
- Ctlr *ctlr;
- Drive *drive;
- SDunit *unit;
- uchar cmd10[10], *cmdp, *p;
- int clen, reqstatus, status;
-
- unit = r->unit;
- if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil){
- r->status = SDtimeout;
- return SDtimeout;
- }
- drive = ctlr->drive[unit->subno];
-
- /*
- * Most SCSI commands can be passed unchanged except for
- * the padding on the end. The few which require munging
- * are not used internally. Mode select/sense(6) could be
- * converted to the 10-byte form but it's not worth the
- * effort. Read/write(6) are easy.
- */
- switch(r->cmd[0]){
- case 0x08: /* read */
- case 0x0A: /* write */
- cmdp = cmd10;
- memset(cmdp, 0, sizeof(cmd10));
- cmdp[0] = r->cmd[0]|0x20;
- cmdp[1] = r->cmd[1] & 0xE0;
- cmdp[5] = r->cmd[3];
- cmdp[4] = r->cmd[2];
- cmdp[3] = r->cmd[1] & 0x0F;
- cmdp[8] = r->cmd[4];
- clen = sizeof(cmd10);
- break;
-
- default:
- cmdp = r->cmd;
- clen = r->clen;
- break;
- }
-
- qlock(drive);
-retry:
- drive->write = r->write;
- drive->data = r->data;
- drive->dlen = r->dlen;
-
- drive->status = 0;
- drive->error = 0;
- if(drive->pkt)
- status = atapktio(drive, cmdp, clen);
- else
- status = atagenio(drive, cmdp, clen);
- if(status == SDretry){
- if(DbgDEBUG)
- print("%s: retry: dma %8.8uX rwm %4.4uX\n",
- unit->name, drive->dmactl, drive->rwmctl);
- goto retry;
- }
- if(status == SDok){
- atasetsense(drive, SDok, 0, 0, 0);
- if(drive->data){
- p = r->data;
- r->rlen = drive->data - p;
- }
- else
- r->rlen = 0;
- }
- else if(status == SDcheck && !(r->flags & SDnosense)){
- drive->write = 0;
- memset(cmd10, 0, sizeof(cmd10));
- cmd10[0] = 0x03;
- cmd10[1] = r->lun<<5;
- cmd10[4] = sizeof(r->sense)-1;
- drive->data = r->sense;
- drive->dlen = sizeof(r->sense)-1;
- drive->status = 0;
- drive->error = 0;
- if(drive->pkt)
- reqstatus = atapktio(drive, cmd10, 6);
- else
- reqstatus = atagenio(drive, cmd10, 6);
- if(reqstatus == SDok){
- r->flags |= SDvalidsense;
- atasetsense(drive, SDok, 0, 0, 0);
- }
- }
- qunlock(drive);
- r->status = status;
- if(status != SDok)
- return status;
-
- /*
- * Fix up any results.
- * Many ATAPI CD-ROMs ignore the LUN field completely and
- * return valid INQUIRY data. Patch the response to indicate
- * 'logical unit not supported' if the LUN is non-zero.
- */
- switch(cmdp[0]){
- case 0x12: /* inquiry */
- if((p = r->data) == nil)
- break;
- if((cmdp[1]>>5) && (!drive->pkt || (p[0] & 0x1F) == 0x05))
- p[0] = 0x7F;
- /*FALLTHROUGH*/
- default:
- break;
- }
-
- return SDok;
-}
-
-static void
-atainterrupt(Ureg*, void* arg)
-{
- Ctlr *ctlr;
- Drive *drive;
- int cmdport, len, status;
-
- ctlr = arg;
-
- ilock(ctlr);
- if(inb(ctlr->ctlport+As) & Bsy){
- iunlock(ctlr);
- if(DEBUG & DbgBsy)
- print("IBsy+");
- return;
- }
- cmdport = ctlr->cmdport;
- status = inb(cmdport+Status);
- if((drive = ctlr->curdrive) == nil){
- iunlock(ctlr);
- if((DEBUG & DbgINL) && ctlr->command != Cedd)
- print("Inil%2.2uX+", ctlr->command);
- return;
- }
-
- if(status & Err)
- drive->error = inb(cmdport+Error);
- else switch(drive->command){
- default:
- drive->error = Abrt;
- break;
-
- case Crs:
- case Crsm:
- if(!(status & Drq)){
- drive->error = Abrt;
- break;
- }
- len = drive->block;
- if(drive->data+len > drive->limit)
- len = drive->limit-drive->data;
- inss(cmdport+Data, drive->data, len/2);
- drive->data += len;
- if(drive->data >= drive->limit)
- ctlr->done = 1;
- break;
-
- case Cws:
- case Cwsm:
- len = drive->block;
- if(drive->data+len > drive->limit)
- len = drive->limit-drive->data;
- drive->data += len;
- if(drive->data >= drive->limit){
- ctlr->done = 1;
- break;
- }
- if(!(status & Drq)){
- drive->error = Abrt;
- break;
- }
- len = drive->block;
- if(drive->data+len > drive->limit)
- len = drive->limit-drive->data;
- outss(cmdport+Data, drive->data, len/2);
- break;
-
- case Cpkt:
- atapktinterrupt(drive);
- break;
-
- case Crd:
- case Cwd:
- atadmainterrupt(drive, drive->count*drive->secsize);
- break;
-
- case Cstandby:
- ctlr->done = 1;
- break;
- }
- iunlock(ctlr);
-
- if(drive->error){
- status |= Err;
- ctlr->done = 1;
- }
-
- if(ctlr->done){
- ctlr->curdrive = nil;
- drive->status = status;
- wakeup(ctlr);
- }
-}
-
-static SDev*
-atapnp(void)
-{
- Ctlr *ctlr;
- Pcidev *p;
- int channel, ispc87415, pi, r;
- SDev *legacy[2], *sdev, *head, *tail;
-
- legacy[0] = legacy[1] = head = tail = nil;
- if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
- head = tail = sdev;
- legacy[0] = sdev;
- }
- if(sdev = ataprobe(0x170, 0x374, IrqATA1)){
- if(head != nil)
- tail->next = sdev;
- else
- head = sdev;
- tail = sdev;
- legacy[1] = sdev;
- }
-
- p = nil;
- while(p = pcimatch(p, 0, 0)){
- /*
- * Look for devices with the correct class and sub-class
- * code and known device and vendor ID; add native-mode
- * channels to the list to be probed, save info for the
- * compatibility mode channels.
- * Note that the legacy devices should not be considered
- * PCI devices by the interrupt controller.
- * For both native and legacy, save info for busmastering
- * if capable.
- * Promise Ultra ATA/66 (PDC20262) appears to
- * 1) give a sub-class of 'other mass storage controller'
- * instead of 'IDE controller', regardless of whether it's
- * the only controller or not;
- * 2) put 0 in the programming interface byte (probably
- * as a consequence of 1) above).
- * Sub-class code 0x04 is 'RAID controller', e.g. VIA VT8237.
- */
- if(p->ccrb != 0x01)
- continue;
- if(p->ccru != 0x01 && p->ccru != 0x04 && p->ccru != 0x80)
- continue;
- pi = p->ccrp;
- ispc87415 = 0;
-
- switch((p->did<<16)|p->vid){
- default:
- continue;
-
- case (0x0002<<16)|0x100B: /* NS PC87415 */
- /*
- * Disable interrupts on both channels until
- * after they are probed for drives.
- * This must be called before interrupts are
- * enabled because the IRQ may be shared.
- */
- ispc87415 = 1;
- pcicfgw32(p, 0x40, 0x00000300);
- break;
- case (0x1000<<16)|0x1042: /* PC-Tech RZ1000 */
- /*
- * Turn off prefetch. Overkill, but cheap.
- */
- r = pcicfgr32(p, 0x40);
- r &= ~0x2000;
- pcicfgw32(p, 0x40, r);
- break;
- case (0x4D38<<16)|0x105A: /* Promise PDC20262 */
- case (0x4D30<<16)|0x105A: /* Promise PDC202xx */
- case (0x4D68<<16)|0x105A: /* Promise PDC20268 */
- case (0x3373<<16)|0x105A: /* Promise 20378 RAID */
- case (0x3149<<16)|0x1106: /* VIA VT8237 SATA/RAID */
- pi = 0x85;
- break;
- case (0x0004<<16)|0x1103: /* HighPoint HPT-370 */
- pi = 0x85;
- /*
- * Turn off fast interrupt prediction.
- */
- if((r = pcicfgr8(p, 0x51)) & 0x80)
- pcicfgw8(p, 0x51, r & ~0x80);
- if((r = pcicfgr8(p, 0x55)) & 0x80)
- pcicfgw8(p, 0x55, r & ~0x80);
- break;
- case (0x0640<<16)|0x1095: /* CMD 640B */
- /*
- * Bugfix code here...
- */
- break;
- case (0x7441<<16)|0x1022: /* AMD 768 */
- /*
- * Set:
- * 0x41 prefetch, postwrite;
- * 0x43 FIFO configuration 1/2 and 1/2;
- * 0x44 status register read retry;
- * 0x46 DMA read and end of sector flush.
- */
- r = pcicfgr8(p, 0x41);
- pcicfgw8(p, 0x41, r|0xF0);
- r = pcicfgr8(p, 0x43);
- pcicfgw8(p, 0x43, (r & 0x90)|0x2A);
- r = pcicfgr8(p, 0x44);
- pcicfgw8(p, 0x44, r|0x08);
- r = pcicfgr8(p, 0x46);
- pcicfgw8(p, 0x46, (r & 0x0C)|0xF0);
- break;
- case (0x0646<<16)|0x1095: /* CMD 646 */
- case (0x0571<<16)|0x1106: /* VIA 82C686 */
- case (0x0211<<16)|0x1166: /* ServerWorks IB6566 */
- case (0x1230<<16)|0x8086: /* 82371FB (PIIX) */
- case (0x7010<<16)|0x8086: /* 82371SB (PIIX3) */
- case (0x7111<<16)|0x8086: /* 82371[AE]B (PIIX4[E]) */
- case (0x2411<<16)|0x8086: /* 82801AA (ICH) */
- case (0x2421<<16)|0x8086: /* 82801AB (ICH0) */
- case (0x244A<<16)|0x8086: /* 82801BA (ICH2, Mobile) */
- case (0x244B<<16)|0x8086: /* 82801BA (ICH2, High-End) */
- case (0x248A<<16)|0x8086: /* 82801CA (ICH3, Mobile) */
- case (0x248B<<16)|0x8086: /* 82801CA (ICH3, High-End) */
- case (0x24CA<<16)|0x8086: /* 82801DBM (ICH4, Mobile) */
- case (0x24CB<<16)|0x8086: /* 82801DB (ICH4, High-End) */
- case (0x24DB<<16)|0x8086: /* 82801EB (ICH5) */
- break;
- }
-
- for(channel = 0; channel < 2; channel++){
- if(pi & (1<<(2*channel))){
- sdev = ataprobe(p->mem[0+2*channel].bar & ~0x01,
- p->mem[1+2*channel].bar & ~0x01,
- p->intl);
- if(sdev == nil)
- continue;
-
- ctlr = sdev->ctlr;
- if(ispc87415) {
- ctlr->ienable = pc87415ienable;
- print("pc87415disable: not yet implemented\n");
- }
-
- if(head != nil)
- tail->next = sdev;
- else
- head = sdev;
- tail = sdev;
- ctlr->tbdf = p->tbdf;
- }
- else if((sdev = legacy[channel]) == nil)
- continue;
- else
- ctlr = sdev->ctlr;
-
- ctlr->pcidev = p;
- if(!(pi & 0x80))
- continue;
- ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
- }
- }
-
-if(0){
- int port;
- ISAConf isa;
-
- /*
- * Hack for PCMCIA drives.
- * This will be tidied once we figure out how the whole
- * removeable device thing is going to work.
- */
- memset(&isa, 0, sizeof(isa));
- isa.port = 0x180; /* change this for your machine */
- isa.irq = 11; /* change this for your machine */
-
- port = isa.port+0x0C;
- channel = pcmspecial("MK2001MPL", &isa);
- if(channel == -1)
- channel = pcmspecial("SunDisk", &isa);
- if(channel == -1){
- isa.irq = 10;
- channel = pcmspecial("CF", &isa);
- }
- if(channel == -1){
- isa.irq = 10;
- channel = pcmspecial("OLYMPUS", &isa);
- }
- if(channel == -1){
- port = isa.port+0x204;
- channel = pcmspecial("ATA/ATAPI", &isa);
- }
- if(channel >= 0 && (sdev = ataprobe(isa.port, port, isa.irq)) != nil){
- if(head != nil)
- tail->next = sdev;
- else
- head = sdev;
- }
-}
- return head;
-}
-
-static SDev*
-atalegacy(int port, int irq)
-{
- return ataprobe(port, port+0x204, irq);
-}
-
-static SDev*
-ataid(SDev* sdev)
-{
- int i;
- Ctlr *ctlr;
- char name[32];
-
- /*
- * Legacy controllers are always 'C' and 'D' and if
- * they exist and have drives will be first in the list.
- * If there are no active legacy controllers, native
- * controllers start at 'C'.
- */
- if(sdev == nil)
- return nil;
- ctlr = sdev->ctlr;
- if(ctlr->cmdport == 0x1F0 || ctlr->cmdport == 0x170)
- i = 2;
- else
- i = 0;
- while(sdev){
- if(sdev->ifc == &sdataifc){
- ctlr = sdev->ctlr;
- if(ctlr->cmdport == 0x1F0)
- sdev->idno = 'C';
- else if(ctlr->cmdport == 0x170)
- sdev->idno = 'D';
- else{
- sdev->idno = 'C'+i;
- i++;
- }
- snprint(name, sizeof(name), "sd%c", sdev->idno);
- kstrdup(&sdev->name, name);
- }
- sdev = sdev->next;
- }
-
- return nil;
-}
-
-static int
-ataenable(SDev* sdev)
-{
- Ctlr *ctlr;
- char name[32];
-
- ctlr = sdev->ctlr;
-
- if(ctlr->bmiba){
-#define ALIGN (4 * 1024)
- if(ctlr->pcidev != nil)
- pcisetbme(ctlr->pcidev);
- // ctlr->prdt = xspanalloc(Nprd*sizeof(Prd), 4, 4*1024);
- ctlr->prdtbase = xalloc(Nprd * sizeof(Prd) + ALIGN);
- ctlr->prdt = (Prd *)(((ulong)ctlr->prdtbase + ALIGN) & ~(ALIGN - 1));
- }
- snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
- intrenable(ctlr->irq, atainterrupt, ctlr, ctlr->tbdf, name);
- outb(ctlr->ctlport+Dc, 0);
- if(ctlr->ienable)
- ctlr->ienable(ctlr);
-
- return 1;
-}
-
-static int
-atadisable(SDev *sdev)
-{
- Ctlr *ctlr;
- char name[32];
-
- ctlr = sdev->ctlr;
- outb(ctlr->ctlport+Dc, Nien); /* disable interrupts */
- if (ctlr->idisable)
- ctlr->idisable(ctlr);
- snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
- intrdisable(ctlr->irq, atainterrupt, ctlr, ctlr->tbdf, name);
- if (ctlr->bmiba) {
- if (ctlr->pcidev)
- pciclrbme(ctlr->pcidev);
- xfree(ctlr->prdtbase);
- }
- return 0;
-}
-
-static int
-atarctl(SDunit* unit, char* p, int l)
-{
- int n;
- Ctlr *ctlr;
- Drive *drive;
-
- if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
- return 0;
- drive = ctlr->drive[unit->subno];
-
- qlock(drive);
- n = snprint(p, l, "config %4.4uX capabilities %4.4uX",
- drive->info[Iconfig], drive->info[Icapabilities]);
- if(drive->dma)
- n += snprint(p+n, l-n, " dma %8.8uX dmactl %8.8uX",
- drive->dma, drive->dmactl);
- if(drive->rwm)
- n += snprint(p+n, l-n, " rwm %ud rwmctl %ud",
- drive->rwm, drive->rwmctl);
- if(drive->flags&Lba48)
- n += snprint(p+n, l-n, " lba48always %s",
- (drive->flags&Lba48always) ? "on" : "off");
- n += snprint(p+n, l-n, "\n");
- if(drive->sectors){
- n += snprint(p+n, l-n, "geometry %lld %d",
- drive->sectors, drive->secsize);
- if(drive->pkt == 0)
- n += snprint(p+n, l-n, " %d %d %d",
- drive->c, drive->h, drive->s);
- n += snprint(p+n, l-n, "\n");
- }
- qunlock(drive);
-
- return n;
-}
-
-static int
-atawctl(SDunit* unit, Cmdbuf* cb)
-{
- int period;
- Ctlr *ctlr;
- Drive *drive;
-
- if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
- return 0;
- drive = ctlr->drive[unit->subno];
-
- qlock(drive);
- if(waserror()){
- qunlock(drive);
- nexterror();
- }
-
- /*
- * Dma and rwm control is passive at the moment,
- * i.e. it is assumed that the hardware is set up
- * correctly already either by the BIOS or when
- * the drive was initially identified.
- */
- if(strcmp(cb->f[0], "dma") == 0){
- if(cb->nf != 2 || drive->dma == 0)
- error(Ebadctl);
- if(strcmp(cb->f[1], "on") == 0)
- drive->dmactl = drive->dma;
- else if(strcmp(cb->f[1], "off") == 0)
- drive->dmactl = 0;
- else
- error(Ebadctl);
- }
- else if(strcmp(cb->f[0], "rwm") == 0){
- if(cb->nf != 2 || drive->rwm == 0)
- error(Ebadctl);
- if(strcmp(cb->f[1], "on") == 0)
- drive->rwmctl = drive->rwm;
- else if(strcmp(cb->f[1], "off") == 0)
- drive->rwmctl = 0;
- else
- error(Ebadctl);
- }
- else if(strcmp(cb->f[0], "standby") == 0){
- switch(cb->nf){
- default:
- error(Ebadctl);
- case 2:
- period = strtol(cb->f[1], 0, 0);
- if(period && (period < 30 || period > 240*5))
- error(Ebadctl);
- period /= 5;
- break;
- }
- if(atastandby(drive, period) != SDok)
- error(Ebadctl);
- }
- else if(strcmp(cb->f[0], "lba48always") == 0){
- if(cb->nf != 2 || !(drive->flags&Lba48))
- error(Ebadctl);
- if(strcmp(cb->f[1], "on") == 0)
- drive->flags |= Lba48always;
- else if(strcmp(cb->f[1], "off") == 0)
- drive->flags &= ~Lba48always;
- else
- error(Ebadctl);
- }
- else
- error(Ebadctl);
- qunlock(drive);
- poperror();
-
- return 0;
-}
-
-SDifc sdataifc = {
- "ata", /* name */
-
- atapnp, /* pnp */
- atalegacy, /* legacy */
- ataid, /* id */
- ataenable, /* enable */
- atadisable, /* disable */
-
- scsiverify, /* verify */
- scsionline, /* online */
- atario, /* rio */
- atarctl, /* rctl */
- atawctl, /* wctl */
-
- scsibio, /* bio */
- ataprobew, /* probe */
- ataclear, /* clear */
- atastat, /* stat */
-};
diff --git a/os/pc/sdmylex.c b/os/pc/sdmylex.c
deleted file mode 100644
index cb132991..00000000
--- a/os/pc/sdmylex.c
+++ /dev/null
@@ -1,1249 +0,0 @@
-/*
- * Mylex MultiMaster (Buslogic BT-*) SCSI Host Adapter
- * in both 24-bit and 32-bit mode.
- * 24-bit mode works for Adaptec AHA-154xx series too.
- *
- * To do:
- * allocate more Ccb's as needed, up to NMbox-1;
- * add nmbox and nccb to Ctlr struct for the above;
- * 64-bit LUN/explicit wide support necessary?
- *
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-#include "../port/sd.h"
-
-#define K2BPA(va, tbdf) PADDR(va)
-#define BPA2K(pa, tbdf) KADDR(pa)
-
-extern SDifc sdmylexifc;
-
-enum { /* registers */
- Rcontrol = 0x00, /* WO: control register */
- Rstatus = 0x00, /* RO: status register */
- Rcpr = 0x01, /* WO: command/parameter register */
- Rdatain = 0x01, /* RO: data-in register */
- Rinterrupt = 0x02, /* RO: interrupt register */
-};
-
-enum { /* Rcontrol */
- Rsbus = 0x10, /* SCSI Bus Reset */
- Rint = 0x20, /* Interrupt Reset */
- Rsoft = 0x40, /* Soft Reset */
- Rhard = 0x80, /* Hard Reset */
-};
-
-enum { /* Rstatus */
- Cmdinv = 0x01, /* Command Invalid */
- Dirrdy = 0x04, /* Data In Register Ready */
- Cprbsy = 0x08, /* Command/Parameter Register Busy */
- Hardy = 0x10, /* Host Adapter Ready */
- Inreq = 0x20, /* Initialisation Required */
- Dfail = 0x40, /* Diagnostic Failure */
- Dact = 0x80, /* Diagnostic Active */
-};
-
-enum { /* Rcpr */
- Cinitialise = 0x01, /* Initialise Mailbox */
- Cstart = 0x02, /* Start Mailbox Command */
- Cinquiry = 0x04, /* Adapter Inquiry */
- Ceombri = 0x05, /* Enable OMBR Interrupt */
- Cinquire = 0x0B, /* Inquire Configuration */
- Cextbios = 0x28, /* AHA-1542: extended BIOS info. */
- Cmbienable = 0x29, /* AHA-1542: Mailbox interface enable */
- Ciem = 0x81, /* Initialise Extended Mailbox */
- Ciesi = 0x8D, /* Inquire Extended Setup Information */
- Cerrm = 0x8F, /* Enable strict round-robin mode */
- Cwide = 0x96, /* Wide CCB */
-};
-
-enum { /* Rinterrupt */
- Imbl = 0x01, /* Incoming Mailbox Loaded */
- Mbor = 0x02, /* Mailbox Out Ready */
- Cmdc = 0x04, /* Command Complete */
- Rsts = 0x08, /* SCSI Reset State */
- Intv = 0x80, /* Interrupt Valid */
-};
-
-typedef struct Mbox24 Mbox24;
-struct Mbox24 {
- uchar code; /* action/completion code */
- uchar ccb[3]; /* CCB pointer (MSB, ..., LSB) */
-};
-
-typedef struct Mbox32 Mbox32;
-struct Mbox32 {
- uchar ccb[4]; /* CCB pointer (LSB, ..., MSB) */
- uchar btstat; /* BT-7[45]7[SD] status */
- uchar sdstat; /* SCSI device status */
- uchar pad;
- uchar code; /* action/completion code */
-};
-
-enum { /* mailbox commands */
- Mbfree = 0x00, /* Mailbox not in use */
-
- Mbostart = 0x01, /* Start a mailbox command */
- Mboabort = 0x02, /* Abort a mailbox command */
-
- Mbiok = 0x01, /* CCB completed without error */
- Mbiabort = 0x02, /* CCB aborted at request of host */
- Mbinx = 0x03, /* Aborted CCB not found */
- Mbierror = 0x04, /* CCB completed with error */
-};
-
-typedef struct Ccb24 Ccb24;
-typedef struct Ccb32 Ccb32;
-typedef union Ccb Ccb;
-
-typedef struct Ccb24 {
- uchar opcode; /* Operation code */
- uchar datadir; /* Data direction control */
- uchar cdblen; /* Length of CDB */
- uchar senselen; /* Length of sense area */
- uchar datalen[3]; /* Data length (MSB, ..., LSB) */
- uchar dataptr[3]; /* Data pointer (MSB, ..., LSB) */
- uchar linkptr[3]; /* Link pointer (MSB, ..., LSB) */
- uchar linkid; /* command linking identifier */
- uchar btstat; /* BT-* adapter status */
- uchar sdstat; /* SCSI device status */
- uchar reserved[2]; /* */
- uchar cs[12+0xFF]; /* Command descriptor block + Sense */
-
- void* data; /* buffer if address > 24-bits */
-
- Rendez;
- int done; /* command completed */
-
- Ccb* ccb; /* link on free list */
-} Ccb24;
-
-
-typedef struct Ccb32 {
- uchar opcode; /* Operation code */
- uchar datadir; /* Data direction control */
- uchar cdblen; /* Length of CDB */
- uchar senselen; /* Length of sense area */
- uchar datalen[4]; /* Data length (LSB, ..., MSB) */
- uchar dataptr[4]; /* Data pointer (LSB, ..., MSB) */
- uchar reserved[2];
- uchar btstat; /* BT-* adapter status */
- uchar sdstat; /* SCSI device status */
- uchar targetid; /* Target ID */
- uchar luntag; /* LUN & tag */
- uchar cdb[12]; /* Command descriptor block */
- uchar ccbctl; /* CCB control */
- uchar linkid; /* command linking identifier */
- uchar linkptr[4]; /* Link pointer (LSB, ..., MSB) */
- uchar senseptr[4]; /* Sense pointer (LSB, ..., MSB) */
- uchar sense[0xFF]; /* Sense bytes */
-
- Rendez;
- int done; /* command completed */
-
- Ccb* ccb; /* link on free list */
-} Ccb32;
-
-typedef union Ccb {
- Ccb24;
- Ccb32;
-} Ccb;
-
-enum { /* opcode */
- OInitiator = 0x00, /* initiator CCB */
- Ordl = 0x03, /* initiator CCB with
- * residual data length returned
- */
-};
-
-enum { /* datadir */
- CCBdatain = 0x08, /* inbound, length is checked */
- CCBdataout = 0x10, /* outbound, length is checked */
-};
-
-enum { /* btstat */
- Eok = 0x00, /* normal completion with no errors */
-};
-
-enum { /* luntag */
- TagEnable = 0x20, /* Tag enable */
- SQTag = 0x00, /* Simple Queue Tag */
- HQTag = 0x40, /* Head of Queue Tag */
- OQTag = 0x80, /* Ordered Queue Tag */
-};
-
-enum { /* CCB control */
- NoDisc = 0x08, /* No disconnect */
- NoUnd = 0x10, /* No underrrun error report */
- NoData = 0x20, /* No data transfer */
- NoStat = 0x40, /* No CCB status if zero */
- NoIntr = 0x80, /* No Interrupts */
-};
-
-typedef struct Ctlr Ctlr;
-struct Ctlr {
- int port; /* I/O port */
- int id; /* adapter SCSI id */
- int bus; /* 24 or 32 -bit */
- int irq;
- int wide;
- Pcidev* pcidev;
- SDev* sdev;
- int spurious;
-
- Lock issuelock;
-
- Lock ccblock;
- QLock ccbq;
- Rendez ccbr;
-
- Lock mboxlock;
- void* mb; /* mailbox out + mailbox in */
- int mbox; /* current mailbox out index into mb */
- int mbix; /* current mailbox in index into mb */
-
- Lock cachelock;
- Ccb* ccb; /* list of free Ccb's */
- Ccb** cache; /* last completed Ccb */
-};
-
-/*
- * The number of mailboxes should be a multiple of 8 (4 for Mbox32)
- * to ensure the boundary between the out and in mailboxes doesn't
- * straddle a cache-line boundary.
- * The number of Ccb's should be less than the number of mailboxes to
- * ensure no queueing is necessary on mailbox allocation.
- */
-enum {
- NMbox = 8*8, /* number of Mbox's */
- NCcb = NMbox-1, /* number of Ccb's */
-};
-
-#define PADDR24(a, n) ((PADDR(a)+(n)) <= (1<<24))
-
-static void
-ccbfree(Ctlr* ctlr, Ccb* ccb)
-{
- lock(&ctlr->ccblock);
- if(ctlr->bus == 24)
- ((Ccb24*)ccb)->ccb = ctlr->ccb;
- else
- ((Ccb32*)ccb)->ccb = ctlr->ccb;
- if(ctlr->ccb == nil)
- wakeup(&ctlr->ccbr);
- ctlr->ccb = ccb;
- unlock(&ctlr->ccblock);
-}
-
-static int
-ccbavailable(void* a)
-{
- return ((Ctlr*)a)->ccb != nil;
-}
-
-static Ccb*
-ccballoc(Ctlr* ctlr)
-{
- Ccb *ccb;
-
- for(;;){
- lock(&ctlr->ccblock);
- if((ccb = ctlr->ccb) != nil){
- if(ctlr->bus == 24)
- ctlr->ccb = ((Ccb24*)ccb)->ccb;
- else
- ctlr->ccb = ((Ccb32*)ccb)->ccb;
- unlock(&ctlr->ccblock);
- break;
- }
-
- unlock(&ctlr->ccblock);
- qlock(&ctlr->ccbq);
- if(waserror()){
- qunlock(&ctlr->ccbq);
- continue;
- }
- sleep(&ctlr->ccbr, ccbavailable, ctlr);
- qunlock(&ctlr->ccbq);
- poperror();
- }
-
- return ccb;
-}
-
-static int
-done24(void* arg)
-{
- return ((Ccb24*)arg)->done;
-}
-
-static int
-mylex24rio(SDreq* r)
-{
- ulong p;
- Ctlr *ctlr;
- Ccb24 *ccb;
- Mbox24 *mb;
- uchar *data, lun, *sense;
- int d, n, btstat, sdstat, target;
-
- ctlr = r->unit->dev->ctlr;
- target = r->unit->subno;
- lun = (r->cmd[1]>>5) & 0x07;
-
- /*
- * Ctlr->cache holds the last completed Ccb for this target if it
- * returned 'check condition'.
- * If this command is a request-sense and there is valid sense data
- * from the last completed Ccb, return it immediately.
- */
- lock(&ctlr->cachelock);
- if((ccb = ctlr->cache[target]) != nil){
- ctlr->cache[target] = nil;
- if(r->cmd[0] == 0x03
- && ccb->sdstat == SDcheck && lun == ((ccb->cs[1]>>5) & 0x07)){
- unlock(&ctlr->cachelock);
- if(r->dlen){
- sense = &ccb->cs[ccb->cdblen];
- n = 8+sense[7];
- if(n > r->dlen)
- n = r->dlen;
- memmove(r->data, sense, n);
- r->rlen = n;
- }
- ccbfree(ctlr, (Ccb*)ccb);
- return SDok;
- }
- }
- unlock(&ctlr->cachelock);
- if(ccb == nil)
- ccb = ccballoc(ctlr);
-
- /*
- * Check if the transfer is to memory above the 24-bit limit the
- * controller can address. If it is, try to allocate a temporary
- * buffer as a staging area.
- */
- n = r->dlen;
- if(n && !PADDR24(r->data, n)){
- data = mallocz(n, 0);
- if(data == nil || !PADDR24(data, n)){
- if(data != nil){
- free(data);
- ccb->data = nil;
- }
- ccbfree(ctlr, (Ccb*)ccb);
- return SDmalloc;
- }
- if(r->write)
- memmove(data, r->data, n);
- ccb->data = r->data;
- }
- else
- data = r->data;
-
- /*
- * Fill in the ccb.
- */
- ccb->opcode = Ordl;
-
- ccb->datadir = (target<<5)|lun;
- if(n == 0)
- ccb->datadir |= CCBdataout|CCBdatain;
- else if(!r->write)
- ccb->datadir |= CCBdatain;
- else
- ccb->datadir |= CCBdataout;
-
- ccb->cdblen = r->clen;
- ccb->senselen = 0xFF;
-
- ccb->datalen[0] = n>>16;
- ccb->datalen[1] = n>>8;
- ccb->datalen[2] = n;
- p = PADDR(data);
- ccb->dataptr[0] = p>>16;
- ccb->dataptr[1] = p>>8;
- ccb->dataptr[2] = p;
-
- ccb->linkptr[0] = ccb->linkptr[1] = ccb->linkptr[2] = 0;
- ccb->linkid = 0;
- ccb->btstat = ccb->sdstat = 0;
- ccb->reserved[0] = ccb->reserved[1] = 0;
-
- memmove(ccb->cs, r->cmd, r->clen);
-
- /*
- * There's one more mbox than there there is
- * ccb so there is always one free.
- */
- lock(&ctlr->mboxlock);
- mb = ctlr->mb;
- mb += ctlr->mbox;
- p = PADDR(ccb);
- mb->ccb[0] = p>>16;
- mb->ccb[1] = p>>8;
- mb->ccb[2] = p;
- mb->code = Mbostart;
- ctlr->mbox++;
- if(ctlr->mbox >= NMbox)
- ctlr->mbox = 0;
-
- /*
- * This command does not require Hardy
- * and doesn't generate a Cmdc interrupt.
- */
- ccb->done = 0;
- outb(ctlr->port+Rcpr, Cstart);
- unlock(&ctlr->mboxlock);
-
- /*
- * Wait for the request to complete and return the status.
- * Since the buffer is not reference counted cannot return
- * until the DMA is done writing into the buffer so the caller
- * cannot free the buffer prematurely.
- */
- while(waserror())
- ;
- sleep(ccb, done24, ccb);
- poperror();
-
- /*
- * Save the status and patch up the number of
- * bytes actually transferred.
- * There's a firmware bug on some 956C controllers
- * which causes the return count from a successful
- * READ CAPACITY not be updated, so fix it here.
- */
- sdstat = ccb->sdstat;
- btstat = ccb->btstat;
-
- d = ccb->datalen[0]<<16;
- d |= ccb->datalen[1]<<8;
- d |= ccb->datalen[2];
- if(ccb->cs[0] == 0x25 && sdstat == SDok)
- d = 0;
- n -= d;
- r->rlen = n;
-
- /*
- * Tidy things up if a staging area was used for the data,
- */
- if(ccb->data != nil){
- if(sdstat == SDok && btstat == 0 && !r->write)
- memmove(ccb->data, data, n);
- free(data);
- ccb->data = nil;
- }
-
- /*
- * If there was a check-condition, save the
- * ccb for a possible request-sense command.
- */
- if(sdstat == SDcheck){
- if(r->flags & SDnosense){
- lock(&ctlr->cachelock);
- if(ctlr->cache[target])
- ccbfree(ctlr, ctlr->cache[target]);
- ctlr->cache[target] = (Ccb*)ccb;
- unlock(&ctlr->cachelock);
- return SDcheck;
- }
- sense = &ccb->cs[ccb->cdblen];
- n = 8+sense[7];
- if(n > sizeof(r->sense)-1)
- n = sizeof(r->sense)-1;
- memmove(r->sense, sense, n);
- r->flags |= SDvalidsense;
- }
- ccbfree(ctlr, (Ccb*)ccb);
-
- if(btstat){
- if(btstat == 0x11)
- return SDtimeout;
- return SDeio;
- }
- return sdstat;
-}
-
-static void
-mylex24interrupt(Ureg*, void* arg)
-{
- ulong pa;
- Ctlr *ctlr;
- Ccb24 *ccb;
- Mbox24 *mb, *mbox;
- int port, rinterrupt, rstatus;
-
- ctlr = arg;
- port = ctlr->port;
-
- /*
- * Save and clear the interrupt(s). The only
- * interrupts expected are Cmdc, which is ignored,
- * and Imbl which means something completed.
- * There's one spurious interrupt left over from
- * initialisation, ignore it.
- */
- rinterrupt = inb(port+Rinterrupt);
- rstatus = inb(port+Rstatus);
- outb(port+Rcontrol, Rint);
- if((rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
- print("%s: interrupt 0x%2.2ux\n",
- ctlr->sdev->name, rinterrupt);
- if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
- print("%s: command invalid\n", ctlr->sdev->name);
-
- /*
- * Look for something in the mail.
- * If there is, save the status, free the mailbox
- * and wakeup whoever.
- */
- mb = ctlr->mb;
- for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
- pa = (mbox->ccb[0]<<16)|(mbox->ccb[1]<<8)|mbox->ccb[2];
- ccb = BPA2K(pa, BUSUNKNOWN);
- mbox->code = 0;
- ccb->done = 1;
- wakeup(ccb);
-
- ctlr->mbix++;
- if(ctlr->mbix >= NMbox+NMbox)
- ctlr->mbix = NMbox;
- }
-}
-
-static int
-done32(void* arg)
-{
- return ((Ccb32*)arg)->done;
-}
-
-static int
-mylex32rio(SDreq* r)
-{
- ulong p;
- uchar lun;
- Ctlr *ctlr;
- Ccb32 *ccb;
- Mbox32 *mb;
- int d, n, btstat, sdstat, target;
-
- ctlr = r->unit->dev->ctlr;
- target = r->unit->subno;
- lun = (r->cmd[1]>>5) & 0x07;
-
- /*
- * Ctlr->cache holds the last completed Ccb for this target if it
- * returned 'check condition'.
- * If this command is a request-sense and there is valid sense data
- * from the last completed Ccb, return it immediately.
- */
- lock(&ctlr->cachelock);
- if((ccb = ctlr->cache[target]) != nil){
- ctlr->cache[target] = nil;
- if(r->cmd[0] == 0x03
- && ccb->sdstat == SDcheck && lun == (ccb->luntag & 0x07)){
- unlock(&ctlr->cachelock);
- if(r->dlen){
- n = 8+ccb->sense[7];
- if(n > r->dlen)
- n = r->dlen;
- memmove(r->data, ccb->sense, n);
- r->rlen = n;
- }
- ccbfree(ctlr, (Ccb*)ccb);
- return SDok;
- }
- }
- unlock(&ctlr->cachelock);
- if(ccb == nil)
- ccb = ccballoc(ctlr);
-
- /*
- * Fill in the ccb.
- */
- ccb->opcode = Ordl;
-
- n = r->dlen;
- if(n == 0)
- ccb->datadir = CCBdataout|CCBdatain;
- else if(!r->write)
- ccb->datadir = CCBdatain;
- else
- ccb->datadir = CCBdataout;
-
- ccb->cdblen = r->clen;
-
- ccb->datalen[0] = n;
- ccb->datalen[1] = n>>8;
- ccb->datalen[2] = n>>16;
- ccb->datalen[3] = n>>24;
- p = PADDR(r->data);
- ccb->dataptr[0] = p;
- ccb->dataptr[1] = p>>8;
- ccb->dataptr[2] = p>>16;
- ccb->dataptr[3] = p>>24;
-
- ccb->targetid = target;
- ccb->luntag = lun;
- if(r->unit->inquiry[7] & 0x02)
- ccb->luntag |= SQTag|TagEnable;
- memmove(ccb->cdb, r->cmd, r->clen);
- ccb->btstat = ccb->sdstat = 0;
- ccb->ccbctl = 0;
-
- /*
- * There's one more mbox than there there is
- * ccb so there is always one free.
- */
- lock(&ctlr->mboxlock);
- mb = ctlr->mb;
- mb += ctlr->mbox;
- p = PADDR(ccb);
- mb->ccb[0] = p;
- mb->ccb[1] = p>>8;
- mb->ccb[2] = p>>16;
- mb->ccb[3] = p>>24;
- mb->code = Mbostart;
- ctlr->mbox++;
- if(ctlr->mbox >= NMbox)
- ctlr->mbox = 0;
-
- /*
- * This command does not require Hardy
- * and doesn't generate a Cmdc interrupt.
- */
- ccb->done = 0;
- outb(ctlr->port+Rcpr, Cstart);
- unlock(&ctlr->mboxlock);
-
- /*
- * Wait for the request to complete and return the status.
- * Since the buffer is not reference counted cannot return
- * until the DMA is done writing into the buffer so the caller
- * cannot free the buffer prematurely.
- */
- while(waserror())
- ;
- sleep(ccb, done32, ccb);
- poperror();
-
- /*
- * Save the status and patch up the number of
- * bytes actually transferred.
- * There's a firmware bug on some 956C controllers
- * which causes the return count from a successful
- * READ CAPACITY not to be updated, so fix it here.
- */
- sdstat = ccb->sdstat;
- btstat = ccb->btstat;
-
- d = ccb->datalen[0];
- d |= (ccb->datalen[1]<<8);
- d |= (ccb->datalen[2]<<16);
- d |= (ccb->datalen[3]<<24);
- if(ccb->cdb[0] == 0x25 && sdstat == SDok)
- d = 0;
- n -= d;
- r->rlen = n;
-
- /*
- * If there was a check-condition, save the
- * ccb for a possible request-sense command.
- */
- if(sdstat == SDcheck){
- if(r->flags & SDnosense){
- lock(&ctlr->cachelock);
- if(ctlr->cache[target])
- ccbfree(ctlr, ctlr->cache[target]);
- ctlr->cache[target] = (Ccb*)ccb;
- unlock(&ctlr->cachelock);
- return SDcheck;
- }
- n = 8+ccb->sense[7];
- if(n > sizeof(r->sense)-1)
- n = sizeof(r->sense)-1;
- memmove(r->sense, ccb->sense, n);
- r->flags |= SDvalidsense;
- }
- ccbfree(ctlr, (Ccb*)ccb);
-
- if(btstat){
- if(btstat == 0x11)
- return SDtimeout;
- return SDeio;
- }
- return sdstat;
-}
-
-static void
-mylex32interrupt(Ureg*, void* arg)
-{
- ulong pa;
- Ctlr *ctlr;
- Ccb32 *ccb;
- Mbox32 *mb, *mbox;
- int port, rinterrupt, rstatus;
-
- ctlr = arg;
- port = ctlr->port;
-
- /*
- * Save and clear the interrupt(s). The only
- * interrupts expected are Cmdc, which is ignored,
- * and Imbl which means something completed.
- * There's one spurious interrupt left over from
- * initialisation, ignore it.
- */
- rinterrupt = inb(port+Rinterrupt);
- rstatus = inb(port+Rstatus);
- outb(port+Rcontrol, Rint);
- if((rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
- print("%s: interrupt 0x%2.2ux\n",
- ctlr->sdev->name, rinterrupt);
- if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
- print("%s: command invalid\n", ctlr->sdev->name);
-
- /*
- * Look for something in the mail.
- * If there is, free the mailbox and wakeup whoever.
- */
- mb = ctlr->mb;
- for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
- pa = (mbox->ccb[3]<<24)
- |(mbox->ccb[2]<<16)
- |(mbox->ccb[1]<<8)
- |mbox->ccb[0];
- if(ctlr->pcidev)
- ccb = BPA2K(pa, ctlr->pcidev->tbdf);
- else
- ccb = BPA2K(pa, BUSUNKNOWN);
- mbox->code = 0;
- ccb->done = 1;
- wakeup(ccb);
-
- ctlr->mbix++;
- if(ctlr->mbix >= NMbox+NMbox)
- ctlr->mbix = NMbox;
- }
-}
-
-static int
-mylexrio(SDreq* r)
-{
- int subno;
- Ctlr *ctlr;
-
- subno = r->unit->subno;
- ctlr = r->unit->dev->ctlr;
- if(subno == ctlr->id || (!ctlr->wide && subno >= 8))
- r->status = SDtimeout;
- else if(ctlr->bus == 24)
- r->status = mylex24rio(r);
- else
- r->status = mylex32rio(r);
- return r->status;
-}
-
-/*
- * Issue a command to a controller. The command and its length is
- * contained in cmd and cmdlen. If any data is to be
- * returned, datalen should be non-zero, and the returned data
- * will be placed in data.
- * If Cmdc is set, bail out, the invalid command will be handled
- * when the interrupt is processed.
- */
-static void
-issueio(int port, uchar* cmd, int cmdlen, uchar* data, int datalen)
-{
- int len;
-
- if(cmd[0] != Cstart && cmd[0] != Ceombri){
- while(!(inb(port+Rstatus) & Hardy))
- ;
- }
- outb(port+Rcpr, cmd[0]);
-
- len = 1;
- while(len < cmdlen){
- if(!(inb(port+Rstatus) & Cprbsy)){
- outb(port+Rcpr, cmd[len]);
- len++;
- }
- if(inb(port+Rinterrupt) & Cmdc)
- return;
- }
-
- if(datalen){
- len = 0;
- while(len < datalen){
- if(inb(port+Rstatus) & Dirrdy){
- data[len] = inb(port+Rdatain);
- len++;
- }
- if(inb(port+Rinterrupt) & Cmdc)
- return;
- }
- }
-}
-
-/*
- * Issue a command to a controller, wait for it to complete then
- * try to reset the interrupt. Should only be called at initialisation.
- */
-static int
-issue(Ctlr* ctlr, uchar* cmd, int cmdlen, uchar* data, int datalen)
-{
- int port;
- uchar rinterrupt, rstatus;
- static Lock mylexissuelock;
-
- port = ctlr->port;
-
- ilock(&ctlr->issuelock);
- issueio(port, cmd, cmdlen, data, datalen);
-
- while(!((rinterrupt = inb(port+Rinterrupt)) & Cmdc))
- ;
-
- rstatus = inb(port+Rstatus);
- outb(port+Rcontrol, Rint);
- iunlock(&ctlr->issuelock);
-
- if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
- return 0;
- return 1;
-}
-
-static SDev*
-mylexprobe(int port, int irq)
-{
- SDev *sdev;
- Ctlr *ctlr;
- uchar cmd[6], data[256];
- int clen, dlen, timeo;
-
- if(ioalloc(port, 0x3, 0, "mylex") < 0)
- return nil;
- ctlr = nil;
- sdev = nil;
- /*
- * Attempt to hard-reset the board and reset
- * the SCSI bus. If the board state doesn't settle to
- * idle with mailbox initialisation required, either
- * it isn't a compatible board or it's broken.
- * If the controller has SCAM set this can take a while.
- */
- if(getconf("*noscsireset") != nil)
- outb(port+Rcontrol, Rhard);
- else
- outb(port+Rcontrol, Rhard|Rsbus);
- for(timeo = 0; timeo < 100; timeo++){
- if(inb(port+Rstatus) == (Inreq|Hardy))
- break;
- delay(100);
- }
- if(inb(port+Rstatus) != (Inreq|Hardy)){
-buggery:
- if(ctlr != nil)
- free(ctlr);
- if (sdev != nil)
- free(sdev);
- iofree(port);
- return nil;
- }
-
- if((ctlr = malloc(sizeof(Ctlr))) == nil)
- goto buggery;
- ctlr->port = port;
- ctlr->irq = irq;
- ctlr->bus = 24;
- ctlr->wide = 0;
-
- /*
- * Try to determine if this is a 32-bit MultiMaster controller
- * by attempting to obtain the extended inquiry information;
- * this command is not implemented on Adaptec 154xx
- * controllers. If successful, the first byte of the returned
- * data is the host adapter bus type, 'E' for 32-bit EISA,
- * PCI and VLB buses.
- */
- cmd[0] = Ciesi;
- cmd[1] = 4;
- clen = 2;
- dlen = 256;
- if(issue(ctlr, cmd, clen, data, dlen)){
- if(data[0] == 'E')
- ctlr->bus = 32;
- ctlr->wide = data[0x0D] & 0x01;
- }
- else{
- /*
- * Inconceivable though it may seem, a hard controller reset
- * is necessary here to clear out the command queue. Every
- * board seems to lock-up in a different way if you give an
- * invalid command and then try to clear out the
- * command/parameter and/or data-in register.
- * Soft reset doesn't do the job either. Fortunately no
- * serious initialisation has been done yet so there's nothing
- * to tidy up.
- */
- outb(port+Rcontrol, Rhard);
- for(timeo = 0; timeo < 100; timeo++){
- if(inb(port+Rstatus) == (Inreq|Hardy))
- break;
- delay(100);
- }
- if(inb(port+Rstatus) != (Inreq|Hardy))
- goto buggery;
- }
-
- /*
- * If the BIOS is enabled on the AHA-1542C/CF and BIOS options for
- * support of drives > 1Gb, dynamic scanning of the SCSI bus or more
- * than 2 drives under DOS 5.0 are enabled, the BIOS disables
- * accepting Cmbinit to protect against running with drivers which
- * don't support those options. In order to unlock the interface it
- * is necessary to read a lock-code using Cextbios and write it back
- * using Cmbienable; the lock-code is non-zero.
- */
- cmd[0] = Cinquiry;
- clen = 1;
- dlen = 4;
- if(issue(ctlr, cmd, clen, data, dlen) == 0)
- goto buggery;
- if(data[0] >= 0x43){
- cmd[0] = Cextbios;
- clen = 1;
- dlen = 2;
- if(issue(ctlr, cmd, clen, data, dlen) == 0)
- goto buggery;
-
- /*
- * Lock-code returned in data[1]. If it's non-zero write
- * it back along with bit 0 of byte 0 cleared to enable
- * mailbox initialisation.
- */
- if(data[1]){
- cmd[0] = Cmbienable;
- cmd[1] = 0;
- cmd[2] = data[1];
- clen = 3;
- if(issue(ctlr, cmd, clen, 0, 0) == 0)
- goto buggery;
- }
- }
-
- /*
- * Get the id, DMA and IRQ info from the board. This will
- * cause an interrupt which will hopefully not cause any
- * trouble because the interrupt number isn't known yet.
- * This is necessary as the DMA won't be set up if the
- * board has the BIOS disabled.
- *
- * If the IRQ is already known, this must be a 32-bit PCI
- * or EISA card, in which case the returned DMA and IRQ can
- * be ignored.
- */
- cmd[0] = Cinquire;
- clen = 1;
- dlen = 3;
- if(issue(ctlr, cmd, clen, data, dlen) == 0)
- goto buggery;
-
- ctlr->id = data[2] & 0x07;
- if(ctlr->irq < 0){
- switch(data[0]){ /* DMA Arbitration Priority */
- case 0x80: /* Channel 7 */
- outb(0xD6, 0xC3);
- outb(0xD4, 0x03);
- break;
- case 0x40: /* Channel 6 */
- outb(0xD6, 0xC2);
- outb(0xD4, 0x02);
- break;
- case 0x20: /* Channel 5 */
- outb(0xD6, 0xC1);
- outb(0xD4, 0x01);
- break;
- case 0x01: /* Channel 0 */
- outb(0x0B, 0xC0);
- outb(0x0A, 0x00);
- break;
- default:
- if(ctlr->bus == 24)
- goto buggery;
- break;
- }
-
- switch(data[1]){ /* Interrupt Channel */
- case 0x40:
- ctlr->irq = 15;
- break;
- case 0x20:
- ctlr->irq = 14;
- break;
- case 0x08:
- ctlr->irq = 12;
- break;
- case 0x04:
- ctlr->irq = 11;
- break;
- case 0x02:
- ctlr->irq = 10;
- break;
- case 0x01:
- ctlr->irq = 9;
- break;
- default:
- goto buggery;
- }
- }
-
- if((sdev = malloc(sizeof(SDev))) == nil)
- goto buggery;
- sdev->ifc = &sdmylexifc;
- sdev->ctlr = ctlr;
- ctlr->sdev = sdev;
- if(!ctlr->wide)
- sdev->nunit = 8;
- else
- sdev->nunit = 16;
-
- return sdev;
-}
-
-static int mylexport[8] = {
- 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0x000, 0x000,
-};
-
-static SDev*
-mylexpnp(void)
-{
- Pcidev *p;
- Ctlr *ctlr;
- ISAConf isa;
- int cfg, ctlrno, i, x;
- SDev *sdev, *head, *tail;
-
- p = nil;
- head = tail = nil;
- while(p = pcimatch(p, 0x104B, 0)){
- if((sdev = mylexprobe(p->mem[0].bar & ~0x01, p->intl)) == nil)
- continue;
-
- ctlr = sdev->ctlr;
- ctlr->pcidev = p;
-
- if(head != nil)
- tail->next = sdev;
- else
- head = sdev;
- tail = sdev;
- }
-
- if(strncmp(KADDR(0xFFFD9), "EISA", 4) == 0){
- for(cfg = 0x1000; cfg < MaxEISA*0x1000; cfg += 0x1000){
- x = 0;
- for(i = 0; i < 4; i++)
- x |= inb(cfg+CfgEISA+i)<<(i*8);
- if(x != 0x0142B30A && x != 0x0242B30A)
- continue;
-
- x = inb(cfg+0xC8C);
- if((sdev = mylexprobe(mylexport[x & 0x07], -1)) == nil)
- continue;
-
- if(head != nil)
- tail->next = sdev;
- else
- head = sdev;
- tail = sdev;
- }
- }
-
- for(ctlrno = 0; ctlrno < 4; ctlrno++){
- memset(&isa, 0, sizeof(isa));
- if(!isaconfig("scsi", ctlrno, &isa))
- continue;
- if(strcmp(isa.type, "aha1542"))
- continue;
- if((sdev = mylexprobe(isa.port, -1)) == nil)
- continue;
-
- if(head != nil)
- tail->next = sdev;
- else
- head = sdev;
- tail = sdev;
- }
-
- return head;
-}
-
-static SDev*
-mylexid(SDev* sdev)
-{
- return scsiid(sdev, &sdmylexifc);
-}
-
-static int
-mylex24enable(Ctlr* ctlr)
-{
- ulong p;
- Ccb24 *ccb, *ccbp;
- uchar cmd[6], *v;
- int len;
-
- len = (sizeof(Mbox24)*NMbox*2)+(sizeof(Ccb24)*NCcb);
- v = xspanalloc(len, 32, 0);
-
- if(!PADDR24(ctlr, sizeof(Ctlr)) || !PADDR24(v, len))
- return 0;
-
- ctlr->mb = v;
- v += sizeof(Mbox24)*NMbox*2;
-
- ccb = (Ccb24*)v;
- for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){
- ccbp->ccb = ctlr->ccb;
- ctlr->ccb = (Ccb*)ccbp;
- }
-
- /*
- * Initialise the software controller and
- * set the board scanning the mailboxes.
- */
- ctlr->mbix = NMbox;
-
- cmd[0] = Cinitialise;
- cmd[1] = NMbox;
- p = K2BPA(ctlr->mb, BUSUNKNOWN);
- cmd[2] = p>>16;
- cmd[3] = p>>8;
- cmd[4] = p;
-
- return issue(ctlr, cmd, 5, 0, 0);
-}
-
-static int
-mylex32enable(Ctlr* ctlr)
-{
- ulong p;
- Ccb32 *ccb, *ccbp;
- uchar cmd[6], *v;
-
- v = xspanalloc((sizeof(Mbox32)*NMbox*2)+(sizeof(Ccb32)*NCcb), 32, 0);
-
- ctlr->mb = v;
- v += sizeof(Mbox32)*NMbox*2;
-
- ccb = (Ccb32*)v;
- for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){
- /*
- * Fill in some stuff that doesn't change.
- */
- ccbp->senselen = sizeof(ccbp->sense);
- p = PADDR(ccbp->sense);
- ccbp->senseptr[0] = p;
- ccbp->senseptr[1] = p>>8;
- ccbp->senseptr[2] = p>>16;
- ccbp->senseptr[3] = p>>24;
-
- ccbp->ccb = ctlr->ccb;
- ctlr->ccb = (Ccb*)ccbp;
- }
-
- /*
- * Attempt wide mode setup.
- */
- if(ctlr->wide){
- cmd[0] = Cwide;
- cmd[1] = 1;
- if(!issue(ctlr, cmd, 2, 0, 0))
- ctlr->wide = 0;
- }
-
- /*
- * Initialise the software controller and
- * set the board scanning the mailboxes.
- */
- ctlr->mbix = NMbox;
-
- cmd[0] = Ciem;
- cmd[1] = NMbox;
- if(ctlr->pcidev)
- p = K2BPA(ctlr->mb, ctlr->tbdf);
- else
- p = K2BPA(ctlr->mb, BUSUNKNOWN);
- cmd[2] = p;
- cmd[3] = p>>8;
- cmd[4] = p>>16;
- cmd[5] = p>>24;
-
- return issue(ctlr, cmd, 6, 0, 0);
-}
-
-static int
-mylexenable(SDev* sdev)
-{
- int tbdf;
- Ctlr *ctlr;
- void (*interrupt)(Ureg*, void*);
- char name[32];
-
- ctlr = sdev->ctlr;
- if(ctlr->cache == nil){
- if((ctlr->cache = malloc(sdev->nunit*sizeof(Ccb*))) == nil)
- return 0;
- }
-
- tbdf = BUSUNKNOWN;
- if(ctlr->bus == 32){
- if(ctlr->pcidev){
- tbdf = ctlr->pcidev->tbdf;
- pcisetbme(ctlr->pcidev);
- }
- if(!mylex32enable(ctlr))
- return 0;
- interrupt = mylex32interrupt;
- }
- else if(mylex24enable(ctlr))
- interrupt = mylex24interrupt;
- else
- return 0;
-
- snprint(name, sizeof(name), "sd%c (%s)", sdev->idno, sdev->ifc->name);
- intrenable(ctlr->irq, interrupt, ctlr, tbdf, name);
-
- return 1;
-}
-
-SDifc sdmylexifc = {
- "mylex", /* name */
-
- mylexpnp, /* pnp */
- nil, /* legacy */
- mylexid, /* id */
- mylexenable, /* enable */
- nil, /* disable */
-
- scsiverify, /* verify */
- scsionline, /* online */
- mylexrio, /* rio */
- nil, /* rctl */
- nil, /* wctl */
-
- scsibio, /* bio */
- nil, /* probe */
- nil, /* clear */
- nil, /* stat */
-};
diff --git a/os/pc/sdscsi.c b/os/pc/sdscsi.c
deleted file mode 100644
index 0340564c..00000000
--- a/os/pc/sdscsi.c
+++ /dev/null
@@ -1,394 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-#include "../port/sd.h"
-
-static int
-scsitest(SDreq* r)
-{
- r->write = 0;
- memset(r->cmd, 0, sizeof(r->cmd));
- r->cmd[1] = r->lun<<5;
- r->clen = 6;
- r->data = nil;
- r->dlen = 0;
- r->flags = 0;
-
- r->status = ~0;
-
- return r->unit->dev->ifc->rio(r);
-}
-
-int
-scsiverify(SDunit* unit)
-{
- SDreq *r;
- int i, status;
- uchar *inquiry;
-
- if((r = malloc(sizeof(SDreq))) == nil)
- return 0;
- if((inquiry = sdmalloc(sizeof(unit->inquiry))) == nil){
- free(r);
- return 0;
- }
- r->unit = unit;
- r->lun = 0; /* ??? */
-
- memset(unit->inquiry, 0, sizeof(unit->inquiry));
- r->write = 0;
- r->cmd[0] = 0x12;
- r->cmd[1] = r->lun<<5;
- r->cmd[4] = sizeof(unit->inquiry)-1;
- r->clen = 6;
- r->data = inquiry;
- r->dlen = sizeof(unit->inquiry)-1;
- r->flags = 0;
-
- r->status = ~0;
- if(unit->dev->ifc->rio(r) != SDok){
- free(r);
- return 0;
- }
- memmove(unit->inquiry, inquiry, r->dlen);
- free(inquiry);
-
- SET(status);
- for(i = 0; i < 3; i++){
- while((status = scsitest(r)) == SDbusy)
- ;
- if(status == SDok || status != SDcheck)
- break;
- if(!(r->flags & SDvalidsense))
- break;
- if((r->sense[2] & 0x0F) != 0x02)
- continue;
-
- /*
- * Unit is 'not ready'.
- * If it is in the process of becoming ready or needs
- * an initialising command, set status so it will be spun-up
- * below.
- * If there's no medium, that's OK too, but don't
- * try to spin it up.
- */
- if(r->sense[12] == 0x04){
- if(r->sense[13] == 0x02 || r->sense[13] == 0x01){
- status = SDok;
- break;
- }
- }
- if(r->sense[12] == 0x3A)
- break;
- }
-
- if(status == SDok){
- /*
- * Try to ensure a direct-access device is spinning.
- * Don't wait for completion, ignore the result.
- */
- if((unit->inquiry[0] & 0x1F) == 0){
- memset(r->cmd, 0, sizeof(r->cmd));
- r->write = 0;
- r->cmd[0] = 0x1B;
- r->cmd[1] = (r->lun<<5)|0x01;
- r->cmd[4] = 1;
- r->clen = 6;
- r->data = nil;
- r->dlen = 0;
- r->flags = 0;
-
- r->status = ~0;
- unit->dev->ifc->rio(r);
- }
- }
- free(r);
-
- if(status == SDok || status == SDcheck)
- return 1;
- return 0;
-}
-
-static int
-scsirio(SDreq* r)
-{
- /*
- * Perform an I/O request, returning
- * -1 failure
- * 0 ok
- * 1 no medium present
- * 2 retry
- * The contents of r may be altered so the
- * caller should re-initialise if necesary.
- */
- r->status = ~0;
- switch(r->unit->dev->ifc->rio(r)){
- default:
- return -1;
- case SDcheck:
- if(!(r->flags & SDvalidsense))
- return -1;
- switch(r->sense[2] & 0x0F){
- case 0x00: /* no sense */
- case 0x01: /* recovered error */
- return 2;
- case 0x06: /* check condition */
- /*
- * 0x28 - not ready to ready transition,
- * medium may have changed.
- * 0x29 - power on or some type of reset.
- */
- if(r->sense[12] == 0x28 && r->sense[13] == 0)
- return 2;
- if(r->sense[12] == 0x29)
- return 2;
- return -1;
- case 0x02: /* not ready */
- /*
- * If no medium present, bail out.
- * If unit is becoming ready, rather than not
- * not ready, wait a little then poke it again. */
- if(r->sense[12] == 0x3A)
- return 1;
- if(r->sense[12] != 0x04 || r->sense[13] != 0x01)
- return -1;
-
- while(waserror())
- ;
- tsleep(&up->sleep, return0, 0, 500);
- poperror();
- scsitest(r);
- return 2;
- default:
- return -1;
- }
- return -1;
- case SDok:
- return 0;
- }
- return -1;
-}
-
-int
-scsionline(SDunit* unit)
-{
- SDreq *r;
- uchar *p;
- int ok, retries;
-
- if((r = malloc(sizeof(SDreq))) == nil)
- return 0;
- if((p = sdmalloc(8)) == nil){
- free(r);
- return 0;
- }
-
- ok = 0;
-
- r->unit = unit;
- r->lun = 0; /* ??? */
- for(retries = 0; retries < 10; retries++){
- /*
- * Read-capacity is mandatory for DA, WORM, CD-ROM and
- * MO. It may return 'not ready' if type DA is not
- * spun up, type MO or type CD-ROM are not loaded or just
- * plain slow getting their act together after a reset.
- */
- r->write = 0;
- memset(r->cmd, 0, sizeof(r->cmd));
- r->cmd[0] = 0x25;
- r->cmd[1] = r->lun<<5;
- r->clen = 10;
- r->data = p;
- r->dlen = 8;
- r->flags = 0;
-
- r->status = ~0;
- switch(scsirio(r)){
- default:
- break;
- case 0:
- unit->sectors = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
- if(unit->sectors == 0)
- continue;
- /*
- * Read-capacity returns the LBA of the last sector,
- * therefore the number of sectors must be incremented.
- */
- unit->sectors++;
- unit->secsize = (p[4]<<24)|(p[5]<<16)|(p[6]<<8)|p[7];
-
- /*
- * Some ATAPI CD readers lie about the block size.
- * Since we don't read audio via this interface
- * it's okay to always fudge this.
- */
- if(unit->secsize == 2352)
- unit->secsize = 2048;
- ok = 1;
- break;
- case 1:
- ok = 1;
- break;
- case 2:
- continue;
- }
- break;
- }
- free(p);
- free(r);
-
- if(ok)
- return ok+retries;
- else
- return 0;
-}
-
-int
-scsiexec(SDunit* unit, int write, uchar* cmd, int clen, void* data, int* dlen)
-{
- SDreq *r;
- int status;
-
- if((r = malloc(sizeof(SDreq))) == nil)
- return SDmalloc;
- r->unit = unit;
- r->lun = cmd[1]>>5; /* ??? */
- r->write = write;
- memmove(r->cmd, cmd, clen);
- r->clen = clen;
- r->data = data;
- if(dlen)
- r->dlen = *dlen;
- r->flags = 0;
-
- r->status = ~0;
-
- /*
- * Call the device-specific I/O routine.
- * There should be no calls to 'error()' below this
- * which percolate back up.
- */
- switch(status = unit->dev->ifc->rio(r)){
- case SDok:
- if(dlen)
- *dlen = r->rlen;
- /*FALLTHROUGH*/
- case SDcheck:
- /*FALLTHROUGH*/
- default:
- /*
- * It's more complicated than this. There are conditions
- * which are 'ok' but for which the returned status code
- * is not 'SDok'.
- * Also, not all conditions require a reqsense, might
- * need to do a reqsense here and make it available to the
- * caller somehow.
- *
- * Mañana.
- */
- break;
- }
- sdfree(r);
-
- return status;
-}
-
-long
-scsibio(SDunit* unit, int lun, int write, void* data, long nb, long bno)
-{
- SDreq *r;
- long rlen;
-
- if((r = malloc(sizeof(SDreq))) == nil)
- error(Enomem);
- r->unit = unit;
- r->lun = lun;
-again:
- r->write = write;
- if(write == 0)
- r->cmd[0] = 0x28;
- else
- r->cmd[0] = 0x2A;
- r->cmd[1] = (lun<<5);
- r->cmd[2] = bno>>24;
- r->cmd[3] = bno>>16;
- r->cmd[4] = bno>>8;
- r->cmd[5] = bno;
- r->cmd[6] = 0;
- r->cmd[7] = nb>>8;
- r->cmd[8] = nb;
- r->cmd[9] = 0;
- r->clen = 10;
- r->data = data;
- r->dlen = nb*unit->secsize;
- r->flags = 0;
-
- r->status = ~0;
- switch(scsirio(r)){
- default:
- rlen = -1;
- break;
- case 0:
- rlen = r->rlen;
- break;
- case 2:
- rlen = -1;
- if(!(r->flags & SDvalidsense))
- break;
- switch(r->sense[2] & 0x0F){
- default:
- break;
- case 0x06: /* check condition */
- /*
- * Check for a removeable media change.
- * If so, mark it by zapping the geometry info
- * to force an online request.
- */
- if(r->sense[12] != 0x28 || r->sense[13] != 0)
- break;
- if(unit->inquiry[1] & 0x80)
- unit->sectors = 0;
- break;
- case 0x02: /* not ready */
- /*
- * If unit is becoming ready,
- * rather than not not ready, try again.
- */
- if(r->sense[12] == 0x04 && r->sense[13] == 0x01)
- goto again;
- break;
- }
- break;
- }
- free(r);
-
- return rlen;
-}
-
-SDev*
-scsiid(SDev* sdev, SDifc* ifc)
-{
- char name[32];
- static char idno[16] = "0123456789abcdef";
- static char *p = idno;
-
- while(sdev){
- if(sdev->ifc == ifc){
- sdev->idno = *p++;
- snprint(name, sizeof(name), "sd%c", sdev->idno);
- kstrdup(&sdev->name, name);
- if(p >= &idno[sizeof(idno)])
- break;
- }
- sdev = sdev->next;
- }
-
- return nil;
-}
diff --git a/os/pc/trap.c b/os/pc/trap.c
deleted file mode 100644
index 465c9bab..00000000
--- a/os/pc/trap.c
+++ /dev/null
@@ -1,571 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-int (*breakhandler)(Ureg *ur, Proc*);
-
-static void debugbpt(Ureg*, void*);
-static void fault386(Ureg*, void*);
-static void doublefault(Ureg*, void*);
-static void unexpected(Ureg*, void*);
-static void _dumpstack(Ureg*);
-
-static Lock vctllock;
-static Vctl *vctl[256];
-
-enum
-{
- Ntimevec = 20 /* number of time buckets for each intr */
-};
-ulong intrtimes[256][Ntimevec];
-
-void
-intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
-{
- int vno;
- Vctl *v;
-
- if(f == nil){
- print("intrenable: nil handler for %d, tbdf 0x%uX for %s\n",
- irq, tbdf, name);
- return;
- }
-
- v = xalloc(sizeof(Vctl));
- v->isintr = 1;
- v->irq = irq;
- v->tbdf = tbdf;
- v->f = f;
- v->a = a;
- strncpy(v->name, name, KNAMELEN-1);
- v->name[KNAMELEN-1] = 0;
-
- ilock(&vctllock);
- vno = arch->intrenable(v);
- if(vno == -1){
- iunlock(&vctllock);
- print("intrenable: couldn't enable irq %d, tbdf 0x%uX for %s\n",
- irq, tbdf, v->name);
- xfree(v);
- return;
- }
- if(vctl[vno]){
- if(vctl[vno]->isr != v->isr || vctl[vno]->eoi != v->eoi)
- panic("intrenable: handler: %s %s %luX %luX %luX %luX\n",
- vctl[vno]->name, v->name,
- vctl[vno]->isr, v->isr, vctl[vno]->eoi, v->eoi);
- v->next = vctl[vno];
- }
- vctl[vno] = v;
- iunlock(&vctllock);
-}
-
-int
-intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
-{
- Vctl **pv, *v;
- int vno;
-
- /*
- * For now, none of this will work with the APIC code,
- * there is no mapping between irq and vector as the IRQ
- * is pretty meaningless.
- */
- if(arch->intrvecno == nil)
- return -1;
- vno = arch->intrvecno(irq);
- ilock(&vctllock);
- pv = &vctl[vno];
- while (*pv &&
- ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a ||
- strcmp((*pv)->name, name)))
- pv = &((*pv)->next);
- assert(*pv);
-
- v = *pv;
- *pv = (*pv)->next; /* Link out the entry */
-
- if(vctl[vno] == nil && arch->intrdisable != nil)
- arch->intrdisable(irq);
- iunlock(&vctllock);
- xfree(v);
- return 0;
-}
-
-static long
-irqallocread(Chan*, void *vbuf, long n, vlong offset)
-{
- char *buf, *p, str[2*(11+1)+KNAMELEN+1+1];
- int m, vno;
- long oldn;
- Vctl *v;
-
- if(n < 0 || offset < 0)
- error(Ebadarg);
-
- oldn = n;
- buf = vbuf;
- for(vno=0; vno<nelem(vctl); vno++){
- for(v=vctl[vno]; v; v=v->next){
- m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, KNAMELEN, v->name);
- if(m <= offset) /* if do not want this, skip entry */
- offset -= m;
- else{
- /* skip offset bytes */
- m -= offset;
- p = str+offset;
- offset = 0;
-
- /* write at most max(n,m) bytes */
- if(m > n)
- m = n;
- memmove(buf, p, m);
- n -= m;
- buf += m;
-
- if(n == 0)
- return oldn;
- }
- }
- }
- return oldn - n;
-}
-
-void
-trapenable(int vno, void (*f)(Ureg*, void*), void* a, char *name)
-{
- Vctl *v;
-
- if(vno < 0 || vno >= VectorPIC)
- panic("trapenable: vno %d\n", vno);
- v = xalloc(sizeof(Vctl));
- v->tbdf = BUSUNKNOWN;
- v->f = f;
- v->a = a;
- strncpy(v->name, name, KNAMELEN);
- v->name[KNAMELEN-1] = 0;
-
- lock(&vctllock);
- if(vctl[vno])
- v->next = vctl[vno]->next;
- vctl[vno] = v;
- unlock(&vctllock);
-}
-
-static void
-nmienable(void)
-{
- int x;
-
- /*
- * Hack: should be locked with NVRAM access.
- */
- outb(0x70, 0x80); /* NMI latch clear */
- outb(0x70, 0);
-
- x = inb(0x61) & 0x07; /* Enable NMI */
- outb(0x61, 0x08|x);
- outb(0x61, x);
-}
-
-void
-trapinit(void)
-{
- int d1, v;
- ulong vaddr;
- Segdesc *idt;
-
- idt = (Segdesc*)IDTADDR;
- vaddr = (ulong)vectortable;
- for(v = 0; v < 256; v++){
- d1 = (vaddr & 0xFFFF0000)|SEGP;
- switch(v){
-
- case VectorBPT:
- d1 |= SEGPL(3)|SEGIG;
- break;
-
- case VectorSYSCALL:
- d1 |= SEGPL(3)|SEGIG;
- break;
-
- default:
- d1 |= SEGPL(0)|SEGIG;
- break;
- }
- idt[v].d0 = (vaddr & 0xFFFF)|(KESEL<<16);
- idt[v].d1 = d1;
- vaddr += 6;
- }
-
- /*
- * Special traps.
- * Syscall() is called directly without going through trap().
- */
- trapenable(VectorBPT, debugbpt, 0, "debugpt");
- trapenable(VectorPF, fault386, 0, "fault386");
- trapenable(Vector2F, doublefault, 0, "doublefault");
- trapenable(Vector15, unexpected, 0, "unexpected");
-
- nmienable();
-
- addarchfile("irqalloc", 0444, irqallocread, nil);
-}
-
-static char* excname[32] = {
- "divide error",
- "debug exception",
- "nonmaskable interrupt",
- "breakpoint",
- "overflow",
- "bounds check",
- "invalid opcode",
- "coprocessor not available",
- "double fault",
- "coprocessor segment overrun",
- "invalid TSS",
- "segment not present",
- "stack exception",
- "general protection violation",
- "page fault",
- "15 (reserved)",
- "coprocessor error",
- "alignment check",
- "machine check",
- "19 (reserved)",
- "20 (reserved)",
- "21 (reserved)",
- "22 (reserved)",
- "23 (reserved)",
- "24 (reserved)",
- "25 (reserved)",
- "26 (reserved)",
- "27 (reserved)",
- "28 (reserved)",
- "29 (reserved)",
- "30 (reserved)",
- "31 (reserved)",
-};
-
-/*
- * keep histogram of interrupt service times
- */
-void
-intrtime(Mach*, int vno)
-{
- USED(vno);
-}
-
-/*
- * All traps come here. It is slower to have all traps call trap()
- * rather than directly vectoring the handler. However, this avoids a
- * lot of code duplication and possible bugs. The only exception is
- * VectorSYSCALL.
- * Trap is called with interrupts disabled via interrupt-gates.
- */
-void
-trap(Ureg* ureg)
-{
- int i, vno;
- char buf[ERRMAX];
- Vctl *ctl, *v;
- Mach *mach;
-
- vno = ureg->trap;
- if(ctl = vctl[vno]){
- if(ctl->isintr){
- m->intr++;
- if(vno >= VectorPIC && vno != VectorSYSCALL)
- m->lastintr = ctl->irq;
- }
-
- if(ctl->isr)
- ctl->isr(vno);
- for(v = ctl; v != nil; v = v->next){
- if(v->f)
- v->f(ureg, v->a);
- }
- if(ctl->eoi)
- ctl->eoi(vno);
-
- if(ctl->isintr){
- if(up && ctl->irq != IrqTIMER && ctl->irq != IrqCLOCK)
- preemption(0);
- }
- }
- else if(vno <= nelem(excname) && up->type == Interp){
- spllo();
- sprint(buf, "sys: trap: %s", excname[vno]);
- error(buf);
- }
- else if(vno >= VectorPIC && vno != VectorSYSCALL){
- /*
- * An unknown interrupt.
- * Check for a default IRQ7. This can happen when
- * the IRQ input goes away before the acknowledge.
- * In this case, a 'default IRQ7' is generated, but
- * the corresponding bit in the ISR isn't set.
- * In fact, just ignore all such interrupts.
- */
-
- /* call all interrupt routines, just in case */
- for(i = VectorPIC; i <= MaxIrqLAPIC; i++){
- ctl = vctl[i];
- if(ctl == nil)
- continue;
- if(!ctl->isintr)
- continue;
- for(v = ctl; v != nil; v = v->next){
- if(v->f)
- v->f(ureg, v->a);
- }
- /* should we do this? */
- if(ctl->eoi)
- ctl->eoi(i);
- }
-
- /* clear the interrupt */
- i8259isr(vno);
-
- if(0)print("cpu%d: spurious interrupt %d, last %d",
- m->machno, vno, m->lastintr);
- if(0)if(conf.nmach > 1){
- for(i = 0; i < 32; i++){
- if(!(active.machs & (1<<i)))
- continue;
- mach = MACHP(i);
- if(m->machno == mach->machno)
- continue;
- print(" cpu%d: last %d",
- mach->machno, mach->lastintr);
- }
- print("\n");
- }
- m->spuriousintr++;
- return;
- }
- else{
- if(vno == VectorNMI){
- nmienable();
- if(m->machno != 0){
- print("cpu%d: PC %8.8luX\n",
- m->machno, ureg->pc);
- for(;;);
- }
- }
- dumpregs(ureg);
- if(vno < nelem(excname))
- panic("%s", excname[vno]);
- panic("unknown trap/intr: %d\n", vno);
- }
-
- /* delaysched set because we held a lock or because our quantum ended */
- if(up && up->delaysched){
- sched();
- splhi();
- }
-}
-
-/*
- * dump registers
- */
-void
-dumpregs2(Ureg* ureg)
-{
- if(up)
- print("cpu%d: registers for %s %lud\n",
- m->machno, up->text, up->pid);
- else
- print("cpu%d: registers for kernel\n", m->machno);
- print("FLAGS=%luX TRAP=%luX ECODE=%luX PC=%luX",
- ureg->flags, ureg->trap, ureg->ecode, ureg->pc);
- print(" SS=%4.4luX USP=%luX\n", ureg->ss & 0xFFFF, ureg->usp);
- print(" AX %8.8luX BX %8.8luX CX %8.8luX DX %8.8luX\n",
- ureg->ax, ureg->bx, ureg->cx, ureg->dx);
- print(" SI %8.8luX DI %8.8luX BP %8.8luX\n",
- ureg->si, ureg->di, ureg->bp);
- print(" CS %4.4luX DS %4.4luX ES %4.4luX FS %4.4luX GS %4.4luX\n",
- ureg->cs & 0xFFFF, ureg->ds & 0xFFFF, ureg->es & 0xFFFF,
- ureg->fs & 0xFFFF, ureg->gs & 0xFFFF);
-}
-
-void
-dumpregs(Ureg* ureg)
-{
- extern ulong etext;
- vlong mca, mct;
-
- dumpregs2(ureg);
-
- /*
- * Processor control registers.
- * If machine check exception, time stamp counter, page size extensions
- * or enhanced virtual 8086 mode extensions are supported, there is a
- * CR4. If there is a CR4 and machine check extensions, read the machine
- * check address and machine check type registers if RDMSR supported.
- */
- print(" CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux",
- getcr0(), getcr2(), getcr3());
- if(m->cpuiddx & 0x9A){
- print(" CR4 %8.8lux", getcr4());
- if((m->cpuiddx & 0xA0) == 0xA0){
- rdmsr(0x00, &mca);
- rdmsr(0x01, &mct);
- print("\n MCA %8.8llux MCT %8.8llux", mca, mct);
- }
- }
- print("\n ur %lux up %lux\n", ureg, up);
-}
-
-/*
- * Fill in enough of Ureg to get a stack trace, and call a function.
- * Used by debugging interface rdb.
- */
-void
-callwithureg(void (*fn)(Ureg*))
-{
- Ureg ureg;
- ureg.pc = getcallerpc(&fn);
- ureg.sp = (ulong)&fn;
- fn(&ureg);
-}
-
-static void
-_dumpstack(Ureg *ureg)
-{
- ulong l, v, i, estack;
- extern ulong etext;
-
- print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp);
- i = 0;
- if(up
- && (ulong)&l >= (ulong)up->kstack
- && (ulong)&l <= (ulong)up->kstack+KSTACK)
- estack = (ulong)up->kstack+KSTACK;
- else if((ulong)&l >= (ulong)m->stack
- && (ulong)&l <= (ulong)m+BY2PG)
- estack = (ulong)m+MACHSIZE;
- else
- return;
-
- for(l=(ulong)&l; l<estack; l+=4){
- v = *(ulong*)l;
- if(KTZERO < v && v < (ulong)&etext){
- /*
- * we could Pick off general CALL (((uchar*)v)[-5] == 0xE8)
- * and CALL indirect through AX (((uchar*)v)[-2] == 0xFF && ((uchar*)v)[-2] == 0xD0),
- * but this is too clever and misses faulting address.
- */
- print("%.8lux=%.8lux ", l, v);
- i++;
- }
- if(i == 4){
- i = 0;
- print("\n");
- }
- }
- if(i)
- print("\n");
-}
-
-void
-dumpstack(void)
-{
- callwithureg(_dumpstack);
-}
-
-static void
-debugbpt(Ureg* ureg, void*)
-{
- char buf[ERRMAX];
-
- if(breakhandler != nil){
- breakhandler(ureg, up);
- return;
- }
- if(up == 0)
- panic("kernel bpt");
- /* restore pc to instruction that caused the trap */
- ureg->pc--;
- sprint(buf, "sys: breakpoint");
- error(buf);
-}
-
-static void
-doublefault(Ureg*, void*)
-{
- panic("double fault");
-}
-
-static void
-unexpected(Ureg* ureg, void*)
-{
- print("unexpected trap %lud; ignoring\n", ureg->trap);
-}
-
-static void
-fault386(Ureg* ureg, void*)
-{
- ulong addr;
- int read, user;
- char buf[ERRMAX];
-
- addr = getcr2();
- user = (ureg->cs & 0xFFFF) == UESEL;
- if(!user && mmukmapsync(addr))
- return;
- read = !(ureg->ecode & 2);
- spllo();
- snprint(buf, sizeof(buf), "trap: fault %s pc=0x%lux addr=0x%lux",
- read ? "read" : "write", ureg->pc, addr);
- if(up->type == Interp)
- disfault(ureg, buf);
- dumpregs(ureg);
- panic("fault: %s\n", buf);
-}
-
-
-
-
-
-static void
-linkproc(void)
-{
- spllo();
- up->kpfun(up->arg);
- pexit("kproc dying", 0);
-}
-
-void
-kprocchild(Proc* p, void (*func)(void*), void* arg)
-{
- /*
- * gotolabel() needs a word on the stack in
- * which to place the return PC used to jump
- * to linkproc().
- */
- p->sched.pc = (ulong)linkproc;
- p->sched.sp = (ulong)p->kstack+KSTACK-BY2WD;
-
- p->kpfun = func;
- p->arg = arg;
-}
-
-
-
-ulong
-dbgpc(Proc *p)
-{
- Ureg *ureg;
-
- ureg = p->dbgreg;
- if(ureg == 0)
- return 0;
-
- return ureg->pc;
-}
diff --git a/os/pc/tv.h b/os/pc/tv.h
deleted file mode 100644
index 181563b8..00000000
--- a/os/pc/tv.h
+++ /dev/null
@@ -1,15 +0,0 @@
-static ushort
-swab16(ushort u) {
- return u;
-}
-
-#define ScreenWidth 640 /* screen width */
-#define ScreenHeight 480 /* screen height */
-#define XCorrection 9 /* correction for x axes (trial and error) */
-#define YCorrection 32 /* correction for y axes (trial and error) */
-#define HSync 1
-#define VSync 1
-
-#define AudioChip TEA6320T /* new board has TEA6320T */
-
-#define EISA(a) (a)
diff --git a/os/pc/uarti8250.c b/os/pc/uarti8250.c
deleted file mode 100644
index 2d6c0da2..00000000
--- a/os/pc/uarti8250.c
+++ /dev/null
@@ -1,740 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/uart.h"
-
-/*
- * 8250 UART and compatibles.
- */
-enum {
- Uart0 = 0x3F8, /* COM1 */
- Uart0IRQ = 4,
- Uart1 = 0x2F8, /* COM2 */
- Uart1IRQ = 3,
-
- UartFREQ = 1843200,
-};
-
-enum { /* I/O ports */
- Rbr = 0, /* Receiver Buffer (RO) */
- Thr = 0, /* Transmitter Holding (WO) */
- Ier = 1, /* Interrupt Enable */
- Iir = 2, /* Interrupt Identification (RO) */
- Fcr = 2, /* FIFO Control (WO) */
- Lcr = 3, /* Line Control */
- Mcr = 4, /* Modem Control */
- Lsr = 5, /* Line Status */
- Msr = 6, /* Modem Status */
- Scr = 7, /* Scratch Pad */
- Dll = 0, /* Divisor Latch LSB */
- Dlm = 1, /* Divisor Latch MSB */
-};
-
-enum { /* Ier */
- Erda = 0x01, /* Enable Received Data Available */
- Ethre = 0x02, /* Enable Thr Empty */
- Erls = 0x04, /* Enable Receiver Line Status */
- Ems = 0x08, /* Enable Modem Status */
-};
-
-enum { /* Iir */
- Ims = 0x00, /* Ms interrupt */
- Ip = 0x01, /* Interrupt Pending (not) */
- Ithre = 0x02, /* Thr Empty */
- Irda = 0x04, /* Received Data Available */
- Irls = 0x06, /* Receiver Line Status */
- Ictoi = 0x0C, /* Character Time-out Indication */
- IirMASK = 0x3F,
- Ifena = 0xC0, /* FIFOs enabled */
-};
-
-enum { /* Fcr */
- FIFOena = 0x01, /* FIFO enable */
- FIFOrclr = 0x02, /* clear Rx FIFO */
- FIFOtclr = 0x04, /* clear Tx FIFO */
- FIFO1 = 0x00, /* Rx FIFO trigger level 1 byte */
- FIFO4 = 0x40, /* 4 bytes */
- FIFO8 = 0x80, /* 8 bytes */
- FIFO14 = 0xC0, /* 14 bytes */
-};
-
-enum { /* Lcr */
- Wls5 = 0x00, /* Word Length Select 5 bits/byte */
- Wls6 = 0x01, /* 6 bits/byte */
- Wls7 = 0x02, /* 7 bits/byte */
- Wls8 = 0x03, /* 8 bits/byte */
- WlsMASK = 0x03,
- Stb = 0x04, /* 2 stop bits */
- Pen = 0x08, /* Parity Enable */
- Eps = 0x10, /* Even Parity Select */
- Stp = 0x20, /* Stick Parity */
- Brk = 0x40, /* Break */
- Dlab = 0x80, /* Divisor Latch Access Bit */
-};
-
-enum { /* Mcr */
- Dtr = 0x01, /* Data Terminal Ready */
- Rts = 0x02, /* Ready To Send */
- Out1 = 0x04, /* no longer in use */
- Ie = 0x08, /* IRQ Enable */
- Dm = 0x10, /* Diagnostic Mode loopback */
-};
-
-enum { /* Lsr */
- Dr = 0x01, /* Data Ready */
- Oe = 0x02, /* Overrun Error */
- Pe = 0x04, /* Parity Error */
- Fe = 0x08, /* Framing Error */
- Bi = 0x10, /* Break Interrupt */
- Thre = 0x20, /* Thr Empty */
- Temt = 0x40, /* Tramsmitter Empty */
- FIFOerr = 0x80, /* error in receiver FIFO */
-};
-
-enum { /* Msr */
- Dcts = 0x01, /* Delta Cts */
- Ddsr = 0x02, /* Delta Dsr */
- Teri = 0x04, /* Trailing Edge of Ri */
- Ddcd = 0x08, /* Delta Dcd */
- Cts = 0x10, /* Clear To Send */
- Dsr = 0x20, /* Data Set Ready */
- Ri = 0x40, /* Ring Indicator */
- Dcd = 0x80, /* Data Set Ready */
-};
-
-typedef struct Ctlr {
- int io;
- int irq;
- int tbdf;
- int iena;
-
- uchar sticky[8];
-
- Lock;
- int hasfifo;
- int checkfifo;
- int fena;
-} Ctlr;
-
-extern PhysUart i8250physuart;
-
-static Ctlr i8250ctlr[2] = {
-{ .io = Uart0,
- .irq = Uart0IRQ,
- .tbdf = BUSUNKNOWN, },
-
-{ .io = Uart1,
- .irq = Uart1IRQ,
- .tbdf = BUSUNKNOWN, },
-};
-
-static Uart i8250uart[2] = {
-{ .regs = &i8250ctlr[0],
- .name = "COM1",
- .freq = UartFREQ,
- .phys = &i8250physuart,
- .special= 0,
- .next = &i8250uart[1], },
-
-{ .regs = &i8250ctlr[1],
- .name = "COM2",
- .freq = UartFREQ,
- .phys = &i8250physuart,
- .special= 0,
- .next = nil, },
-};
-
-#define csr8r(c, r) inb((c)->io+(r))
-#define csr8w(c, r, v) outb((c)->io+(r), (c)->sticky[(r)]|(v))
-
-static long
-i8250status(Uart* uart, void* buf, long n, long offset)
-{
- char *p;
- Ctlr *ctlr;
- uchar ier, lcr, mcr, msr;
-
- ctlr = uart->regs;
- p = malloc(READSTR);
- mcr = ctlr->sticky[Mcr];
- msr = csr8r(ctlr, Msr);
- ier = ctlr->sticky[Ier];
- lcr = ctlr->sticky[Lcr];
- snprint(p, READSTR,
- "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
- "dev(%d) type(%d) framing(%d) overruns(%d) "
- "berr(%d) serr(%d)%s%s%s%s\n",
-
- uart->baud,
- uart->hup_dcd,
- (msr & Dsr) != 0,
- uart->hup_dsr,
- (lcr & WlsMASK) + 5,
- (ier & Ems) != 0,
- (lcr & Pen) ? ((lcr & Eps) ? 'e': 'o'): 'n',
- (mcr & Rts) != 0,
- (lcr & Stb) ? 2: 1,
- ctlr->fena,
-
- uart->dev,
- uart->type,
- uart->ferr,
- uart->oerr,
- uart->berr,
- uart->serr,
- (msr & Cts) ? " cts": "",
- (msr & Dsr) ? " dsr": "",
- (msr & Dcd) ? " dcd": "",
- (msr & Ri) ? " ring": ""
- );
- n = readstr(offset, buf, n, p);
- free(p);
-
- return n;
-}
-
-static void
-i8250fifo(Uart* uart, int level)
-{
- Ctlr *ctlr;
-
- ctlr = uart->regs;
- if(ctlr->hasfifo == 0)
- return;
-
- /*
- * Changing the FIFOena bit in Fcr flushes data
- * from both receive and transmit FIFOs; there's
- * no easy way to guarantee not losing data on
- * the receive side, but it's possible to wait until
- * the transmitter is really empty.
- */
- ilock(ctlr);
- while(!(csr8r(ctlr, Lsr) & Temt))
- ;
-
- /*
- * Set the trigger level, default is the max.
- * value.
- * Some UARTs require FIFOena to be set before
- * other bits can take effect, so set it twice.
- */
- ctlr->fena = level;
- switch(level){
- case 0:
- break;
- case 1:
- level = FIFO1|FIFOena;
- break;
- case 4:
- level = FIFO4|FIFOena;
- break;
- case 8:
- level = FIFO8|FIFOena;
- break;
- default:
- level = FIFO14|FIFOena;
- break;
- }
- csr8w(ctlr, Fcr, level);
- csr8w(ctlr, Fcr, level);
- iunlock(ctlr);
-}
-
-static void
-i8250dtr(Uart* uart, int on)
-{
- Ctlr *ctlr;
-
- /*
- * Toggle DTR.
- */
- ctlr = uart->regs;
- if(on)
- ctlr->sticky[Mcr] |= Dtr;
- else
- ctlr->sticky[Mcr] &= ~Dtr;
- csr8w(ctlr, Mcr, 0);
-}
-
-static void
-i8250rts(Uart* uart, int on)
-{
- Ctlr *ctlr;
-
- /*
- * Toggle RTS.
- */
- ctlr = uart->regs;
- if(on)
- ctlr->sticky[Mcr] |= Rts;
- else
- ctlr->sticky[Mcr] &= ~Rts;
- csr8w(ctlr, Mcr, 0);
-}
-
-static void
-i8250modemctl(Uart* uart, int on)
-{
- Ctlr *ctlr;
-
- ctlr = uart->regs;
- ilock(&uart->tlock);
- if(on){
- ctlr->sticky[Ier] |= Ems;
- csr8w(ctlr, Ier, ctlr->sticky[Ier]);
- uart->modem = 1;
- uart->cts = csr8r(ctlr, Msr) & Cts;
- }
- else{
- ctlr->sticky[Ier] &= ~Ems;
- csr8w(ctlr, Ier, ctlr->sticky[Ier]);
- uart->modem = 0;
- uart->cts = 1;
- }
- iunlock(&uart->tlock);
-
- /* modem needs fifo */
- (*uart->phys->fifo)(uart, on);
-}
-
-static int
-i8250parity(Uart* uart, int parity)
-{
- int lcr;
- Ctlr *ctlr;
-
- ctlr = uart->regs;
- lcr = ctlr->sticky[Lcr] & ~(Eps|Pen);
-
- switch(parity){
- case 'e':
- lcr |= Eps|Pen;
- break;
- case 'o':
- lcr |= Pen;
- break;
- case 'n':
- break;
- default:
- return -1;
- }
- ctlr->sticky[Lcr] = lcr;
- csr8w(ctlr, Lcr, 0);
-
- uart->parity = parity;
-
- return 0;
-}
-
-static int
-i8250stop(Uart* uart, int stop)
-{
- int lcr;
- Ctlr *ctlr;
-
- ctlr = uart->regs;
- lcr = ctlr->sticky[Lcr] & ~Stb;
-
- switch(stop){
- case 1:
- break;
- case 2:
- lcr |= Stb;
- break;
- default:
- return -1;
- }
- ctlr->sticky[Lcr] = lcr;
- csr8w(ctlr, Lcr, 0);
-
- uart->stop = stop;
-
- return 0;
-}
-
-static int
-i8250bits(Uart* uart, int bits)
-{
- int lcr;
- Ctlr *ctlr;
-
- ctlr = uart->regs;
- lcr = ctlr->sticky[Lcr] & ~WlsMASK;
-
- switch(bits){
- case 5:
- lcr |= Wls5;
- break;
- case 6:
- lcr |= Wls6;
- break;
- case 7:
- lcr |= Wls7;
- break;
- case 8:
- lcr |= Wls8;
- break;
- default:
- return -1;
- }
- ctlr->sticky[Lcr] = lcr;
- csr8w(ctlr, Lcr, 0);
-
- uart->bits = bits;
-
- return 0;
-}
-
-static int
-i8250baud(Uart* uart, int baud)
-{
- ulong bgc;
- Ctlr *ctlr;
-
- /*
- * Set the Baud rate by calculating and setting the Baud rate
- * Generator Constant. This will work with fairly non-standard
- * Baud rates.
- */
- if(uart->freq == 0 || baud <= 0)
- return -1;
- bgc = (uart->freq+8*baud-1)/(16*baud);
-
- ctlr = uart->regs;
- csr8w(ctlr, Lcr, Dlab);
- outb(ctlr->io+Dlm, bgc>>8);
- outb(ctlr->io+Dll, bgc);
- csr8w(ctlr, Lcr, 0);
-
- uart->baud = baud;
-
- return 0;
-}
-
-static void
-i8250break(Uart* uart, int ms)
-{
- Ctlr *ctlr;
-
- /*
- * Send a break.
- */
- if(ms <= 0)
- ms = 200;
-
- ctlr = uart->regs;
- csr8w(ctlr, Lcr, Brk);
- tsleep(&up->sleep, return0, 0, ms);
- csr8w(ctlr, Lcr, 0);
-}
-
-static void
-i8250kick(Uart* uart)
-{
- int i;
- Ctlr *ctlr;
-
- if(uart->cts == 0 || uart->blocked)
- return;
-
- /*
- * 128 here is an arbitrary limit to make sure
- * we don't stay in this loop too long. If the
- * chip's output queue is longer than 128, too
- * bad -- presotto
- */
- ctlr = uart->regs;
- for(i = 0; i < 128; i++){
- if(!(csr8r(ctlr, Lsr) & Thre))
- break;
- if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
- break;
- outb(ctlr->io+Thr, *(uart->op++));
- }
-}
-
-static void
-i8250interrupt(Ureg*, void* arg)
-{
- Ctlr *ctlr;
- Uart *uart;
- int iir, lsr, old, r;
-
- uart = arg;
-
- ctlr = uart->regs;
- for(iir = csr8r(ctlr, Iir); !(iir & Ip); iir = csr8r(ctlr, Iir)){
- switch(iir & IirMASK){
- case Ims: /* Ms interrupt */
- r = csr8r(ctlr, Msr);
- if(r & Dcts){
- ilock(&uart->tlock);
- old = uart->cts;
- uart->cts = r & Cts;
- if(old == 0 && uart->cts)
- uart->ctsbackoff = 2;
- iunlock(&uart->tlock);
- }
- if(r & Ddsr){
- old = r & Dsr;
- if(uart->hup_dsr && uart->dsr && !old)
- uart->dohup = 1;
- uart->dsr = old;
- }
- if(r & Ddcd){
- old = r & Dcd;
- if(uart->hup_dcd && uart->dcd && !old)
- uart->dohup = 1;
- uart->dcd = old;
- }
- break;
- case Ithre: /* Thr Empty */
- uartkick(uart);
- break;
- case Irda: /* Received Data Available */
- case Irls: /* Receiver Line Status */
- case Ictoi: /* Character Time-out Indication */
- /*
- * Consume any received data.
- * If the received byte came in with a break,
- * parity or framing error, throw it away;
- * overrun is an indication that something has
- * already been tossed.
- */
- while((lsr = csr8r(ctlr, Lsr)) & Dr){
- if(lsr & (FIFOerr|Oe))
- uart->oerr++;
- if(lsr & Pe)
- uart->perr++;
- if(lsr & Fe)
- uart->ferr++;
- r = csr8r(ctlr, Rbr);
- if(!(lsr & (Bi|Fe|Pe)))
- uartrecv(uart, r);
- }
- break;
-
- default:
- iprint("weird uart interrupt 0x%2.2uX\n", iir);
- break;
- }
- }
-}
-
-static void
-i8250disable(Uart* uart)
-{
- Ctlr *ctlr;
-
- /*
- * Turn off DTR and RTS, disable interrupts and fifos.
- */
- (*uart->phys->dtr)(uart, 0);
- (*uart->phys->rts)(uart, 0);
- (*uart->phys->fifo)(uart, 0);
-
- ctlr = uart->regs;
- ctlr->sticky[Ier] = 0;
- csr8w(ctlr, Ier, ctlr->sticky[Ier]);
-
- if(ctlr->iena != 0){
- if(intrdisable(ctlr->irq, i8250interrupt, uart, ctlr->tbdf, uart->name) == 0)
- ctlr->iena = 0;
- }
-}
-
-static void
-i8250enable(Uart* uart, int ie)
-{
- Ctlr *ctlr;
-
- ctlr = uart->regs;
-
- /*
- * Check if there is a FIFO.
- * Changing the FIFOena bit in Fcr flushes data
- * from both receive and transmit FIFOs; there's
- * no easy way to guarantee not losing data on
- * the receive side, but it's possible to wait until
- * the transmitter is really empty.
- * Also, reading the Iir outwith i8250interrupt()
- * can be dangerous, but this should only happen
- * once, before interrupts are enabled.
- */
- ilock(ctlr);
- if(!ctlr->checkfifo){
- /*
- * Wait until the transmitter is really empty.
- */
- while(!(csr8r(ctlr, Lsr) & Temt))
- ;
- csr8w(ctlr, Fcr, FIFOena);
- if(csr8r(ctlr, Iir) & Ifena)
- ctlr->hasfifo = 1;
- csr8w(ctlr, Fcr, 0);
- ctlr->checkfifo = 1;
- }
- iunlock(ctlr);
-
- /*
- * Enable interrupts and turn on DTR and RTS.
- * Be careful if this is called to set up a polled serial line
- * early on not to try to enable interrupts as interrupt-
- * -enabling mechanisms might not be set up yet.
- */
- if(ie){
- if(ctlr->iena == 0){
- intrenable(ctlr->irq, i8250interrupt, uart, ctlr->tbdf, uart->name);
- ctlr->iena = 1;
- }
- ctlr->sticky[Ier] = Ethre|Erda;
- ctlr->sticky[Mcr] |= Ie;
- }
- else{
- ctlr->sticky[Ier] = 0;
- ctlr->sticky[Mcr] = 0;
- }
- csr8w(ctlr, Ier, ctlr->sticky[Ier]);
- csr8w(ctlr, Mcr, ctlr->sticky[Mcr]);
-
- (*uart->phys->dtr)(uart, 1);
- (*uart->phys->rts)(uart, 1);
-
- /*
- * During startup, the i8259 interrupt controller is reset.
- * This may result in a lost interrupt from the i8250 uart.
- * The i8250 thinks the interrupt is still outstanding and does not
- * generate any further interrupts. The workaround is to call the
- * interrupt handler to clear any pending interrupt events.
- * Note: this must be done after setting Ier.
- */
- if(ie)
- i8250interrupt(nil, uart);
-}
-
-void*
-i8250alloc(int io, int irq, int tbdf)
-{
- Ctlr *ctlr;
-
- if((ctlr = malloc(sizeof(Ctlr))) != nil){
- ctlr->io = io;
- ctlr->irq = irq;
- ctlr->tbdf = tbdf;
- }
-
- return ctlr;
-}
-
-static Uart*
-i8250pnp(void)
-{
- return i8250uart;
-}
-
-static int
-i8250getc(Uart *uart)
-{
- Ctlr *ctlr;
-
- ctlr = uart->regs;
- while(!(csr8r(ctlr, Lsr)&Dr))
- delay(1);
- return csr8r(ctlr, Rbr);
-}
-
-static void
-i8250putc(Uart *uart, int c)
-{
- int i;
- Ctlr *ctlr;
-
- ctlr = uart->regs;
- for(i = 0; !(csr8r(ctlr, Lsr)&Thre) && i < 128; i++)
- delay(1);
- outb(ctlr->io+Thr, c);
- for(i = 0; !(csr8r(ctlr, Lsr)&Thre) && i < 128; i++)
- delay(1);
-}
-
-PhysUart i8250physuart = {
- .name = "i8250",
- .pnp = i8250pnp,
- .enable = i8250enable,
- .disable = i8250disable,
- .kick = i8250kick,
- .dobreak = i8250break,
- .baud = i8250baud,
- .bits = i8250bits,
- .stop = i8250stop,
- .parity = i8250parity,
- .modemctl = i8250modemctl,
- .rts = i8250rts,
- .dtr = i8250dtr,
- .status = i8250status,
- .fifo = i8250fifo,
- .getc = i8250getc,
- .putc = i8250putc,
-};
-
-void
-i8250console(void)
-{
- Uart *uart;
- int n;
- char *cmd, *p;
-
- if((p = getconf("console")) == nil)
- return;
- n = strtoul(p, &cmd, 0);
- if(p == cmd)
- return;
- switch(n){
- default:
- return;
- case 0:
- uart = &i8250uart[0];
- break;
- case 1:
- uart = &i8250uart[1];
- break;
- }
-
- (*uart->phys->enable)(uart, 0);
- uartctl(uart, "b9600 l8 pn s1");
- if(*cmd != '\0')
- uartctl(uart, cmd);
-
- consuart = uart;
- uart->console = 1;
-}
-
-void
-i8250mouse(char* which, int (*putc)(Queue*, int), int setb1200)
-{
- char *p;
- int port;
-
- port = strtol(which, &p, 0);
- if(p == which || port < 0 || port > 1)
- error(Ebadarg);
- uartmouse(&i8250uart[port], putc, setb1200);
-}
-
-void
-i8250setmouseputc(char* which, int (*putc)(Queue*, int))
-{
- char *p;
- int port;
-
- port = strtol(which, &p, 0);
- if(p == which || port < 0 || port > 1)
- error(Ebadarg);
- uartsetmouseputc(&i8250uart[port], putc);
-
-}
diff --git a/os/pc/uartisa.c b/os/pc/uartisa.c
deleted file mode 100644
index de4a8dcc..00000000
--- a/os/pc/uartisa.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/uart.h"
-
-extern PhysUart i8250physuart;
-extern PhysUart isaphysuart;
-extern void* i8250alloc(int, int, int);
-
-static Uart*
-uartisa(int ctlrno, ISAConf* isa)
-{
- int io;
- void *ctlr;
- Uart *uart;
- char buf[64];
-
- io = isa->port;
- snprint(buf, sizeof(buf), "%s%d", isaphysuart.name, ctlrno);
- if(ioalloc(io, 8, 0, buf) < 0){
- print("uartisa: I/O 0x%uX in use\n", io);
- return nil;
- }
-
- uart = malloc(sizeof(Uart));
- ctlr = i8250alloc(io, isa->irq, BUSUNKNOWN);
- if(ctlr == nil){
- iofree(io);
- free(uart);
- return nil;
- }
-
- uart->regs = ctlr;
- snprint(buf, sizeof(buf), "COM%d", ctlrno+1);
- kstrdup(&uart->name, buf);
- uart->freq = isa->freq;
- uart->phys = &i8250physuart;
-
- return uart;
-}
-
-static Uart*
-uartisapnp(void)
-{
- int ctlrno;
- ISAConf isa;
- Uart *head, *tail, *uart;
-
- /*
- * Look for up to 4 discrete UARTs on the ISA bus.
- * All suitable devices are configured to simply point
- * to the generic i8250 driver.
- */
- head = tail = nil;
- for(ctlrno = 2; ctlrno < 6; ctlrno++){
- memset(&isa, 0, sizeof(isa));
- if(!isaconfig("uart", ctlrno, &isa))
- continue;
- if(strcmp(isa.type, "isa") != 0)
- continue;
- if(isa.port == 0 || isa.irq == 0)
- continue;
- if(isa.freq == 0)
- isa.freq = 1843200;
- uart = uartisa(ctlrno, &isa);
- if(uart == nil)
- continue;
- if(head != nil)
- tail->next = uart;
- else
- head = uart;
- tail = uart;
- }
-
- return head;
-}
-
-PhysUart isaphysuart = {
- .name = "UartISA",
- .pnp = uartisapnp,
- .enable = nil,
- .disable = nil,
- .kick = nil,
- .dobreak = nil,
- .baud = nil,
- .bits = nil,
- .stop = nil,
- .parity = nil,
- .modemctl = nil,
- .rts = nil,
- .dtr = nil,
- .status = nil,
- .fifo = nil,
-};
diff --git a/os/pc/uartpci.c b/os/pc/uartpci.c
deleted file mode 100644
index e84592b0..00000000
--- a/os/pc/uartpci.c
+++ /dev/null
@@ -1,137 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/uart.h"
-
-extern PhysUart i8250physuart;
-extern PhysUart pciphysuart;
-extern void* i8250alloc(int, int, int);
-
-static Uart*
-uartpci(int ctlrno, Pcidev* p, int barno, int n, int freq, char* name)
-{
- int i, io;
- void *ctlr;
- char buf[64];
- Uart *head, *uart;
-
- io = p->mem[barno].bar & ~0x01;
- snprint(buf, sizeof(buf), "%s%d", pciphysuart.name, ctlrno);
- if(ioalloc(io, p->mem[barno].size, 0, buf) < 0){
- print("uartpci: I/O 0x%uX in use\n", io);
- return nil;
- }
-
- head = uart = malloc(sizeof(Uart)*n);
-
- for(i = 0; i < n; i++){
- ctlr = i8250alloc(io, p->intl, p->tbdf);
- io += 8;
- if(ctlr == nil)
- continue;
-
- uart->regs = ctlr;
- snprint(buf, sizeof(buf), "%s.%8.8uX", name, p->tbdf);
- kstrdup(&uart->name, buf);
- uart->freq = freq;
- uart->phys = &i8250physuart;
- if(uart != head)
- (uart-1)->next = uart;
- uart++;
- }
-
- return head;
-}
-
-static Uart*
-uartpcipnp(void)
-{
- Pcidev *p;
- char *name;
- int ctlrno, n, subid;
- Uart *head, *tail, *uart;
-
- /*
- * Loop through all PCI devices looking for simple serial
- * controllers (ccrb == 0x07) and configure the ones which
- * are familiar. All suitable devices are configured to
- * simply point to the generic i8250 driver.
- */
- head = tail = nil;
- ctlrno = 0;
- for(p = pcimatch(nil, 0, 0); p != nil; p = pcimatch(p, 0, 0)){
- if(p->ccrb != 0x07 || p->ccru != 0)
- continue;
-
- switch((p->did<<16)|p->vid){
- default:
- continue;
- case (0x9050<<16)|0x10B5: /* Perle PCI-Fast4 series */
- case (0x9030<<16)|0x10B5: /* Perle Ultraport series */
- /*
- * These devices consists of a PLX bridge (the above
- * PCI VID+DID) behind which are some 16C654 UARTs.
- * Must check the subsystem VID and DID for correct
- * match.
- */
- subid = pcicfgr16(p, PciSVID);
- subid |= pcicfgr16(p, PciSID)<<16;
- switch(subid){
- default:
- continue;
- case (0x0011<<16)|0x12E0: /* Perle PCI-Fast16 */
- n = 16;
- name = "PCI-Fast16";
- break;
- case (0x0021<<16)|0x12E0: /* Perle PCI-Fast8 */
- n = 8;
- name = "PCI-Fast8";
- break;
- case (0x0031<<16)|0x12E0: /* Perle PCI-Fast4 */
- n = 4;
- name = "PCI-Fast4";
- break;
- case (0x0021<<16)|0x155F: /* Perle Ultraport8 */
- n = 8;
- name = "Ultraport8"; /* 16C754 UARTs */
- break;
- }
- uart = uartpci(ctlrno, p, 2, n, 7372800, name);
- if(uart == nil)
- continue;
- break;
- }
-
- if(head != nil)
- tail->next = uart;
- else
- head = uart;
- for(tail = uart; tail->next != nil; tail = tail->next)
- ;
- ctlrno++;
- }
-
- return head;
-}
-
-PhysUart pciphysuart = {
- .name = "UartPCI",
- .pnp = uartpcipnp,
- .enable = nil,
- .disable = nil,
- .kick = nil,
- .dobreak = nil,
- .baud = nil,
- .bits = nil,
- .stop = nil,
- .parity = nil,
- .modemctl = nil,
- .rts = nil,
- .dtr = nil,
- .status = nil,
- .fifo = nil,
-};
diff --git a/os/pc/usb.h b/os/pc/usb.h
deleted file mode 100644
index 32da4d51..00000000
--- a/os/pc/usb.h
+++ /dev/null
@@ -1,160 +0,0 @@
-typedef struct Ctlr Ctlr;
-typedef struct Endpt Endpt;
-typedef struct Udev Udev;
-typedef struct Usbhost Usbhost;
-
-enum
-{
- MaxUsb = 10, /* max number of USB Host Controller Interfaces (Usbhost*) */
- MaxUsbDev = 32, /* max number of attached USB devices, including root hub (Udev*) */
-
- /*
- * USB packet definitions...
- */
- TokIN = 0x69,
- TokOUT = 0xE1,
- TokSETUP = 0x2D,
-
- /* request type */
- RH2D = 0<<7,
- RD2H = 1<<7,
- Rstandard = 0<<5,
- Rclass = 1<<5,
- Rvendor = 2<<5,
- Rdevice = 0,
- Rinterface = 1,
- Rendpt = 2,
- Rother = 3,
-};
-
-#define Class(csp) ((csp)&0xff)
-#define Subclass(csp) (((csp)>>8)&0xff)
-#define Proto(csp) (((csp)>>16)&0xff)
-#define CSP(c, s, p) ((c) | ((s)<<8) | ((p)<<16))
-
-/*
- * device endpoint
- */
-struct Endpt
-{
- Ref;
- Lock;
- int x; /* index in Udev.ep */
- int id; /* hardware endpoint address */
- int maxpkt; /* maximum packet size (from endpoint descriptor) */
- int data01; /* 0=DATA0, 1=DATA1 */
- uchar eof;
- ulong csp;
- uchar mode; /* OREAD, OWRITE, ORDWR */
- uchar nbuf; /* number of buffers allowed */
- uchar iso;
- uchar debug;
- uchar active; /* listed for examination by interrupts */
- int setin;
- /* ISO related: */
- int hz;
- int remain; /* for packet size calculations */
- int samplesz;
- int sched; /* schedule index; -1 if undefined or aperiodic */
- int pollms; /* polling interval in msec */
- int psize; /* (remaining) size of this packet */
- int off; /* offset into packet */
- /* Real-time iso stuff */
- ulong foffset; /* file offset (to detect seeks) */
- ulong poffset; /* offset of next packet to be queued */
- ulong toffset; /* offset associated with time */
- vlong time; /* timeassociated with offset */
- int buffered; /* bytes captured but unread, or written but unsent */
- /* end ISO stuff */
-
- Udev* dev; /* owning device */
-
- ulong nbytes;
- ulong nblocks;
-
- void *private;
-
- // all the rest could (should?) move to the driver private structure; except perhaps err
- QLock rlock;
- Rendez rr;
- Queue* rq;
- QLock wlock;
- Rendez wr;
- Queue* wq;
-
- int ntd;
- char* err; // needs to be global for unstall; fix?
-
- Endpt* activef; /* active endpoint list */
-};
-
-/* device parameters */
-enum
-{
- /* Udev.state */
- Disabled = 0,
- Attached,
- Enabled,
- Assigned,
- Configured,
-
- /* Udev.class */
- Noclass = 0,
- Hubclass = 9,
-};
-
-/*
- * active USB device
- */
-struct Udev
-{
- Ref;
- Lock;
- Usbhost *uh;
- int x; /* index in usbdev[] */
- int busy;
- int state;
- int id;
- uchar port; /* port number on connecting hub */
- ulong csp;
- ushort vid; /* vendor id */
- ushort did; /* product id */
- int ls;
- int npt;
- Endpt* ep[16]; /* active end points */
- Udev* ports; /* active ports, if hub */
- Udev* next; /* next device on this hub */
-};
-
-/*
- * One of these per active Host Controller Interface (HCI)
- */
-struct Usbhost
-{
- ISAConf; /* hardware info */
- int tbdf; /* type+busno+devno+funcno */
-
- QLock; /* protects namespace state */
- int idgen; /* version number to distinguish new connections */
- Udev* dev[MaxUsbDev]; /* device endpoints managed by this HCI */
-
- void (*init)(Usbhost*);
- void (*interrupt)(Ureg*, void*);
-
- void (*portinfo)(Usbhost*, char*, char*);
- void (*portreset)(Usbhost*, int);
- void (*portenable)(Usbhost*, int, int);
-
- void (*epalloc)(Usbhost*, Endpt*);
- void (*epfree)(Usbhost*, Endpt*);
- void (*epopen)(Usbhost*, Endpt*);
- void (*epclose)(Usbhost*, Endpt*);
- void (*epmode)(Usbhost*, Endpt*);
-
- long (*read)(Usbhost*, Endpt*, void*, long, vlong);
- long (*write)(Usbhost*, Endpt*, void*, long, vlong, int);
-
- void *ctlr;
-};
-
-extern void addusbtype(char*, int(*)(Usbhost*));
diff --git a/os/pc/usbuhci.c b/os/pc/usbuhci.c
deleted file mode 100644
index 4d65726c..00000000
--- a/os/pc/usbuhci.c
+++ /dev/null
@@ -1,1538 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#include "usb.h"
-
-#define XPRINT if(debug)print
-
-static int Chatty = 0;
-static int debug = 0;
-
-static char Estalled[] = "usb endpoint stalled";
-
-/*
- * UHCI interface registers and bits
- */
-enum
-{
- /* i/o space */
- Cmd = 0,
- Status = 2,
- Usbintr = 4,
- Frnum = 6,
- Flbaseadd = 8,
- SOFMod = 0xC,
- Portsc0 = 0x10,
- Portsc1 = 0x12,
-
- /* port status */
- Suspend = 1<<12,
- PortReset = 1<<9,
- SlowDevice = 1<<8,
- ResumeDetect = 1<<6,
- PortChange = 1<<3, /* write 1 to clear */
- PortEnable = 1<<2,
- StatusChange = 1<<1, /* write 1 to clear */
- DevicePresent = 1<<0,
-
- NFRAME = 1024,
- FRAMESIZE= NFRAME*sizeof(ulong), /* fixed by hardware; aligned to same */
-
- Vf = 1<<2, /* TD only */
- IsQH = 1<<1,
- Terminate = 1<<0,
-
- /* TD.status */
- SPD = 1<<29,
- ErrLimit0 = 0<<27,
- ErrLimit1 = 1<<27,
- ErrLimit2 = 2<<27,
- ErrLimit3 = 3<<27,
- LowSpeed = 1<<26,
- IsoSelect = 1<<25,
- IOC = 1<<24,
- Active = 1<<23,
- Stalled = 1<<22,
- DataBufferErr = 1<<21,
- Babbling = 1<<20,
- NAKed = 1<<19,
- CRCorTimeout = 1<<18,
- BitstuffErr = 1<<17,
- AnyError = (Stalled | DataBufferErr | Babbling | NAKed | CRCorTimeout | BitstuffErr),
-
- /* TD.dev */
- IsDATA1 = 1<<19,
-
- /* TD.flags (software) */
- CancelTD= 1<<0,
- IsoClean= 1<<2,
-};
-
-static struct
-{
- int bit;
- char *name;
-}
-portstatus[] =
-{
- { Suspend, "suspend", },
- { PortReset, "reset", },
- { SlowDevice, "lowspeed", },
- { ResumeDetect, "resume", },
- { PortChange, "portchange", },
- { PortEnable, "enable", },
- { StatusChange, "statuschange", },
- { DevicePresent, "present", },
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Endptx Endptx;
-typedef struct QH QH;
-typedef struct TD TD;
-
-/*
- * software structures
- */
-struct Ctlr
-{
- Lock; /* protects state shared with interrupt (eg, free list) */
- Ctlr* next;
- Pcidev* pcidev;
- int active;
-
- int io;
- ulong* frames; /* frame list */
- ulong* frameld; /* real time load on each of the frame list entries */
- QLock resetl; /* lock controller during USB reset */
-
- TD* tdpool;
- TD* freetd;
- QH* qhpool;
- QH* freeqh;
-
- QH* ctlq; /* queue for control i/o */
- QH* bwsop; /* empty bandwidth sop (to PIIX4 errata specifications) */
- QH* bulkq; /* queue for bulk i/o (points back to bandwidth sop) */
- QH* recvq; /* receive queues for bulk i/o */
-
- Udev* ports[2];
-
- struct {
- Lock;
- Endpt* f;
- } activends;
-
- long usbints; /* debugging */
- long framenumber;
- long frameptr;
- long usbbogus;
-};
-
-#define IN(x) ins(ctlr->io+(x))
-#define OUT(x, v) outs(ctlr->io+(x), (v))
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-struct Endptx
-{
- QH* epq; /* queue of TDs for this endpoint */
-
- /* ISO related: */
- void* tdalloc;
- void* bpalloc;
- uchar* bp0; /* first block in array */
- TD * td0; /* first td in array */
- TD * etd; /* pointer into circular list of TDs for isochronous ept */
- TD * xtd; /* next td to be cleaned */
-};
-
-/*
- * UHCI hardware structures, aligned on 16-byte boundary
- */
-struct TD
-{
- ulong link;
- ulong status; /* controller r/w */
- ulong dev;
- ulong buffer;
-
- /* software */
- ulong flags;
- union{
- Block* bp; /* non-iso */
- ulong offset; /* iso */
- };
- Endpt* ep;
- TD* next;
-};
-#define TFOL(p) ((TD*)KADDR((ulong)(p) & ~(0xF|PCIWINDOW)))
-
-struct QH
-{
- ulong head;
- ulong entries; /* address of next TD or QH to process (updated by controller) */
-
- /* software */
- QH* hlink;
- TD* first;
- QH* next; /* free list */
- TD* last;
- ulong _d1; /* fillers */
- ulong _d2;
-};
-#define QFOL(p) ((QH*)KADDR((ulong)(p) & ~(0xF|PCIWINDOW)))
-
-static TD *
-alloctd(Ctlr *ctlr)
-{
- TD *t;
-
- ilock(ctlr);
- t = ctlr->freetd;
- if(t == nil)
- panic("alloctd"); /* TO DO */
- ctlr->freetd = t->next;
- t->next = nil;
- iunlock(ctlr);
- t->ep = nil;
- t->bp = nil;
- t->status = 0;
- t->link = Terminate;
- t->buffer = 0;
- t->flags = 0;
- return t;
-}
-
-static void
-freetd(Ctlr *ctlr, TD *t)
-{
- t->ep = nil;
- if(t->bp)
- freeb(t->bp);
- t->bp = nil;
- ilock(ctlr);
- t->buffer = 0xdeadbeef;
- t->next = ctlr->freetd;
- ctlr->freetd = t;
- iunlock(ctlr);
-}
-
-static void
-dumpdata(Block *b, int n)
-{
- int i;
-
- XPRINT("\tb %8.8lux[%d]: ", (ulong)b->rp, n);
- if(n > 16)
- n = 16;
- for(i=0; i<n; i++)
- XPRINT(" %2.2ux", b->rp[i]);
- XPRINT("\n");
-}
-
-static void
-dumptd(TD *t, int follow)
-{
- int i, n;
- char buf[20], *s;
- TD *t0;
-
- t0 = t;
- while(t){
- i = t->dev & 0xFF;
- if(i == TokOUT || i == TokSETUP)
- n = ((t->dev>>21) + 1) & 0x7FF;
- else if((t->status & Active) == 0)
- n = (t->status + 1) & 0x7FF;
- else
- n = 0;
- s = buf;
- if(t->status & Active)
- *s++ = 'A';
- if(t->status & Stalled)
- *s++ = 'S';
- if(t->status & DataBufferErr)
- *s++ = 'D';
- if(t->status & Babbling)
- *s++ = 'B';
- if(t->status & NAKed)
- *s++ = 'N';
- if(t->status & CRCorTimeout)
- *s++ = 'T';
- if(t->status & BitstuffErr)
- *s++ = 'b';
- if(t->status & LowSpeed)
- *s++ = 'L';
- *s = 0;
- XPRINT("td %8.8lux: ", t);
- XPRINT("l=%8.8lux s=%8.8lux d=%8.8lux b=%8.8lux %8.8lux f=%8.8lux\n",
- t->link, t->status, t->dev, t->buffer, t->bp?(ulong)t->bp->rp:0, t->flags);
- XPRINT("\ts=%s,ep=%ld,d=%ld,D=%ld\n",
- buf, (t->dev>>15)&0xF, (t->dev>>8)&0xFF, (t->dev>>19)&1);
- if(debug && t->bp && (t->flags & CancelTD) == 0)
- dumpdata(t->bp, n);
- if(!follow || t->link & Terminate || t->link & IsQH)
- break;
- t = TFOL(t->link);
- if(t == t0)
- break; /* looped */
- }
-}
-
-static TD *
-alloctde(Ctlr *ctlr, Endpt *e, int pid, int n)
-{
- TD *t;
- int tog, id;
-
- t = alloctd(ctlr);
- id = (e->x<<7)|(e->dev->x&0x7F);
- tog = 0;
- if(e->data01 && pid != TokSETUP)
- tog = IsDATA1;
- t->ep = e;
- t->status = ErrLimit3 | Active | IOC; /* or put IOC only on last? */
- if(e->dev->ls)
- t->status |= LowSpeed;
- t->dev = ((n-1)<<21) | ((id&0x7FF)<<8) | pid | tog;
- return t;
-}
-
-static QH *
-allocqh(Ctlr *ctlr)
-{
- QH *qh;
-
- ilock(ctlr);
- qh = ctlr->freeqh;
- if(qh == nil)
- panic("allocqh"); /* TO DO */
- ctlr->freeqh = qh->next;
- qh->next = nil;
- iunlock(ctlr);
- qh->head = Terminate;
- qh->entries = Terminate;
- qh->hlink = nil;
- qh->first = nil;
- qh->last = nil;
- return qh;
-}
-
-static void
-freeqh(Ctlr *ctlr, QH *qh)
-{
- ilock(ctlr);
- qh->next = ctlr->freeqh;
- ctlr->freeqh = qh;
- iunlock(ctlr);
-}
-
-static void
-dumpqh(QH *q)
-{
- int i;
- QH *q0;
-
- q0 = q;
- for(i = 0; q != nil && i < 10; i++){
- XPRINT("qh %8.8lux: %8.8lux %8.8lux\n", q, q->head, q->entries);
- if((q->entries & Terminate) == 0)
- dumptd(TFOL(q->entries), 1);
- if(q->head & Terminate)
- break;
- if((q->head & IsQH) == 0){
- XPRINT("head:");
- dumptd(TFOL(q->head), 1);
- break;
- }
- q = QFOL(q->head);
- if(q == q0)
- break; /* looped */
- }
-}
-
-static void
-queuetd(Ctlr *ctlr, QH *q, TD *t, int vf, char *why)
-{
- TD *lt;
-
- for(lt = t; lt->next != nil; lt = lt->next)
- lt->link = PCIWADDR(lt->next) | vf;
- lt->link = Terminate;
- ilock(ctlr);
- XPRINT("queuetd %s: t=%p lt=%p q=%p first=%p last=%p entries=%.8lux\n",
- why, t, lt, q, q->first, q->last, q->entries);
- if(q->first != nil){
- q->last->link = PCIWADDR(t) | vf;
- q->last->next = t;
- }else{
- q->first = t;
- q->entries = PCIWADDR(t);
- }
- q->last = lt;
- XPRINT(" t=%p q=%p first=%p last=%p entries=%.8lux\n",
- t, q, q->first, q->last, q->entries);
- dumpqh(q);
- iunlock(ctlr);
-}
-
-static void
-cleantd(Ctlr *ctlr, TD *t, int discard)
-{
- Block *b;
- int n, err;
-
- XPRINT("cleanTD: %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer);
- if(t->ep != nil && t->ep->debug)
- dumptd(t, 0);
- if(t->status & Active)
- panic("cleantd Active");
- err = t->status & (AnyError&~NAKed);
- /* TO DO: on t->status&AnyError, q->entries will not have advanced */
- if (err) {
- XPRINT("cleanTD: Error %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer);
-// print("cleanTD: Error %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer);
- }
- switch(t->dev&0xFF){
- case TokIN:
- if(discard || (t->flags & CancelTD) || t->ep == nil || t->ep->x!=0&&err){
- if(t->ep != nil){
- if(err != 0)
- t->ep->err = err==Stalled? Estalled: Eio;
- wakeup(&t->ep->rr); /* in case anyone cares */
- }
- break;
- }
- b = t->bp;
- n = (t->status + 1) & 0x7FF;
- if(n > b->lim - b->wp)
- n = 0;
- b->wp += n;
- if(Chatty)
- dumpdata(b, n);
- t->bp = nil;
- t->ep->nbytes += n;
- t->ep->nblocks++;
- qpass(t->ep->rq, b); /* TO DO: flow control */
- wakeup(&t->ep->rr); /* TO DO */
- break;
- case TokSETUP:
- XPRINT("cleanTD: TokSETUP %lux\n", &t->ep);
- /* don't really need to wakeup: subsequent IN or OUT gives status */
- if(t->ep != nil) {
- wakeup(&t->ep->wr); /* TO DO */
- XPRINT("cleanTD: wakeup %lux\n", &t->ep->wr);
- }
- break;
- case TokOUT:
- /* TO DO: mark it done somewhere */
- XPRINT("cleanTD: TokOut %lux\n", &t->ep);
- if(t->ep != nil){
- if(t->bp){
- n = BLEN(t->bp);
- t->ep->nbytes += n;
- t->ep->nblocks++;
- }
- if(t->ep->x!=0 && err != 0)
- t->ep->err = err==Stalled? Estalled: Eio;
- if(--t->ep->ntd < 0)
- panic("cleantd ntd");
- wakeup(&t->ep->wr); /* TO DO */
- XPRINT("cleanTD: wakeup %lux\n", &t->ep->wr);
- }
- break;
- }
- freetd(ctlr, t);
-}
-
-static void
-cleanq(Ctlr *ctlr, QH *q, int discard, int vf)
-{
- TD *t, *tp;
-
- ilock(ctlr);
- tp = nil;
- for(t = q->first; t != nil;){
- XPRINT("cleanq: %8.8lux %8.8lux %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer, t->flags, t->next);
- if(t->status & Active){
- if(t->status & NAKed){
- t->status = (t->status & ~NAKed) | IOC; /* ensure interrupt next frame */
- tp = t;
- t = t->next;
- continue;
- }
- if(t->flags & CancelTD){
- XPRINT("cancelTD: %8.8lux\n", (ulong)t);
- t->status = (t->status & ~Active) | IOC; /* ensure interrupt next frame */
- tp = t;
- t = t->next;
- continue;
- }
- tp = t;
- t = t->next;
- continue;
- }
- t->status &= ~IOC;
- if (tp == nil) {
- q->first = t->next;
- if(q->first != nil)
- q->entries = PCIWADDR(q->first);
- else
- q->entries = Terminate;
- } else {
- tp->next = t->next;
- if (t->next != nil)
- tp->link = PCIWADDR(t->next) | vf;
- else
- tp->link = Terminate;
- }
- if (q->last == t)
- q->last = tp;
- iunlock(ctlr);
- cleantd(ctlr, t, discard);
- ilock(ctlr);
- if (tp)
- t = tp->next;
- else
- t = q->first;
- XPRINT("t = %8.8lux\n", t);
- dumpqh(q);
- }
- if(q->first && q->entries != PCIWADDR(q->first)){
- ctlr->usbbogus++;
- q->entries = PCIWADDR(q->first);
- }
- iunlock(ctlr);
-}
-
-static void
-canceltds(Ctlr *ctlr, QH *q, Endpt *e)
-{
- TD *t;
-
- if(q != nil){
- ilock(ctlr);
- for(t = q->first; t != nil; t = t->next)
- if(t->ep == e)
- t->flags |= CancelTD;
- iunlock(ctlr);
- XPRINT("cancel:\n");
- dumpqh(q);
- }
-}
-
-static void
-eptcancel(Ctlr *ctlr, Endpt *e)
-{
- Endptx *x;
-
- if(e == nil)
- return;
- x = e->private;
- canceltds(ctlr, x->epq, e);
- canceltds(ctlr, ctlr->ctlq, e);
- canceltds(ctlr, ctlr->bulkq, e);
-}
-
-static void
-eptactivate(Ctlr *ctlr, Endpt *e)
-{
- ilock(&ctlr->activends);
- if(e->active == 0){
- XPRINT("activate 0x%p\n", e);
- e->active = 1;
- e->activef = ctlr->activends.f;
- ctlr->activends.f = e;
- }
- iunlock(&ctlr->activends);
-}
-
-static void
-eptdeactivate(Ctlr *ctlr, Endpt *e)
-{
- Endpt **l;
-
- /* could be O(1) but not worth it yet */
- ilock(&ctlr->activends);
- if(e->active){
- e->active = 0;
- XPRINT("deactivate 0x%p\n", e);
- for(l = &ctlr->activends.f; *l != e; l = &(*l)->activef)
- if(*l == nil){
- iunlock(&ctlr->activends);
- panic("usb eptdeactivate");
- }
- *l = e->activef;
- }
- iunlock(&ctlr->activends);
-}
-
-static void
-queueqh(Ctlr *ctlr, QH *qh)
-{
- QH *q;
-
- // See if it's already queued
- for (q = ctlr->recvq->next; q; q = q->hlink)
- if (q == qh)
- return;
- if ((qh->hlink = ctlr->recvq->next) == nil)
- qh->head = Terminate;
- else
- qh->head = PCIWADDR(ctlr->recvq->next) | IsQH;
- ctlr->recvq->next = qh;
- ctlr->recvq->entries = PCIWADDR(qh) | IsQH;
-}
-
-static QH*
-qxmit(Ctlr *ctlr, Endpt *e, Block *b, int pid)
-{
- TD *t;
- int n, vf;
- QH *qh;
- Endptx *x;
-
- x = e->private;
- if(b != nil){
- n = BLEN(b);
- t = alloctde(ctlr, e, pid, n);
- t->bp = b;
- t->buffer = PCIWADDR(b->rp);
- }else
- t = alloctde(ctlr, e, pid, 0);
- ilock(ctlr);
- e->ntd++;
- iunlock(ctlr);
- if(e->debug) pprint("QTD: %8.8lux n=%ld\n", t, b?BLEN(b): 0);
- vf = 0;
- if(e->x == 0){
- qh = ctlr->ctlq;
- vf = 0;
- }else if((qh = x->epq) == nil || e->mode != OWRITE){
- qh = ctlr->bulkq;
- vf = Vf;
- }
- queuetd(ctlr, qh, t, vf, "qxmit");
- return qh;
-}
-
-static QH*
-qrcv(Ctlr *ctlr, Endpt *e)
-{
- TD *t;
- Block *b;
- QH *qh;
- int vf;
- Endptx *x;
-
- x = e->private;
- t = alloctde(ctlr, e, TokIN, e->maxpkt);
- b = allocb(e->maxpkt);
- t->bp = b;
- t->buffer = PCIWADDR(b->wp);
- vf = 0;
- if(e->x == 0){
- qh = ctlr->ctlq;
- }else if((qh = x->epq) == nil || e->mode != OREAD){
- qh = ctlr->bulkq;
- vf = Vf;
- }
- queuetd(ctlr, qh, t, vf, "qrcv");
- return qh;
-}
-
-static int
-usbsched(Ctlr *ctlr, int pollms, ulong load)
-{
- int i, d, q;
- ulong best, worst;
-
- best = 1000000;
- q = -1;
- for (d = 0; d < pollms; d++){
- worst = 0;
- for (i = d; i < NFRAME; i++){
- if (ctlr->frameld[i] + load > worst)
- worst = ctlr->frameld[i] + load;
- }
- if (worst < best){
- best = worst;
- q = d;
- }
- }
- return q;
-}
-
-static int
-schedendpt(Ctlr *ctlr, Endpt *e)
-{
- TD *td;
- Endptx *x;
- uchar *bp;
- int i, id, ix, size, frnum;
-
- if(!e->iso || e->sched >= 0)
- return 0;
-
- if (e->active){
- return -1;
- }
- e->off = 0;
- e->sched = usbsched(ctlr, e->pollms, e->maxpkt);
- if(e->sched < 0)
- return -1;
-
- x = e->private;
- if (x->tdalloc || x->bpalloc)
- panic("usb: tdalloc/bpalloc");
- x->tdalloc = mallocz(0x10 + NFRAME*sizeof(TD), 1);
- x->bpalloc = mallocz(0x10 + e->maxpkt*NFRAME/e->pollms, 1);
- x->td0 = (TD*)(((ulong)x->tdalloc + 0xf) & ~0xf);
- x->bp0 = (uchar *)(((ulong)x->bpalloc + 0xf) & ~0xf);
- frnum = (IN(Frnum) + 1) & 0x3ff;
- frnum = (frnum & ~(e->pollms - 1)) + e->sched;
- x->xtd = &x->td0[(frnum+8)&0x3ff]; /* Next td to finish */
- x->etd = nil;
- e->remain = 0;
- e->nbytes = 0;
- td = x->td0;
- for(i = e->sched; i < NFRAME; i += e->pollms){
- bp = x->bp0 + e->maxpkt*i/e->pollms;
- td->buffer = PCIWADDR(bp);
- td->ep = e;
- td->next = &td[1];
- ctlr->frameld[i] += e->maxpkt;
- td++;
- }
- td[-1].next = x->td0;
- for(i = e->sched; i < NFRAME; i += e->pollms){
- ix = (frnum+i) & 0x3ff;
- td = &x->td0[ix];
-
- id = (e->x<<7)|(e->dev->x&0x7F);
- if (e->mode == OREAD)
- /* enable receive on this entry */
- td->dev = ((e->maxpkt-1)<<21) | ((id&0x7FF)<<8) | TokIN;
- else{
- size = (e->hz + e->remain)*e->pollms/1000;
- e->remain = (e->hz + e->remain)*e->pollms%1000;
- size *= e->samplesz;
- td->dev = ((size-1)<<21) | ((id&0x7FF)<<8) | TokOUT;
- }
- td->status = ErrLimit1 | Active | IsoSelect | IOC;
- td->link = ctlr->frames[ix];
- td->flags |= IsoClean;
- ctlr->frames[ix] = PCIWADDR(td);
- }
- return 0;
-}
-
-static void
-unschedendpt(Ctlr *ctlr, Endpt *e)
-{
- int q;
- TD *td;
- Endptx *x;
- ulong *addr;
-
- if(!e->iso || e->sched < 0)
- return;
-
- x = e->private;
- if (x->tdalloc == nil)
- panic("tdalloc");
- for (q = e->sched; q < NFRAME; q += e->pollms){
- td = x->td0++;
- addr = &ctlr->frames[q];
- while(*addr != PADDR(td)) {
- if(*addr & IsQH)
- panic("usb: TD expected");
- addr = &TFOL(*addr)->link;
- }
- *addr = td->link;
- ctlr->frameld[q] -= e->maxpkt;
- }
- free(x->tdalloc);
- free(x->bpalloc);
- x->tdalloc = nil;
- x->bpalloc = nil;
- x->etd = nil;
- x->td0 = nil;
- e->sched = -1;
-}
-
-static void
-epalloc(Usbhost *uh, Endpt *e)
-{
- Endptx *x;
-
- x = malloc(sizeof(Endptx));
- e->private = x;
- x->epq = allocqh(uh->ctlr);
- if(x->epq == nil)
- panic("devendptx");
-}
-
-static void
-epfree(Usbhost *uh, Endpt *e)
-{
- Ctlr *ctlr;
- Endptx *x;
-
- ctlr = uh->ctlr;
- x = e->private;
- if(x->epq != nil)
- freeqh(ctlr, x->epq);
-}
-
-static void
-epopen(Usbhost *uh, Endpt *e)
-{
- Ctlr *ctlr;
-
- ctlr = uh->ctlr;
- if(e->iso && e->active)
- error("already open");
- if(schedendpt(ctlr, e) < 0){
- if(e->active)
- error("cannot schedule USB endpoint, active");
- else
- error("cannot schedule USB endpoint");
- }
- eptactivate(ctlr, e);
-}
-
-static void
-epclose(Usbhost *uh, Endpt *e)
-{
- Ctlr *ctlr;
-
- ctlr = uh->ctlr;
- eptdeactivate(ctlr, e);
- unschedendpt(ctlr, e);
-}
-
-static void
-epmode(Usbhost *uh, Endpt *e)
-{
- Ctlr *ctlr;
- Endptx *x;
-
- ctlr = uh->ctlr;
- x = e->private;
- if(e->iso) {
- if(x->epq != nil) {
- freeqh(ctlr, x->epq);
- x->epq = nil;
- }
- }
- else {
- /* Each bulk device gets a queue head hanging off the
- * bulk queue head
- */
- if(x->epq == nil) {
- x->epq = allocqh(ctlr);
- if(x->epq == nil)
- panic("epbulk: allocqh");
- }
- queueqh(ctlr, x->epq);
- }
-}
-
-static int ioport[] = {-1, Portsc0, Portsc1};
-
-static void
-portreset(Usbhost *uh, int port)
-{
- int i, p;
- Ctlr *ctlr;
-
- ctlr = uh->ctlr;
- if(port != 1 && port != 2)
- error(Ebadarg);
-
- /* should check that device not being configured on other port? */
- p = ioport[port];
- qlock(&ctlr->resetl);
- if(waserror()){
- qunlock(&ctlr->resetl);
- nexterror();
- }
- XPRINT("r: %x\n", IN(p));
- ilock(ctlr);
- OUT(p, PortReset);
- delay(12); /* BUG */
- XPRINT("r2: %x\n", IN(p));
- OUT(p, IN(p) & ~PortReset);
- XPRINT("r3: %x\n", IN(p));
- OUT(p, IN(p) | PortEnable);
- microdelay(64);
- for(i=0; i<1000 && (IN(p) & PortEnable) == 0; i++)
- ;
- XPRINT("r': %x %d\n", IN(p), i);
- OUT(p, (IN(p) & ~PortReset)|PortEnable);
- iunlock(ctlr);
- poperror();
- qunlock(&ctlr->resetl);
-}
-
-static void
-portenable(Usbhost *uh, int port, int on)
-{
- int w, p;
- Ctlr *ctlr;
-
- ctlr = uh->ctlr;
- if(port != 1 && port != 2)
- error(Ebadarg);
-
- /* should check that device not being configured on other port? */
- p = ioport[port];
- qlock(&ctlr->resetl);
- if(waserror()){
- qunlock(&ctlr->resetl);
- nexterror();
- }
- ilock(ctlr);
- w = IN(p);
- if(on)
- w |= PortEnable;
- else
- w &= ~PortEnable;
- OUT(p, w);
- microdelay(64);
- iunlock(ctlr);
- XPRINT("e: %x\n", IN(p));
- poperror();
- qunlock(&ctlr->resetl);
-}
-
-static void
-portinfo(Usbhost *uh, char *s, char *se)
-{
- int x, i, j;
- Ctlr *ctlr;
-
- ctlr = uh->ctlr;
- for(i = 1; i <= 2; i++) {
- ilock(ctlr);
- x = IN(ioport[i]);
- if((x & (PortChange|StatusChange)) != 0)
- OUT(ioport[i], x);
- iunlock(ctlr);
- s = seprint(s, se, "%d %ux", i, x);
- for(j = 0; j < nelem(portstatus); j++) {
- if((x & portstatus[j].bit) != 0)
- s = seprint(s, se, " %s", portstatus[j].name);
- }
- s = seprint(s, se, "\n");
- }
-}
-
-static void
-cleaniso(Endpt *e, int frnum)
-{
- TD *td;
- int id, n, i;
- Endptx *x;
- uchar *bp;
-
- x = e->private;
- td = x->xtd;
- if (td->status & Active)
- return;
- id = (e->x<<7)|(e->dev->x&0x7F);
- do {
- if (td->status & AnyError)
- XPRINT("usbisoerror 0x%lux\n", td->status);
- n = (td->status + 1) & 0x3ff;
- e->nbytes += n;
- if ((td->flags & IsoClean) == 0)
- e->nblocks++;
- if (e->mode == OREAD){
- e->buffered += n;
- e->poffset += (td->status + 1) & 0x3ff;
- td->offset = e->poffset;
- td->dev = ((e->maxpkt -1)<<21) | ((id&0x7FF)<<8) | TokIN;
- e->toffset = td->offset;
- }else{
- if ((td->flags & IsoClean) == 0){
- e->buffered -= n;
- if (e->buffered < 0){
-// print("e->buffered %d?\n", e->buffered);
- e->buffered = 0;
- }
- }
- e->toffset = td->offset;
- n = (e->hz + e->remain)*e->pollms/1000;
- e->remain = (e->hz + e->remain)*e->pollms%1000;
- n *= e->samplesz;
- td->dev = ((n -1)<<21) | ((id&0x7FF)<<8) | TokOUT;
- td->offset = e->poffset;
- e->poffset += n;
- }
- td = td->next;
- if (x->xtd == td){
- XPRINT("@");
- break;
- }
- } while ((td->status & Active) == 0);
- e->time = todget(nil);
- x->xtd = td;
- for (n = 2; n < 4; n++){
- i = ((frnum + n)&0x3ff);
- td = x->td0 + i;
- bp = x->bp0 + e->maxpkt*i/e->pollms;
- if (td->status & Active)
- continue;
-
- if (e->mode == OWRITE){
- if (td == x->etd) {
- XPRINT("*");
- memset(bp+e->off, 0, e->maxpkt-e->off);
- if (e->off == 0)
- td->flags |= IsoClean;
- else
- e->buffered += (((td->dev>>21) +1) & 0x3ff) - e->off;
- x->etd = nil;
- }else if ((td->flags & IsoClean) == 0){
- XPRINT("-");
- memset(bp, 0, e->maxpkt);
- td->flags |= IsoClean;
- }
- } else {
- /* Unread bytes are now lost */
- e->buffered -= (td->status + 1) & 0x3ff;
- }
- td->status = ErrLimit1 | Active | IsoSelect | IOC;
- }
- wakeup(&e->wr);
-}
-
-static void
-interrupt(Ureg*, void *a)
-{
- QH *q;
- Ctlr *ctlr;
- Endpt *e;
- Endptx *x;
- int s, frnum;
- Usbhost *uh;
-
- uh = a;
- ctlr = uh->ctlr;
- s = IN(Status);
- ctlr->frameptr = inl(ctlr->io+Flbaseadd);
- ctlr->framenumber = IN(Frnum) & 0x3ff;
- OUT(Status, s);
- if ((s & 0x1f) == 0)
- return;
- ctlr->usbints++;
- frnum = IN(Frnum) & 0x3ff;
- if (s & 0x1a) {
- XPRINT("cmd #%x sofmod #%x\n", IN(Cmd), inb(ctlr->io+SOFMod));
- XPRINT("sc0 #%x sc1 #%x\n", IN(Portsc0), IN(Portsc1));
- }
-
- ilock(&ctlr->activends);
- for(e = ctlr->activends.f; e != nil; e = e->activef) {
- x = e->private;
- if(!e->iso && x->epq != nil) {
- XPRINT("cleanq(ctlr, x->epq, 0, 0)\n");
- cleanq(ctlr, x->epq, 0, 0);
- }
- if(e->iso) {
- XPRINT("cleaniso(e)\n");
- cleaniso(e, frnum);
- }
- }
- iunlock(&ctlr->activends);
- XPRINT("cleanq(ctlr, ctlr->ctlq, 0, 0)\n");
- cleanq(ctlr, ctlr->ctlq, 0, 0);
- XPRINT("cleanq(ctlr, ctlr->bulkq, 0, Vf)\n");
- cleanq(ctlr, ctlr->bulkq, 0, Vf);
- XPRINT("clean recvq\n");
- for (q = ctlr->recvq->next; q; q = q->hlink) {
- XPRINT("cleanq(ctlr, q, 0, Vf)\n");
- cleanq(ctlr, q, 0, Vf);
- }
-}
-
-static int
-eptinput(void *arg)
-{
- Endpt *e;
-
- e = arg;
- return e->eof || e->err || qcanread(e->rq);
-}
-
-static int
-isoreadyx(Endptx *x)
-{
- return x->etd == nil || (x->etd != x->xtd && (x->etd->status & Active) == 0);
-}
-
-static int
-isoready(void *arg)
-{
- int ret;
- Ctlr *ctlr;
- Endpt *e;
- Endptx *x;
-
- e = arg;
- ctlr = e->dev->uh->ctlr;
- x = e->private;
- ilock(&ctlr->activends);
- ret = isoreadyx(x);
- iunlock(&ctlr->activends);
- return ret;
-}
-
-static long
-isoio(Ctlr *ctlr, Endpt *e, void *a, long n, ulong offset, int w)
-{
- TD *td;
- Endptx *x;
- int i, frnum;
- uchar *p, *q, *bp;
- volatile int isolock;
-
- x = e->private;
- qlock(&e->rlock);
- isolock = 0;
- if(waserror()){
- if (isolock){
- isolock = 0;
- iunlock(&ctlr->activends);
- }
- qunlock(&e->rlock);
- eptcancel(ctlr, e);
- nexterror();
- }
- p = a;
- if (offset != 0 && offset != e->foffset){
- iprint("offset %lud, foffset %lud\n", offset, e->foffset);
- /* Seek to a specific position */
- frnum = (IN(Frnum) + 8) & 0x3ff;
- td = x->td0 +frnum;
- if (offset < td->offset)
- error("ancient history");
- while (offset > e->toffset){
- tsleep(&e->wr, return0, 0, 500);
- }
- while (offset >= td->offset + ((w?(td->dev >> 21):td->status) + 1) & 0x7ff){
- td = td->next;
- if (td == x->xtd)
- iprint("trouble\n");
- }
- ilock(&ctlr->activends);
- isolock = 1;
- e->off = td->offset - offset;
- if (e->off >= e->maxpkt){
- iprint("I can't program: %d\n", e->off);
- e->off = 0;
- }
- x->etd = td;
- e->foffset = offset;
- }
- do {
- if (isolock == 0){
- ilock(&ctlr->activends);
- isolock = 1;
- }
- td = x->etd;
- if (td == nil || e->off == 0){
- if (td == nil){
- XPRINT("0");
- if (w){
- frnum = (IN(Frnum) + 1) & 0x3ff;
- td = x->td0 + frnum;
- while(td->status & Active)
- td = td->next;
- }else{
- frnum = (IN(Frnum) - 4) & 0x3ff;
- td = x->td0 + frnum;
- while(td->next != x->xtd)
- td = td->next;
- }
- x->etd = td;
- e->off = 0;
- }else{
- /* New td, make sure it's ready */
- while (isoreadyx(x) == 0){
- isolock = 0;
- iunlock(&ctlr->activends);
- sleep(&e->wr, isoready, e);
- ilock(&ctlr->activends);
- isolock = 1;
- }
- if (x->etd == nil){
- XPRINT("!");
- continue;
- }
- }
- if (w)
- e->psize = ((td->dev >> 21) + 1) & 0x7ff;
- else
- e->psize = (x->etd->status + 1) & 0x7ff;
- if(e->psize > e->maxpkt)
- panic("packet size > maximum");
- }
- if((i = n) >= e->psize)
- i = e->psize;
- if (w)
- e->buffered += i;
- else{
- e->buffered -= i;
- if (e->buffered < 0)
- e->buffered = 0;
- }
- isolock = 0;
- iunlock(&ctlr->activends);
- td->flags &= ~IsoClean;
- bp = x->bp0 + (td - x->td0) * e->maxpkt / e->pollms;
- q = bp + e->off;
- if (w){
- memmove(q, p, i);
- }else{
- memmove(p, q, i);
- }
- p += i;
- n -= i;
- e->off += i;
- e->psize -= i;
- if (e->psize){
- if (n != 0)
- panic("usb iso: can't happen");
- break;
- }
- if(w)
- td->offset = offset + (p-(uchar*)a) - (((td->dev >> 21) + 1) & 0x7ff);
- td->status = ErrLimit3 | Active | IsoSelect | IOC;
- x->etd = td->next;
- e->off = 0;
- } while(n > 0);
- n = p-(uchar*)a;
- e->foffset += n;
- poperror();
- if (isolock)
- iunlock(&ctlr->activends);
- qunlock(&e->rlock);
- return n;
-}
-
-static long
-read(Usbhost *uh, Endpt *e, void *a, long n, vlong offset)
-{
- long l, i;
- Block *b;
- Ctlr *ctlr;
- uchar *p;
-
- ctlr = uh->ctlr;
- if(e->iso)
- return isoio(ctlr, e, a, n, (ulong)offset, 0);
-
- XPRINT("qlock(%p)\n", &e->rlock);
- qlock(&e->rlock);
- XPRINT("got qlock(%p)\n", &e->rlock);
- if(waserror()){
- qunlock(&e->rlock);
- eptcancel(ctlr, e);
- nexterror();
- }
- p = a;
- do {
- if(e->eof) {
- XPRINT("e->eof\n");
- break;
- }
- if(e->err)
- error(e->err);
- qrcv(ctlr, e);
- if(!e->iso)
- e->data01 ^= 1;
- sleep(&e->rr, eptinput, e);
- if(e->err)
- error(e->err);
- b = qget(e->rq); /* TO DO */
- if(b == nil) {
- XPRINT("b == nil\n");
- break;
- }
- if(waserror()){
- freeb(b);
- nexterror();
- }
- l = BLEN(b);
- if((i = l) > n)
- i = n;
- if(i > 0){
- memmove(p, b->rp, i);
- p += i;
- }
- poperror();
- freeb(b);
- n -= i;
- if (l != e->maxpkt)
- break;
- } while (n > 0);
- poperror();
- qunlock(&e->rlock);
- return p-(uchar*)a;
-}
-
-static int
-qisempty(void *arg)
-{
- return ((QH*)arg)->entries & Terminate;
-}
-
-static long
-write(Usbhost *uh, Endpt *e, void *a, long n, vlong offset, int tok)
-{
- int i, j;
- QH *qh;
- Block *b;
- Ctlr *ctlr;
- uchar *p;
-
- ctlr = uh->ctlr;
- if(e->iso)
- return isoio(ctlr, e, a, n, (ulong)offset, 1);
-
- p = a;
- qlock(&e->wlock);
- if(waserror()){
- qunlock(&e->wlock);
- eptcancel(ctlr, e);
- nexterror();
- }
- do {
- if(e->err)
- error(e->err);
- if((i = n) >= e->maxpkt)
- i = e->maxpkt;
- b = allocb(i);
- if(waserror()){
- freeb(b);
- nexterror();
- }
- XPRINT("out [%d]", i);
- for (j = 0; j < i; j++) XPRINT(" %.2x", p[j]);
- XPRINT("\n");
- memmove(b->wp, p, i);
- b->wp += i;
- p += i;
- n -= i;
- poperror();
- qh = qxmit(ctlr, e, b, tok);
- tok = TokOUT;
- e->data01 ^= 1;
- if(e->ntd >= e->nbuf) {
-XPRINT("qh %s: q=%p first=%p last=%p entries=%.8lux\n",
- "writeusb sleep", qh, qh->first, qh->last, qh->entries);
- XPRINT("write: sleep %lux\n", &e->wr);
- sleep(&e->wr, qisempty, qh);
- XPRINT("write: awake\n");
- }
- } while(n > 0);
- poperror();
- qunlock(&e->wlock);
- return p-(uchar*)a;
-}
-
-static void
-init(Usbhost* uh)
-{
- Ctlr *ctlr;
-
- ctlr = uh->ctlr;
- ilock(ctlr);
- outl(ctlr->io+Flbaseadd, PCIWADDR(ctlr->frames));
- OUT(Frnum, 0);
- OUT(Usbintr, 0xF); /* enable all interrupts */
- XPRINT("cmd 0x%x sofmod 0x%x\n", IN(Cmd), inb(ctlr->io+SOFMod));
- XPRINT("sc0 0x%x sc1 0x%x\n", IN(Portsc0), IN(Portsc1));
- if((IN(Cmd)&1)==0)
- OUT(Cmd, 1); /* run */
-// pprint("at: c=%x s=%x c0=%x\n", IN(Cmd), IN(Status), IN(Portsc0));
- iunlock(ctlr);
-}
-
-static void
-scanpci(void)
-{
- int io;
- Ctlr *ctlr;
- Pcidev *p;
- static int already = 0;
-
- if(already)
- return;
- already = 1;
- p = nil;
- while(p = pcimatch(p, 0, 0)) {
- /*
- * Find UHCI controllers. Class = 12 (serial controller),
- * Sub-class = 3 (USB) and Programming Interface = 0.
- */
- if(p->ccrb != 0x0C || p->ccru != 0x03 || p->ccrp != 0x00)
- continue;
- io = p->mem[4].bar & ~0x0F;
- if(io == 0) {
- print("usbuhci: failed to map registers\n");
- continue;
- }
- if(ioalloc(io, p->mem[4].size, 0, "usbuhci") < 0){
- print("usbuhci: port %d in use\n", io);
- continue;
- }
- if(p->intl == 0xFF || p->intl == 0) {
- print("usbuhci: no irq assigned for port %d\n", io);
- continue;
- }
-
- XPRINT("usbuhci: %x/%x port 0x%ux size 0x%x irq %d\n",
- p->vid, p->did, io, p->mem[4].size, p->intl);
-
- ctlr = malloc(sizeof(Ctlr));
- ctlr->pcidev = p;
- ctlr->io = io;
- if(ctlrhead != nil)
- ctlrtail->next = ctlr;
- else
- ctlrhead = ctlr;
- ctlrtail = ctlr;
- }
-}
-
-static int
-reset(Usbhost *uh)
-{
- int i;
- TD *t;
- ulong io;
- Ctlr *ctlr;
- Pcidev *p;
-
- scanpci();
-
- /*
- * Any adapter matches if no uh->port is supplied,
- * otherwise the ports must match.
- */
- for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
- if(ctlr->active)
- continue;
- if(uh->port == 0 || uh->port == ctlr->io){
- ctlr->active = 1;
- break;
- }
- }
- if(ctlr == nil)
- return -1;
-
- io = ctlr->io;
- p = ctlr->pcidev;
-
- uh->ctlr = ctlr;
- uh->port = io;
- uh->irq = p->intl;
- uh->tbdf = p->tbdf;
-
- XPRINT("usbcmd\t0x%.4x\nusbsts\t0x%.4x\nusbintr\t0x%.4x\nfrnum\t0x%.2x\n",
- IN(Cmd), IN(Status), IN(Usbintr), inb(io+Frnum));
- XPRINT("frbaseadd\t0x%.4x\nsofmod\t0x%x\nportsc1\t0x%.4x\nportsc2\t0x%.4x\n",
- IN(Flbaseadd), inb(io+SOFMod), IN(Portsc0), IN(Portsc1));
-
- OUT(Cmd, 0); /* stop */
- while((IN(Status) & (1<<5)) == 0) /* wait for halt */
- ;
- OUT(Status, 0xFF); /* clear pending interrupts */
- pcicfgw16(p, 0xc0, 0x2000); /* legacy support register: turn off lunacy mode */
-
- if(0){
- i = inb(io+SOFMod);
- OUT(Cmd, 4); /* global reset */
- delay(15);
- OUT(Cmd, 0); /* end reset */
- delay(4);
- outb(io+SOFMod, i);
- }
-
- ctlr->tdpool = xspanalloc(128*sizeof(TD), 16, 0);
- for(i=128; --i>=0;){
- ctlr->tdpool[i].next = ctlr->freetd;
- ctlr->freetd = &ctlr->tdpool[i];
- }
- ctlr->qhpool = xspanalloc(64*sizeof(QH), 16, 0);
- for(i=64; --i>=0;){
- ctlr->qhpool[i].next = ctlr->freeqh;
- ctlr->freeqh = &ctlr->qhpool[i];
- }
-
- /*
- * the last entries of the periodic (interrupt & isochronous) scheduling TD entries
- * points to the control queue and the bandwidth sop for bulk traffic.
- * this is looped following the instructions in PIIX4 errata 29773804.pdf:
- * a QH links to a looped but inactive TD as its sole entry,
- * with its head entry leading on to the bulk traffic, the last QH of which
- * links back to the empty QH.
- */
- ctlr->ctlq = allocqh(ctlr);
- ctlr->bwsop = allocqh(ctlr);
- ctlr->bulkq = allocqh(ctlr);
- ctlr->recvq = allocqh(ctlr);
- t = alloctd(ctlr); /* inactive TD, looped */
- t->link = PCIWADDR(t);
- ctlr->bwsop->entries = PCIWADDR(t);
-
- ctlr->ctlq->head = PCIWADDR(ctlr->bulkq) | IsQH;
- ctlr->bulkq->head = PCIWADDR(ctlr->recvq) | IsQH;
- ctlr->recvq->head = PCIWADDR(ctlr->bwsop) | IsQH;
- if (1) /* don't use loop back */
- ctlr->bwsop->head = Terminate;
- else /* set up loop back */
- ctlr->bwsop->head = PCIWADDR(ctlr->bwsop) | IsQH;
-
- ctlr->frames = xspanalloc(FRAMESIZE, FRAMESIZE, 0);
- ctlr->frameld = xallocz(FRAMESIZE, 1);
- for (i = 0; i < NFRAME; i++)
- ctlr->frames[i] = PCIWADDR(ctlr->ctlq) | IsQH;
-
- /*
- * Linkage to the generic USB driver.
- */
- uh->init = init;
- uh->interrupt = interrupt;
-
- uh->portinfo = portinfo;
- uh->portreset = portreset;
- uh->portenable = portenable;
-
- uh->epalloc = epalloc;
- uh->epfree = epfree;
- uh->epopen = epopen;
- uh->epclose = epclose;
- uh->epmode = epmode;
-
- uh->read = read;
- uh->write = write;
-
- return 0;
-}
-
-void
-usbuhcilink(void)
-{
- addusbtype("uhci", reset);
-}
diff --git a/os/pc/vga.c b/os/pc/vga.c
deleted file mode 100644
index 0d6c7743..00000000
--- a/os/pc/vga.c
+++ /dev/null
@@ -1,241 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static Memimage* back;
-static Memimage *conscol;
-
-static Point curpos;
-static Rectangle window;
-static int *xp;
-static int xbuf[256];
-static Lock vgascreenlock;
-int drawdebug;
-
-void
-vgaimageinit(ulong chan)
-{
- if(back == nil){
- back = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
- if(back == nil)
- panic("back alloc"); /* RSC BUG */
- back->flags |= Frepl;
- back->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
- memfillcolor(back, DBlack);
- }
-
- if(conscol == nil){
- conscol = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
- if(conscol == nil)
- panic("conscol alloc"); /* RSC BUG */
- conscol->flags |= Frepl;
- conscol->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
- memfillcolor(conscol, DWhite);
- }
-}
-
-static void
-vgascroll(VGAscr* scr)
-{
- int h, o;
- Point p;
- Rectangle r;
-
- h = scr->memdefont->height;
- o = 8*h;
- r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
- p = Pt(window.min.x, window.min.y+o);
- memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p, S);
- r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
- memimagedraw(scr->gscreen, r, back, ZP, nil, ZP, S);
-
- curpos.y -= o;
-}
-
-static void
-vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
-{
- Point p;
- int h, w, pos;
- Rectangle r;
-
-// drawdebug = 1;
- if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
- xp = xbuf;
-
- h = scr->memdefont->height;
- switch(buf[0]){
-
- case '\n':
- if(curpos.y+h >= window.max.y){
- vgascroll(scr);
- *flushr = window;
- }
- curpos.y += h;
- vgascreenputc(scr, "\r", flushr);
- break;
-
- case '\r':
- xp = xbuf;
- curpos.x = window.min.x;
- break;
-
- case '\t':
- p = memsubfontwidth(scr->memdefont, " ");
- w = p.x;
- if(curpos.x >= window.max.x-4*w)
- vgascreenputc(scr, "\n", flushr);
-
- pos = (curpos.x-window.min.x)/w;
- pos = 4-(pos%4);
- *xp++ = curpos.x;
- r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
- curpos.x += pos*w;
- break;
-
- case '\b':
- if(xp <= xbuf)
- break;
- xp--;
- r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP, S);
- combinerect(flushr, r);
- curpos.x = *xp;
- break;
-
- case '\0':
- break;
-
- default:
- p = memsubfontwidth(scr->memdefont, buf);
- w = p.x;
-
- if(curpos.x >= window.max.x-w)
- vgascreenputc(scr, "\n", flushr);
-
- *xp++ = curpos.x;
- r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
- memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
- combinerect(flushr, r);
- curpos.x += w;
- }
-// drawdebug = 0;
-}
-
-static void
-vgascreenputs(char* s, int n)
-{
- int i;
- Rune r;
- char buf[4];
- VGAscr *scr;
- Rectangle flushr;
-
- scr = &vgascreen[0];
-
- if(!islo()){
- /*
- * Don't deadlock trying to
- * print in an interrupt.
- */
- if(!canlock(&vgascreenlock))
- return;
- }
- else
- lock(&vgascreenlock);
-
- flushr = Rect(10000, 10000, -10000, -10000);
-
- while(n > 0){
- i = chartorune(&r, s);
- if(i == 0){
- s++;
- --n;
- continue;
- }
- memmove(buf, s, i);
- buf[i] = 0;
- n -= i;
- s += i;
- vgascreenputc(scr, buf, &flushr);
- }
- flushmemscreen(flushr);
-
- unlock(&vgascreenlock);
-}
-
-void
-vgascreenwin(VGAscr* scr)
-{
- int h, w;
-
- h = scr->memdefont->height;
- w = scr->memdefont->info[' '].width;
-
- window = insetrect(scr->gscreen->r, 48);
- window.max.x = window.min.x+((window.max.x-window.min.x)/w)*w;
- window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
- curpos = window.min;
-
- screenputs = vgascreenputs;
-}
-
-/*
- * Supposedly this is the way to turn DPMS
- * monitors off using just the VGA registers.
- * Unfortunately, it seems to mess up the video mode
- * on the cards I've tried.
- */
-void
-vgablank(VGAscr*, int blank)
-{
- uchar seq1, crtc17;
-
- if(blank) {
- seq1 = 0x00;
- crtc17 = 0x80;
- } else {
- seq1 = 0x20;
- crtc17 = 0x00;
- }
-
- outs(Seqx, 0x0100); /* synchronous reset */
- seq1 |= vgaxi(Seqx, 1) & ~0x20;
- vgaxo(Seqx, 1, seq1);
- crtc17 |= vgaxi(Crtx, 0x17) & ~0x80;
- delay(10);
- vgaxo(Crtx, 0x17, crtc17);
- outs(Crtx, 0x0300); /* end synchronous reset */
-}
-
-void
-cornerstring(char *s)
-{
- int h, w;
- VGAscr *scr;
- Rectangle r;
- Point p;
-
- scr = &vgascreen[0];
- if(scr->aperture == 0 || screenputs != vgascreenputs)
- return;
- p = memsubfontwidth(scr->memdefont, s);
- w = p.x;
- h = scr->memdefont->height;
-
- r = Rect(0, 0, w, h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
- memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
-// flushmemscreen(r);
-}
diff --git a/os/pc/vga.h b/os/pc/vga.h
deleted file mode 100644
index 685a8ee5..00000000
--- a/os/pc/vga.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Generic VGA registers.
- */
-enum {
- MiscW = 0x03C2, /* Miscellaneous Output (W) */
- MiscR = 0x03CC, /* Miscellaneous Output (R) */
- Status0 = 0x03C2, /* Input status 0 (R) */
- Status1 = 0x03DA, /* Input Status 1 (R) */
- FeatureR = 0x03CA, /* Feature Control (R) */
- FeatureW = 0x03DA, /* Feature Control (W) */
-
- Seqx = 0x03C4, /* Sequencer Index, Data at Seqx+1 */
- Crtx = 0x03D4, /* CRT Controller Index, Data at Crtx+1 */
- Grx = 0x03CE, /* Graphics Controller Index, Data at Grx+1 */
- Attrx = 0x03C0, /* Attribute Controller Index and Data */
-
- PaddrW = 0x03C8, /* Palette Address Register, write */
- Pdata = 0x03C9, /* Palette Data Register */
- Pixmask = 0x03C6, /* Pixel Mask Register */
- PaddrR = 0x03C7, /* Palette Address Register, read */
- Pstatus = 0x03C7, /* DAC Status (RO) */
-
- Pcolours = 256, /* Palette */
- Pred = 0,
- Pgreen = 1,
- Pblue = 2,
-
- Pblack = 0x00,
- Pwhite = 0xFF,
-};
-
-#define vgai(port) inb(port)
-#define vgao(port, data) outb(port, data)
-
-extern int vgaxi(long, uchar);
-extern int vgaxo(long, uchar, uchar);
-
-typedef struct Cursor Cursor;
-struct Cursor
-{
- Point offset;
- uchar clr[2*16];
- uchar set[2*16];
-};
-
-/*
- * First pass at tidying this up...
- */
-typedef struct Mode {
- int x;
- int y;
- int d;
-
- ulong aperture; /* this is a physical address */
- int apsize;
- int apshift;
-} Mode;
-
-/*
- * Definitions of known VGA controllers.
- */
-typedef struct Vgac Vgac;
-struct Vgac {
- char* name;
- void (*page)(int);
- void (*init)(Mode*);
- int (*ident)(void);
- void (*enable)(void);
- void (*disable)(void);
- void (*move)(int, int);
- void (*load)(Cursor*);
- Vgac* link;
-};
-
-extern void addvgaclink(Vgac*);
diff --git a/os/pc/vga3dfx.c b/os/pc/vga3dfx.c
deleted file mode 100644
index cce27185..00000000
--- a/os/pc/vga3dfx.c
+++ /dev/null
@@ -1,258 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-typedef struct {
- int vidProcCfg;
- int hwCurPatAddr;
- int hwCurLoc;
- int hwCurC0;
- int hwCurC1;
-} Cursor3dfx;
-
-enum {
- dramInit0 = 0x18,
- dramInit1 = 0x1C,
-
- hwCur = 0x5C,
-};
-
-static ulong
-tdfxlinear(VGAscr* scr, int* size, int* align)
-{
- Pcidev *p;
- int oapsize, wasupamem;
- ulong aperture, oaperture;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- aperture = 0;
- if(p = pcimatch(nil, 0x121A, 0)){
- switch(p->did){
- case 0x0003: /* Banshee */
- case 0x0005: /* Avenger (a.k.a. Voodoo3) */
- case 0x0009: /* Voodoo5 */
- aperture = p->mem[1].bar & ~0x0F;
- *size = p->mem[1].size;
- break;
- default:
- break;
- }
- }
-
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-tdfxenable(VGAscr* scr)
-{
- Pcidev *p;
- ulong aperture;
- int align, i, *mmio, size;
-
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the physical address of
- * the MMIO registers.
- */
- if(scr->io)
- return;
- if(p = pcimatch(nil, 0x121A, 0)){
- switch(p->did){
- case 0x0003: /* Banshee */
- case 0x0005: /* Avenger (a.k.a. Voodoo3) */
- break;
- default:
- return;
- }
- }
- else
- return;
- scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
- if(scr->io == 0)
- return;
-
- addvgaseg("3dfxmmio", (ulong)scr->io, p->mem[0].size);
-
- size = p->mem[1].size;
- align = 0;
- aperture = tdfxlinear(scr, &size, &align);
- if(aperture){
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("3dfxscreen", aperture, size);
- }
-
- /*
- * Find a place for the cursor data in display memory.
- * If SDRAM then there's 16MB memory else it's SGRAM
- * and can count it based on the power-on straps -
- * chip size can be 8Mb or 16Mb, and there can be 4 or
- * 8 of them.
- * Use the last 1KB of the framebuffer.
- */
- mmio = KADDR(scr->io + dramInit0);
- if(*(mmio+1) & 0x40000000)
- i = 16*1024*1024;
- else{
- if(*mmio & 0x08000000)
- i = 16*1024*1024/8;
- else
- i = 8*1024*1024/8;
- if(*mmio & 0x04000000)
- i *= 8;
- else
- i *= 4;
- }
- scr->storage = i - 1024;
-}
-
-static void
-tdfxcurdisable(VGAscr* scr)
-{
- Cursor3dfx *cursor3dfx;
-
- if(scr->io == 0)
- return;
- cursor3dfx = KADDR(scr->io+hwCur);
- cursor3dfx->vidProcCfg &= ~0x08000000;
-}
-
-static void
-tdfxcurload(VGAscr* scr, Cursor* curs)
-{
- int y;
- uchar *p;
- Cursor3dfx *cursor3dfx;
-
- if(scr->io == 0)
- return;
- cursor3dfx = KADDR(scr->io+hwCur);
-
- /*
- * Disable the cursor then load the new image in
- * the top-left of the 64x64 array.
- * The cursor data is stored in memory as 128-bit
- * words consisting of plane 0 in the least significant 64-bits
- * and plane 1 in the most significant.
- * The X11 cursor truth table is:
- * p0 p1 colour
- * 0 0 transparent
- * 0 1 transparent
- * 1 0 hwCurC0
- * 1 1 hwCurC1
- * Unused portions of the image have been initialised to be
- * transparent.
- */
- cursor3dfx->vidProcCfg &= ~0x08000000;
- p = KADDR(scr->aperture + scr->storage);
- for(y = 0; y < 16; y++){
- *p++ = curs->clr[2*y]|curs->set[2*y];
- *p++ = curs->clr[2*y+1]|curs->set[2*y+1];
- p += 6;
- *p++ = curs->set[2*y];
- *p++ = curs->set[2*y+1];
- p += 6;
- }
-
- /*
- * Save the cursor hotpoint and enable the cursor.
- * The 0,0 cursor point is bottom-right.
- */
- scr->offset.x = 63+curs->offset.x;
- scr->offset.y = 63+curs->offset.y;
- cursor3dfx->vidProcCfg |= 0x08000000;
-}
-
-static int
-tdfxcurmove(VGAscr* scr, Point p)
-{
- Cursor3dfx *cursor3dfx;
-
- if(scr->io == 0)
- return 1;
- cursor3dfx = KADDR(scr->io+hwCur);
-
- cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x);
-
- return 0;
-}
-
-static void
-tdfxcurenable(VGAscr* scr)
-{
- Cursor3dfx *cursor3dfx;
-
- tdfxenable(scr);
- if(scr->io == 0)
- return;
- cursor3dfx = KADDR(scr->io+hwCur);
-
- /*
- * Cursor colours.
- */
- cursor3dfx->hwCurC0 = 0xFFFFFFFF;
- cursor3dfx->hwCurC1 = 0x00000000;
-
- /*
- * Initialise the 64x64 cursor to be transparent (X11 mode).
- */
- cursor3dfx->hwCurPatAddr = scr->storage;
- memset(KADDR(scr->aperture + scr->storage), 0, 64*16);
-
- /*
- * Load, locate and enable the 64x64 cursor in X11 mode.
- */
- tdfxcurload(scr, &arrow);
- tdfxcurmove(scr, ZP);
- cursor3dfx->vidProcCfg |= 0x08000002;
-}
-
-VGAdev vga3dfxdev = {
- "3dfx",
-
- tdfxenable,
- nil,
- nil,
- tdfxlinear,
-};
-
-VGAcur vga3dfxcur = {
- "3dfxhwgc",
-
- tdfxcurenable,
- tdfxcurdisable,
- tdfxcurload,
- tdfxcurmove,
-};
diff --git a/os/pc/vgaark2000pv.c b/os/pc/vgaark2000pv.c
deleted file mode 100644
index d42eccc3..00000000
--- a/os/pc/vgaark2000pv.c
+++ /dev/null
@@ -1,190 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static int
-ark2000pvpageset(VGAscr*, int page)
-{
- uchar seq15;
-
- seq15 = vgaxi(Seqx, 0x15);
- vgaxo(Seqx, 0x15, page);
- vgaxo(Seqx, 0x16, page);
-
- return seq15;
-}
-
-static void
-ark2000pvpage(VGAscr* scr, int page)
-{
- lock(&scr->devlock);
- ark2000pvpageset(scr, page);
- unlock(&scr->devlock);
-}
-
-static void
-ark2000pvdisable(VGAscr*)
-{
- uchar seq20;
-
- seq20 = vgaxi(Seqx, 0x20) & ~0x08;
- vgaxo(Seqx, 0x20, seq20);
-}
-
-static void
-ark2000pvenable(VGAscr* scr)
-{
- uchar seq20;
- ulong storage;
-
- /*
- * Disable the cursor then configure for X-Windows style,
- * 32x32 and 4/8-bit colour depth.
- * Set cursor colours for 4/8-bit.
- */
- seq20 = vgaxi(Seqx, 0x20) & ~0x1F;
- vgaxo(Seqx, 0x20, seq20);
- seq20 |= 0x18;
-
- vgaxo(Seqx, 0x26, 0x00);
- vgaxo(Seqx, 0x27, 0x00);
- vgaxo(Seqx, 0x28, 0x00);
- vgaxo(Seqx, 0x29, 0xFF);
- vgaxo(Seqx, 0x2A, 0xFF);
- vgaxo(Seqx, 0x2B, 0xFF);
-
- /*
- * Cursor storage is a 256 byte or 1Kb block located in the last
- * 16Kb of video memory. Crt25 is the index of which block.
- */
- storage = (vgaxi(Seqx, 0x10)>>6) & 0x03;
- storage = (1024*1024)<<storage;
- storage -= 256;
- scr->storage = storage;
- vgaxo(Seqx, 0x25, 0x3F);
-
- /*
- * Enable the cursor.
- */
- vgaxo(Seqx, 0x20, seq20);
-}
-
-static void
-ark2000pvload(VGAscr* scr, Cursor* curs)
-{
- uchar *p, seq10;
- int opage, x, y;
-
- /*
- * Is linear addressing turned on? This will determine
- * how we access the cursor storage.
- */
- seq10 = vgaxi(Seqx, 0x10);
- opage = 0;
- p = KADDR(scr->aperture);
- if(!(seq10 & 0x10)){
- lock(&scr->devlock);
- opage = ark2000pvpageset(scr, scr->storage>>16);
- p += (scr->storage & 0xFFFF);
- }
- else
- p += scr->storage;
-
- /*
- * The cursor is set in X11 mode which gives the following
- * truth table:
- * and xor colour
- * 0 0 underlying pixel colour
- * 0 1 underlying pixel colour
- * 1 0 background colour
- * 1 1 foreground colour
- * Put the cursor into the top-left of the 32x32 array.
- * The manual doesn't say what the data layout in memory is -
- * this worked out by trial and error.
- */
- for(y = 0; y < 32; y++){
- for(x = 0; x < 32/8; x++){
- if(x < 16/8 && y < 16){
- *p++ = curs->clr[2*y + x]|curs->set[2*y + x];
- *p++ = curs->set[2*y + x];
- }
- else {
- *p++ = 0x00;
- *p++ = 0x00;
- }
- }
- }
-
- if(!(seq10 & 0x10)){
- ark2000pvpageset(scr, opage);
- unlock(&scr->devlock);
- }
-
- /*
- * Save the cursor hotpoint.
- */
- scr->offset = curs->offset;
-}
-
-static int
-ark2000pvmove(VGAscr* scr, Point p)
-{
- int x, xo, y, yo;
-
- /*
- * Mustn't position the cursor offscreen even partially,
- * or it might disappear. Therefore, if x or y is -ve, adjust the
- * cursor origins instead.
- */
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- /*
- * Load the new values.
- */
- vgaxo(Seqx, 0x2C, xo);
- vgaxo(Seqx, 0x2D, yo);
- vgaxo(Seqx, 0x21, (x>>8) & 0x0F);
- vgaxo(Seqx, 0x22, x & 0xFF);
- vgaxo(Seqx, 0x23, (y>>8) & 0x0F);
- vgaxo(Seqx, 0x24, y & 0xFF);
-
- return 0;
-}
-
-VGAdev vgaark2000pvdev = {
- "ark2000pv",
-
- 0,
- 0,
- ark2000pvpage,
- 0,
-};
-
-VGAcur vgaark2000pvcur = {
- "ark2000pvhwgc",
-
- ark2000pvenable,
- ark2000pvdisable,
- ark2000pvload,
- ark2000pvmove,
-};
diff --git a/os/pc/vgabt485.c b/os/pc/vgabt485.c
deleted file mode 100644
index 1c155e6d..00000000
--- a/os/pc/vgabt485.c
+++ /dev/null
@@ -1,245 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-/*
- * Hardware graphics cursor support for
- * Brooktree Bt485 Monolithic True-Color RAMDAC.
- * Assumes hooked up to an S3 86C928.
- *
- * BUGS:
- * 64x64x2 cursor always used;
- * no support for interlaced mode.
- */
-enum {
- AddrW = 0x00, /* Address register; palette/cursor RAM write */
- Palette = 0x01, /* 6/8-bit color palette data */
- Pmask = 0x02, /* Pixel mask register */
- AddrR = 0x03, /* Address register; palette/cursor RAM read */
- ColorW = 0x04, /* Address register; cursor/overscan color write */
- Color = 0x05, /* Cursor/overscan color data */
- Cmd0 = 0x06, /* Command register 0 */
- ColorR = 0x07, /* Address register; cursor/overscan color read */
- Cmd1 = 0x08, /* Command register 1 */
- Cmd2 = 0x09, /* Command register 2 */
- Status = 0x0A, /* Status */
- Cmd3 = 0x1A, /* Command register 3 */
- Cram = 0x0B, /* Cursor RAM array data */
- Cxlr = 0x0C, /* Cursor x-low register */
- Cxhr = 0x0D, /* Cursor x-high register */
- Cylr = 0x0E, /* Cursor y-low register */
- Cyhr = 0x0F, /* Cursor y-high register */
-
- Nreg = 0x10,
-};
-
-/*
- * Lower 2-bits of indirect DAC register
- * addressing.
- */
-static ushort dacxreg[4] = {
- PaddrW, Pdata, Pixmask, PaddrR
-};
-
-static uchar
-bt485io(uchar reg)
-{
- uchar crt55, cr0;
-
- crt55 = vgaxi(Crtx, 0x55) & 0xFC;
- if((reg & 0x0F) == Status){
- /*
- * 1,2: Set indirect addressing for Status or
- * Cmd3 - set bit7 of Cr0.
- */
- vgaxo(Crtx, 0x55, crt55|((Cmd0>>2) & 0x03));
- cr0 = vgai(dacxreg[Cmd0 & 0x03])|0x80;
- vgao(dacxreg[Cmd0 & 0x03], cr0);
-
- /*
- * 3,4: Set the index into the Write register,
- * index == 0x00 for Status, 0x01 for Cmd3.
- */
- vgaxo(Crtx, 0x55, crt55|((AddrW>>2) & 0x03));
- vgao(dacxreg[AddrW & 0x03], (reg == Status) ? 0x00: 0x01);
-
- /*
- * 5,6: Get the contents of the appropriate
- * register at 0x0A.
- */
- }
-
- return crt55;
-}
-
-static uchar
-bt485i(uchar reg)
-{
- uchar crt55, r;
-
- crt55 = bt485io(reg);
- vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
- r = vgai(dacxreg[reg & 0x03]);
- vgaxo(Crtx, 0x55, crt55);
-
- return r;
-}
-
-static void
-bt485o(uchar reg, uchar data)
-{
- uchar crt55;
-
- crt55 = bt485io(reg);
- vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
- vgao(dacxreg[reg & 0x03], data);
- vgaxo(Crtx, 0x55, crt55);
-}
-
-static void
-bt485disable(VGAscr*)
-{
- uchar r;
-
- /*
- * Disable
- * cursor mode 3;
- * cursor control enable for Bt485 DAC;
- * the hardware cursor external operation mode.
- */
- r = bt485i(Cmd2) & ~0x03;
- bt485o(Cmd2, r);
-
- r = vgaxi(Crtx, 0x45) & ~0x20;
- vgaxo(Crtx, 0x45, r);
-
- r = vgaxi(Crtx, 0x55) & ~0x20;
- vgaxo(Crtx, 0x55, r);
-}
-
-static void
-bt485enable(VGAscr*)
-{
- uchar r;
-
- /*
- * Turn cursor off.
- */
- r = bt485i(Cmd2) & 0xFC;
- bt485o(Cmd2, r);
-
- /*
- * Overscan colour,
- * cursor colour 1 (white),
- * cursor colour 2, 3 (black).
- */
- bt485o(ColorW, 0x00);
- bt485o(Color, Pwhite); bt485o(Color, Pwhite); bt485o(Color, Pwhite);
-
- bt485o(Color, Pwhite); bt485o(Color, Pwhite); bt485o(Color, Pwhite);
-
- bt485o(Color, Pblack); bt485o(Color, Pblack); bt485o(Color, Pblack);
- bt485o(Color, Pblack); bt485o(Color, Pblack); bt485o(Color, Pblack);
-
- /*
- * Finally, enable
- * the hardware cursor external operation mode;
- * cursor control enable for Bt485 DAC.
- * The #9GXE cards seem to need the 86C928 Bt485 support
- * enabled in order to work at all in enhanced mode.
- */
-
- r = vgaxi(Crtx, 0x55)|0x20;
- vgaxo(Crtx, 0x55, r);
-
- r = vgaxi(Crtx, 0x45)|0x20;
- vgaxo(Crtx, 0x45, r);
-}
-
-static void
-bt485load(VGAscr* scr, Cursor* curs)
-{
- uchar r;
- int x, y;
-
- /*
- * Turn cursor off;
- * put cursor into 64x64x2 mode and clear MSBs of address;
- * clear LSBs of address;
- */
- r = bt485i(Cmd2) & 0xFC;
- bt485o(Cmd2, r);
-
- r = (bt485i(Cmd3) & 0xFC)|0x04;
- bt485o(Cmd3, r);
-
- bt485o(AddrW, 0x00);
-
- /*
- * Now load the cursor RAM array, both planes.
- * The cursor is 16x16, the array 64x64; put
- * the cursor in the top left. The 0,0 cursor
- * point is bottom-right, so positioning will
- * have to take that into account.
- */
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16)
- bt485o(Cram, curs->clr[x+y*2]);
- else
- bt485o(Cram, 0x00);
- }
- }
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16)
- bt485o(Cram, curs->set[x+y*2]);
- else
- bt485o(Cram, 0x00);
- }
- }
-
- /*
- * Initialise the cursor hot-point
- * and enable the cursor.
- */
- scr->offset.x = 64+curs->offset.x;
- scr->offset.y = 64+curs->offset.y;
-
- r = (bt485i(Cmd2) & 0xFC)|0x01;
- bt485o(Cmd2, r);
-}
-
-static int
-bt485move(VGAscr* scr, Point p)
-{
- int x, y;
-
- x = p.x+scr->offset.x;
- y = p.y+scr->offset.y;
-
- bt485o(Cxlr, x & 0xFF);
- bt485o(Cxhr, (x>>8) & 0x0F);
- bt485o(Cylr, y & 0xFF);
- bt485o(Cyhr, (y>>8) & 0x0F);
-
- return 0;
-}
-
-VGAcur vgabt485cur = {
- "bt485hwgc",
-
- bt485enable,
- bt485disable,
- bt485load,
- bt485move,
-};
diff --git a/os/pc/vgaclgd542x.c b/os/pc/vgaclgd542x.c
deleted file mode 100644
index 6dd95e9e..00000000
--- a/os/pc/vgaclgd542x.c
+++ /dev/null
@@ -1,291 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static int
-clgd542xpageset(VGAscr*, int page)
-{
- uchar gr09;
- int opage;
-
- if(vgaxi(Seqx, 0x07) & 0xF0)
- page = 0;
- gr09 = vgaxi(Grx, 0x09);
- if(vgaxi(Grx, 0x0B) & 0x20){
- vgaxo(Grx, 0x09, page<<2);
- opage = gr09>>2;
- }
- else{
- vgaxo(Grx, 0x09, page<<4);
- opage = gr09>>4;
- }
-
- return opage;
-}
-
-static void
-clgd542xpage(VGAscr* scr, int page)
-{
- lock(&scr->devlock);
- clgd542xpageset(scr, page);
- unlock(&scr->devlock);
-}
-
-static ulong
-clgd542xlinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- Pcidev *p;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
- if(wasupamem)
- upafree(oaperture, oapsize);
- scr->isupamem = 0;
-
- if(p = pcimatch(nil, 0x1013, 0)){
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
- }
- else
- aperture = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0))
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-clgd542xdisable(VGAscr*)
-{
- uchar sr12;
-
- sr12 = vgaxi(Seqx, 0x12);
- vgaxo(Seqx, 0x12, sr12 & ~0x01);
-}
-
-static void
-clgd542xenable(VGAscr* scr)
-{
- uchar sr12;
- int mem, x;
-
- /*
- * Disable the cursor.
- */
- sr12 = vgaxi(Seqx, 0x12);
- vgaxo(Seqx, 0x12, sr12 & ~0x01);
-
- /*
- * Cursor colours.
- * Can't call setcolor here as cursor is already locked.
- */
- vgaxo(Seqx, 0x12, sr12|0x02);
- vgao(PaddrW, 0x00);
- vgao(Pdata, Pwhite);
- vgao(Pdata, Pwhite);
- vgao(Pdata, Pwhite);
- vgao(PaddrW, 0x0F);
- vgao(Pdata, Pblack);
- vgao(Pdata, Pblack);
- vgao(Pdata, Pblack);
- vgaxo(Seqx, 0x12, sr12);
-
- mem = 0;
- switch(vgaxi(Crtx, 0x27) & ~0x03){
-
- case 0x88: /* CL-GD5420 */
- case 0x8C: /* CL-GD5422 */
- case 0x94: /* CL-GD5424 */
- case 0x80: /* CL-GD5425 */
- case 0x90: /* CL-GD5426 */
- case 0x98: /* CL-GD5427 */
- case 0x9C: /* CL-GD5429 */
- /*
- * The BIOS leaves the memory size in Seq0A, bits 4 and 3.
- * See Technical Reference Manual Appendix E1, Section 1.3.2.
- *
- * The storage area for the 64x64 cursors is the last 16Kb of
- * display memory.
- */
- mem = (vgaxi(Seqx, 0x0A)>>3) & 0x03;
- break;
-
- case 0xA0: /* CL-GD5430 */
- case 0xA8: /* CL-GD5434 */
- case 0xAC: /* CL-GD5436 */
- case 0xB8: /* CL-GD5446 */
- case 0x30: /* CL-GD7543 */
- /*
- * Attempt to intuit the memory size from the DRAM control
- * register. Minimum is 512KB.
- * If DRAM bank switching is on then there's double.
- */
- x = vgaxi(Seqx, 0x0F);
- mem = (x>>3) & 0x03;
- if(x & 0x80)
- mem++;
- break;
-
- default: /* uh, ah dunno */
- break;
- }
- scr->storage = ((256<<mem)-16)*1024;
-
- /*
- * Set the current cursor to index 0
- * and turn the 64x64 cursor on.
- */
- vgaxo(Seqx, 0x13, 0);
- vgaxo(Seqx, 0x12, sr12|0x05);
-}
-
-static void
-clgd542xinitcursor(VGAscr* scr, int xo, int yo, int index)
-{
- uchar *p, seq07;
- uint p0, p1;
- int opage, x, y;
-
- /*
- * Is linear addressing turned on? This will determine
- * how we access the cursor storage.
- */
- seq07 = vgaxi(Seqx, 0x07);
- opage = 0;
- p = KADDR(scr->aperture);
- if(!(seq07 & 0xF0)){
- lock(&scr->devlock);
- opage = clgd542xpageset(scr, scr->storage>>16);
- p += (scr->storage & 0xFFFF);
- }
- else
- p += scr->storage;
- p += index*1024;
-
- for(y = yo; y < 16; y++){
- p0 = scr->set[2*y];
- p1 = scr->set[2*y+1];
- if(xo){
- p0 = (p0<<xo)|(p1>>(8-xo));
- p1 <<= xo;
- }
- *p++ = p0;
- *p++ = p1;
-
- for(x = 16; x < 64; x += 8)
- *p++ = 0x00;
-
- p0 = scr->clr[2*y]|scr->set[2*y];
- p1 = scr->clr[2*y+1]|scr->set[2*y+1];
- if(xo){
- p0 = (p0<<xo)|(p1>>(8-xo));
- p1 <<= xo;
- }
- *p++ = p0;
- *p++ = p1;
-
- for(x = 16; x < 64; x += 8)
- *p++ = 0x00;
- }
- while(y < 64+yo){
- for(x = 0; x < 64; x += 8){
- *p++ = 0x00;
- *p++ = 0x00;
- }
- y++;
- }
-
- if(!(seq07 & 0xF0)){
- clgd542xpageset(scr, opage);
- unlock(&scr->devlock);
- }
-}
-
-static void
-clgd542xload(VGAscr* scr, Cursor* curs)
-{
- uchar sr12;
-
- /*
- * Disable the cursor.
- */
- sr12 = vgaxi(Seqx, 0x12);
- vgaxo(Seqx, 0x12, sr12 & ~0x01);
-
- memmove(&scr->Cursor, curs, sizeof(Cursor));
- clgd542xinitcursor(scr, 0, 0, 0);
-
- /*
- * Enable the cursor.
- */
- vgaxo(Seqx, 0x13, 0);
- vgaxo(Seqx, 0x12, sr12|0x05);
-}
-
-static int
-clgd542xmove(VGAscr* scr, Point p)
-{
- int index, x, xo, y, yo;
-
- index = 0;
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- if(xo || yo){
- clgd542xinitcursor(scr, xo, yo, 1);
- index = 1;
- }
- vgaxo(Seqx, 0x13, index<<2);
-
- vgaxo(Seqx, 0x10|((x & 0x07)<<5), (x>>3) & 0xFF);
- vgaxo(Seqx, 0x11|((y & 0x07)<<5), (y>>3) & 0xFF);
-
- return 0;
-}
-
-VGAdev vgaclgd542xdev = {
- "clgd542x",
-
- 0,
- 0,
- clgd542xpage,
- clgd542xlinear,
-};
-
-VGAcur vgaclgd542xcur = {
- "clgd542xhwgc",
-
- clgd542xenable,
- clgd542xdisable,
- clgd542xload,
- clgd542xmove,
-};
diff --git a/os/pc/vgaclgd546x.c b/os/pc/vgaclgd546x.c
deleted file mode 100644
index 62bcd82a..00000000
--- a/os/pc/vgaclgd546x.c
+++ /dev/null
@@ -1,277 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-typedef struct Cursor546x Cursor546x;
-struct Cursor546x {
- ushort x;
- ushort y;
- ushort preset;
- ushort enable;
- ushort addr;
-};
-
-enum {
- PaletteState = 0xB0,
- CursorMMIO = 0xE0,
-};
-
-static ulong
-clgd546xlinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- Pcidev *p;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- aperture = 0;
- if(p = pcimatch(nil, 0x1013, 0)){
- switch(p->did){
- case 0xD0:
- case 0xD4:
- case 0xD6:
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
- break;
- default:
- break;
- }
- }
-
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-static void
-clgd546xenable(VGAscr* scr)
-{
- Pcidev *p;
- int size, align;
- ulong aperture;
-
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the virtual address of
- * the MMIO registers.
- */
- if(scr->io)
- return;
- if(p = pcimatch(nil, 0x1013, 0)){
- switch(p->did){
- case 0xD0:
- case 0xD4:
- case 0xD6:
- break;
- default:
- return;
- }
- }
- else
- return;
- scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
- if(scr->io == 0)
- return;
- addvgaseg("clgd546xmmio", scr->io, p->mem[1].size);
-
- scr->io = (ulong)KADDR(scr->io);
-
- size = p->mem[0].size;
- align = 0;
- aperture = clgd546xlinear(scr, &size, &align);
- if(aperture) {
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("clgd546xscreen", aperture, size);
- }
-}
-
-static void
-clgd546xcurdisable(VGAscr* scr)
-{
- Cursor546x *cursor546x;
-
- if(scr->io == 0)
- return;
- cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
- cursor546x->enable = 0;
-}
-
-static void
-clgd546xcurload(VGAscr* scr, Cursor* curs)
-{
- int c, i, m, y;
- uchar *p;
- Cursor546x *cursor546x;
-
- if(scr->io == 0)
- return;
- cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
-
- /*
- * Disable the cursor then change only the bits
- * that need it.
- */
- cursor546x->enable = 0;
- p = (uchar*)(scr->aperture + scr->storage);
- for(y = 0; y < 16; y++){
- c = curs->set[2*y];
- m = 0;
- for(i = 0; i < 8; i++){
- if(c & (1<<(7-i)))
- m |= 1<<i;
- }
- *p++ = m;
- c = curs->set[2*y + 1];
- m = 0;
- for(i = 0; i < 8; i++){
- if(c & (1<<(7-i)))
- m |= 1<<i;
- }
- *p++ = m;
- p += 6;
- c = curs->set[2*y]|curs->clr[2*y];
- m = 0;
- for(i = 0; i < 8; i++){
- if(c & (1<<(7-i)))
- m |= 1<<i;
- }
- *p++ = m;
- c = curs->set[2*y + 1]|curs->clr[2*y + 1];
- m = 0;
- for(i = 0; i < 8; i++){
- if(c & (1<<(7-i)))
- m |= 1<<i;
- }
- *p++ = m;
- p += 6;
- }
-
- /*
- * Save the cursor hotpoint and enable the cursor.
- */
- scr->offset = curs->offset;
- cursor546x->enable = 1;
-}
-
-static int
-clgd546xcurmove(VGAscr* scr, Point p)
-{
- int x, xo, y, yo;
- Cursor546x *cursor546x;
-
- if(scr->io == 0)
- return 1;
- cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
-
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- cursor546x->preset = (xo<<8)|yo;
- cursor546x->x = x;
- cursor546x->y = y;
-
- return 0;
-}
-
-static void
-clgd546xcurenable(VGAscr* scr)
-{
- uchar *p;
- Cursor546x *cursor546x;
-
- clgd546xenable(scr);
- if(scr->io == 0)
- return;
- cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
-
- /*
- * Cursor colours.
- * Can't call setcolor here as cursor is already locked.
- */
- p = (uchar*)(scr->io+PaletteState);
- *p |= 0x08;
- vgao(PaddrW, 0x00);
- vgao(Pdata, Pwhite);
- vgao(Pdata, Pwhite);
- vgao(Pdata, Pwhite);
- vgao(PaddrW, 0x0F);
- vgao(Pdata, Pblack);
- vgao(Pdata, Pblack);
- vgao(Pdata, Pblack);
- *p &= ~0x08;
-
- /*
- * Find a place for the cursor data in display memory.
- * 2 cursor images might be needed, 1KB each so use the last
- * 2KB of the framebuffer and initialise them to be
- * transparent.
- */
- scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
- cursor546x->addr = (scr->storage>>10)<<2;
- memset((uchar*)(scr->aperture + scr->storage), 0, 2*64*16);
-
- /*
- * Load, locate and enable the 64x64 cursor.
- */
- clgd546xcurload(scr, &arrow);
- clgd546xcurmove(scr, ZP);
- cursor546x->enable = 1;
-}
-
-VGAdev vgaclgd546xdev = {
- "clgd546x",
-
- clgd546xenable,
- nil,
- nil,
- clgd546xlinear,
-};
-
-VGAcur vgaclgd546xcur = {
- "clgd546xhwgc",
-
- clgd546xcurenable,
- clgd546xcurdisable,
- clgd546xcurload,
- clgd546xcurmove,
-};
diff --git a/os/pc/vgact65545.c b/os/pc/vgact65545.c
deleted file mode 100644
index 9a1467ac..00000000
--- a/os/pc/vgact65545.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static void
-ct65545page(VGAscr*, int page)
-{
- outb(0x3D6, 0x10);
- outb(0x3D7, page<<6);
-}
-
-static void
-ct65545disable(VGAscr*)
-{
- outl(0xA3D0, 0);
-}
-
-static void
-ct65545enable(VGAscr* scr)
-{
- ulong storage;
-
- /*
- * Find a place for the cursor data in display memory.
- * Must be on a 1024-byte boundary.
- */
- storage = ROUND(scr->gscreen->width*BY2WD*scr->gscreen->r.max.y, 1024);
- outl(0xB3D0, storage);
- scr->storage = storage;
-
- /*
- * Set the colours.
- * Enable the cursor.
- */
- outl(0xA7D0, 0xFFFF0000);
- outl(0xA3D0, 2);
-}
-
-static void
-ct65545initcursor(VGAscr* scr, int xo, int yo, int index)
-{
- uchar *mem;
- uint and, clr, set, xor;
- int i, x, y;
-
- mem = KADDR(scr->aperture);
- mem += scr->storage + index*1024;
-
- for(y = yo; y < 16; y++){
- clr = (scr->clr[2*y]<<8)|scr->clr[2*y+1];
- set = (scr->set[2*y]<<8)|scr->set[2*y+1];
- if(xo){
- clr <<= xo;
- set <<= xo;
- }
-
- and = 0;
- xor = 0;
- for(i = 0; i < 16; i++){
- if(set & (1<<i)){
- /* nothing to do */
- }
- else if(clr & (1<<i))
- xor |= 1<<i;
- else
- and |= 1<<i;
- }
- *mem++ = and>>8;
- *mem++ = xor>>8;
- *mem++ = and;
- *mem++ = xor;
-
- for(x = 16; x < 64; x += 8){
- *mem++ = 0xFF;
- *mem++ = 0x00;
- }
- }
- while(y < 64+yo){
- for(x = 0; x < 64; x += 8){
- *mem++ = 0xFF;
- *mem++ = 0x00;
- }
- y++;
- }
-}
-
-static void
-ct65545load(VGAscr* scr, Cursor* curs)
-{
- memmove(&scr->Cursor, curs, sizeof(Cursor));
- ct65545initcursor(scr, 0, 0, 0);
-}
-
-static int
-ct65545move(VGAscr* scr, Point p)
-{
- int index, x, xo, y, yo;
-
- index = 0;
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- if(xo || yo){
- ct65545initcursor(scr, xo, yo, 1);
- index = 1;
- }
- outl(0xB3D0, scr->storage + index*1024);
-
- outl(0xAFD0, (y<<16)|x);
-
- return 0;
-}
-
-VGAdev vgact65545dev = {
- "ct65540", /* BUG: really 65545 */
-
- 0,
- 0,
- ct65545page,
- 0,
-};
-
-VGAcur vgact65545cur = {
- "ct65545hwgc",
-
- ct65545enable,
- ct65545disable,
- ct65545load,
- ct65545move,
-};
diff --git a/os/pc/vgacyber938x.c b/os/pc/vgacyber938x.c
deleted file mode 100644
index 7c86679c..00000000
--- a/os/pc/vgacyber938x.c
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum {
- CursorON = 0xC8,
- CursorOFF = 0x00,
-};
-
-static int
-cyber938xpageset(VGAscr*, int page)
-{
- int opage;
-
- opage = inb(0x3D8);
-
- outb(0x3D8, page);
- outb(0x3D9, page);
-
- return opage;
-}
-
-static void
-cyber938xpage(VGAscr* scr, int page)
-{
- lock(&scr->devlock);
- cyber938xpageset(scr, page);
- unlock(&scr->devlock);
-}
-
-static ulong
-cyber938xlinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- int osize;
- Pcidev *p;
-
- osize = *size;
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
- if(wasupamem)
- upafree(oaperture, oapsize);
- scr->isupamem = 0;
- scr->mmio = 0;
-
- if(p = pcimatch(nil, 0x1023, 0)){
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
- /*
- * Heuristic to detect the MMIO space. We're flying blind
- * here, with only the XFree86 source to guide us.
- */
- if(p->mem[1].size == 0x20000)
- scr->mmio = (ulong*)(p->mem[1].bar & ~0x0F);
- }
- else
- aperture = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0))
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 1;
-
- if(aperture)
- addvgaseg("cyber938xscreen", aperture, osize);
- if(scr->mmio)
- addvgaseg("cyber938xmmio", (ulong)scr->mmio, 0x20000);
-
- return aperture;
-}
-
-static void
-cyber938xcurdisable(VGAscr*)
-{
- vgaxo(Crtx, 0x50, CursorOFF);
-}
-
-static void
-cyber938xcurload(VGAscr* scr, Cursor* curs)
-{
- uchar *p;
- int islinear, opage, y;
-
- cyber938xcurdisable(scr);
-
- opage = 0;
- p = KADDR(scr->aperture);
- islinear = vgaxi(Crtx, 0x21) & 0x20;
- if(!islinear){
- lock(&scr->devlock);
- opage = cyber938xpageset(scr, scr->storage>>16);
- p += (scr->storage & 0xFFFF);
- }
- else
- p += scr->storage;
-
- for(y = 0; y < 16; y++){
- *p++ = curs->set[2*y]|curs->clr[2*y];
- *p++ = curs->set[2*y + 1]|curs->clr[2*y + 1];
- *p++ = 0x00;
- *p++ = 0x00;
- *p++ = curs->set[2*y];
- *p++ = curs->set[2*y + 1];
- *p++ = 0x00;
- *p++ = 0x00;
- }
- memset(p, 0, (32-y)*8);
-
- if(!islinear){
- cyber938xpageset(scr, opage);
- unlock(&scr->devlock);
- }
-
- /*
- * Save the cursor hotpoint and enable the cursor.
- */
- scr->offset = curs->offset;
- vgaxo(Crtx, 0x50, CursorON);
-}
-
-static int
-cyber938xcurmove(VGAscr* scr, Point p)
-{
- int x, xo, y, yo;
-
- /*
- * Mustn't position the cursor offscreen even partially,
- * or it might disappear. Therefore, if x or y is -ve, adjust the
- * cursor origins instead.
- */
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- /*
- * Load the new values.
- */
- vgaxo(Crtx, 0x46, xo);
- vgaxo(Crtx, 0x47, yo);
- vgaxo(Crtx, 0x40, x & 0xFF);
- vgaxo(Crtx, 0x41, (x>>8) & 0xFF);
- vgaxo(Crtx, 0x42, y & 0xFF);
- vgaxo(Crtx, 0x43, (y>>8) & 0xFF);
-
- return 0;
-}
-
-static void
-cyber938xcurenable(VGAscr* scr)
-{
- int i;
- ulong storage;
-
- cyber938xcurdisable(scr);
-
- /*
- * Cursor colours.
- */
- for(i = 0x48; i < 0x4C; i++)
- vgaxo(Crtx, i, 0x00);
- for(i = 0x4C; i < 0x50; i++)
- vgaxo(Crtx, i, 0xFF);
-
- /*
- * Find a place for the cursor data in display memory.
- */
- storage = ((scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024);
- vgaxo(Crtx, 0x44, storage & 0xFF);
- vgaxo(Crtx, 0x45, (storage>>8) & 0xFF);
- storage *= 1024;
- scr->storage = storage;
-
- /*
- * Load, locate and enable the 32x32 cursor.
- * (64x64 is bit 0, X11 format is bit 6 and cursor
- * enable is bit 7). Bit 3 needs to be set on 9382
- * chips otherwise even the white bits are black.
- */
- cyber938xcurload(scr, &arrow);
- cyber938xcurmove(scr, ZP);
- vgaxo(Crtx, 0x50, CursorON);
-}
-
-VGAdev vgacyber938xdev = {
- "cyber938x",
-
- nil, /* enable */
- nil, /* disable */
- cyber938xpage, /* page */
- cyber938xlinear, /* linear */
- nil, /* drawinit */
-};
-
-VGAcur vgacyber938xcur = {
- "cyber938xhwgc",
-
- cyber938xcurenable, /* enable */
- cyber938xcurdisable, /* disable */
- cyber938xcurload, /* load */
- cyber938xcurmove, /* move */
-};
diff --git a/os/pc/vgaet4000.c b/os/pc/vgaet4000.c
deleted file mode 100644
index f3ede446..00000000
--- a/os/pc/vgaet4000.c
+++ /dev/null
@@ -1,270 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static void
-setet4000page(int page)
-{
- uchar p;
-
- p = page & 0x0F;
- p |= p<<4;
- outb(0x3CD, p);
-
- p = (page & 0x30);
- p |= p>>4;
- outb(0x3CB, p);
-}
-
-static void
-et4000page(VGAscr *scr, int page)
-{
- lock(&scr->devlock);
- setet4000page(page);
- unlock(&scr->devlock);
-}
-
-static void
-et4000disable(VGAscr*)
-{
- uchar imaF7;
-
- outb(0x217A, 0xF7);
- imaF7 = inb(0x217B) & ~0x80;
- outb(0x217B, imaF7);
-}
-
-static void
-et4000enable(VGAscr *scr)
-{
- uchar imaF7;
-
- et4000disable(scr);
-
- /*
- * Configure CRTCB for Sprite, 64x64,
- * CRTC pixel overlay.
- */
- outb(0x217A, 0xEF);
- outb(0x217B, 0x02);
-
- /*
- * Cursor goes in the top left corner
- * of the Sprite area, so the horizontal and
- * vertical presets are 0.
- */
- outb(0x217A, 0xE2);
- outb(0x217B, 0x00);
- outb(0x217A, 0xE3);
- outb(0x217B, 0x00);
-
- outb(0x217A, 0xE6);
- outb(0x217B, 0x00);
- outb(0x217A, 0xE7);
- outb(0x217B, 0x00);
-
- /*
- * Find a place for the cursor data in display memory.
- * Must be on a "doubleword" boundary, but put it on a
- * 1024-byte boundary so that there's no danger of it
- * crossing a page.
- */
- scr->storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024;
- scr->storage *= 1024/4;
- outb(0x217A, 0xE8);
- outb(0x217B, scr->storage & 0xFF);
- outb(0x217A, 0xE9);
- outb(0x217B, (scr->storage>>8) & 0xFF);
- outb(0x217A, 0xEA);
- outb(0x217B, (scr->storage>>16) & 0x0F);
- scr->storage *= 4;
-
- /*
- * Row offset in "quadwords". Must be 2 for Sprite.
- * Bag the pixel-panning.
- * Colour depth, must be 2 for Sprite.
- */
- outb(0x217A, 0xEB);
- outb(0x217B, 0x02);
- outb(0x217A, 0xEC);
- outb(0x217B, 0x00);
-
- outb(0x217A, 0xED);
- outb(0x217B, 0x00);
-
- outb(0x217A, 0xEE);
-// if(vgascreen.ldepth == 3)
- outb(0x217B, 0x01);
-// else
-// outb(0x217B, 0x00);
-
- /*
- * Enable the CRTCB/Sprite.
- */
- outb(0x217A, 0xF7);
- imaF7 = inb(0x217B);
- outb(0x217B, 0x80|imaF7);
-}
-
-static void
-et4000load(VGAscr *scr, Cursor *c)
-{
- uchar p0, p1, *mem;
- int i, x, y;
- ushort p;
- uchar clr[2*16], set[2*16];
-
- /*
- * Lock the display memory so we can update the
- * cursor bitmap if necessary.
- */
- lock(&scr->devlock);
-
- /*
- * Disable the cursor.
- * Set the display page (do we need to restore
- * the current contents when done?) and the
- * pointer to the two planes. What if this crosses
- * into a new page?
- */
- et4000disable(scr);
-
- setet4000page(scr->storage>>16);
- mem = (uchar*)KADDR(scr->aperture) + (scr->storage & 0xFFFF);
-
- /*
- * Initialise the 64x64 cursor RAM array. There are 2 planes,
- * p0 and p1. Data is written 4 pixels per byte, with p1 the
- * MS bit of each pixel.
- * The cursor mode gives the following truth table:
- * p1 p0 colour
- * 0 0 Sprite Colour 0 (defined as 0x00)
- * 0 1 Sprite Colour 1 (defined as 0xFF)
- * 1 0 Transparent (allow CRTC pixel pass through)
- * 1 1 Invert (allow CRTC pixel invert through)
- * Put the cursor into the top-left of the 64x64 array.
- *
- * This is almost certainly wrong, since it has not
- * been updated for the 3rd edition color values.
- */
- memmove(clr, c->clr, sizeof(clr));
-// pixreverse(clr, sizeof(clr), 0);
- memmove(set, c->set, sizeof(set));
-// pixreverse(set, sizeof(set), 0);
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16){
- p0 = clr[x+y*2];
- p1 = set[x+y*2];
-
- p = 0x0000;
- for(i = 0; i < 8; i++){
- if(p1 & (1<<(7-i))){
- /* nothing to do */
- }
- else if(p0 & (1<<(7-i)))
- p |= 0x01<<(2*i);
- else
- p |= 0x02<<(2*i);
- }
- *mem++ = p & 0xFF;
- *mem++ = (p>>8) & 0xFF;
- }
- else {
- *mem++ = 0xAA;
- *mem++ = 0xAA;
- }
- }
- }
-
- /*
- * enable the cursor.
- */
- outb(0x217A, 0xF7);
- p = inb(0x217B)|0x80;
- outb(0x217B, p);
-
- unlock(&scr->devlock);
-}
-
-static int
-et4000move(VGAscr *scr, Point p)
-{
- int x, xo, y, yo;
-
- if(canlock(&scr->devlock) == 0)
- return 1;
-
- /*
- * Mustn't position the cursor offscreen even partially,
- * or it disappears. Therefore, if x or y is -ve, adjust the
- * cursor presets instead.
- */
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- /*
- * The cursor image is jerky if we don't do this.
- * The cursor information is probably fetched from
- * display memory during the horizontal blank active
- * time and it doesn't like it if the coordinates
- * are changed underneath.
- */
- while((vgai(Status1) & 0x08) == 0)
- ;
-
- outb(0x217A, 0xE2);
- outb(0x217B, xo);
-
- outb(0x217A, 0xE6);
- outb(0x217B, yo);
-
- outb(0x217A, 0xE1);
- outb(0x217B, (x>>8) & 0xFF);
- outb(0x217A, 0xE0);
- outb(0x217B, x & 0xFF);
- outb(0x217A, 0xE5);
- outb(0x217B, (y>>8) & 0xFF);
- outb(0x217A, 0xE4);
- outb(0x217B, y & 0xFF);
-
- unlock(&scr->devlock);
- return 0;
-}
-
-VGAcur vgaet4000cur = {
- "et4000hwgc",
-
- et4000enable,
- et4000disable,
- et4000load,
- et4000move,
-};
-
-VGAdev vgaet4000dev = {
- "et4000",
-
- 0,
- 0,
- et4000page,
- 0
-};
diff --git a/os/pc/vgahiqvideo.c b/os/pc/vgahiqvideo.c
deleted file mode 100644
index 6ae02b04..00000000
--- a/os/pc/vgahiqvideo.c
+++ /dev/null
@@ -1,274 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum {
- Xrx = 0x3D6, /* Configuration Extensions Index */
-};
-
-static uchar
-hiqvideoxi(long port, uchar index)
-{
- uchar data;
-
- outb(port, index);
- data = inb(port+1);
-
- return data;
-}
-
-static void
-hiqvideoxo(long port, uchar index, uchar data)
-{
- outb(port, index);
- outb(port+1, data);
-}
-
-static ulong
-hiqvideolinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- Pcidev *p;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- aperture = 0;
- if(p = pcimatch(nil, 0x102C, 0)){
- switch(p->did){
- case 0x00C0: /* 69000 HiQVideo */
- case 0x00E0: /* 65550 HiQV32 */
- case 0x00E4: /* 65554 HiQV32 */
- case 0x00E5: /* 65555 HiQV32 */
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
- break;
- default:
- break;
- }
- }
-
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-hiqvideoenable(VGAscr* scr)
-{
- Pcidev *p;
- int align, size, vmsize;
- ulong aperture;
-
- /*
- * Only once, can't be disabled for now.
- */
- if(scr->io)
- return;
- if(p = pcimatch(nil, 0x102C, 0)){
- switch(p->did){
- case 0x00C0: /* 69000 HiQVideo */
- vmsize = 2*1024*1024;
- break;
- case 0x00E0: /* 65550 HiQV32 */
- case 0x00E4: /* 65554 HiQV32 */
- case 0x00E5: /* 65555 HiQV32 */
- switch((hiqvideoxi(Xrx, 0x43)>>1) & 0x03){
- default:
- case 0:
- vmsize = 1*1024*1024;
- break;
- case 1:
- vmsize = 2*1024*1024;
- break;
- }
- break;
- default:
- return;
- }
- }
- else
- return;
-
- size = p->mem[0].size;
- align = 0;
- aperture = hiqvideolinear(scr, &size, &align);
- if(aperture) {
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("hiqvideoscreen", aperture, size);
- }
-
- /*
- * Find a place for the cursor data in display memory.
- * Must be on a 4096-byte boundary.
- * scr->io holds the physical address of the cursor
- * storage area in the framebuffer region.
- */
- scr->storage = vmsize-4096;
- scr->io = scr->aperture+scr->storage;
-}
-
-static void
-hiqvideocurdisable(VGAscr*)
-{
- hiqvideoxo(Xrx, 0xA0, 0x10);
-}
-
-static void
-hiqvideocurload(VGAscr* scr, Cursor* curs)
-{
- uchar *p;
- int x, y;
-
- /*
- * Disable the cursor.
- */
- hiqvideocurdisable(scr);
-
- if(scr->io == 0)
- return;
- p = KADDR(scr->io);
-
- for(y = 0; y < 16; y += 2){
- *p++ = ~(curs->clr[2*y]|curs->set[2*y]);
- *p++ = ~(curs->clr[2*y+1]|curs->set[2*y+1]);
- *p++ = 0xFF;
- *p++ = 0xFF;
- *p++ = ~(curs->clr[2*y+2]|curs->set[2*y+2]);
- *p++ = ~(curs->clr[2*y+3]|curs->set[2*y+3]);
- *p++ = 0xFF;
- *p++ = 0xFF;
- *p++ = curs->set[2*y];
- *p++ = curs->set[2*y+1];
- *p++ = 0x00;
- *p++ = 0x00;
- *p++ = curs->set[2*y+2];
- *p++ = curs->set[2*y+3];
- *p++ = 0x00;
- *p++ = 0x00;
- }
- while(y < 32){
- for(x = 0; x < 64; x += 8)
- *p++ = 0xFF;
- for(x = 0; x < 64; x += 8)
- *p++ = 0x00;
- y += 2;
- }
-
- /*
- * Save the cursor hotpoint and enable the cursor.
- */
- scr->offset = curs->offset;
- hiqvideoxo(Xrx, 0xA0, 0x11);
-}
-
-static int
-hiqvideocurmove(VGAscr* scr, Point p)
-{
- int x, y;
-
- if(scr->io == 0)
- return 1;
-
- if((x = p.x+scr->offset.x) < 0)
- x = 0x8000|(-x & 0x07FF);
- if((y = p.y+scr->offset.y) < 0)
- y = 0x8000|(-y & 0x07FF);
-
- hiqvideoxo(Xrx, 0xA4, x & 0xFF);
- hiqvideoxo(Xrx, 0xA5, (x>>8) & 0xFF);
- hiqvideoxo(Xrx, 0xA6, y & 0xFF);
- hiqvideoxo(Xrx, 0xA7, (y>>8) & 0xFF);
-
- return 0;
-}
-
-static void
-hiqvideocurenable(VGAscr* scr)
-{
- uchar xr80;
-
- hiqvideoenable(scr);
- if(scr->io == 0)
- return;
-
- /*
- * Disable the cursor.
- */
- hiqvideocurdisable(scr);
-
- /*
- * Cursor colours.
- * Can't call setcolor here as cursor is already locked.
- * When done make sure the cursor enable in Xr80 is set.
- */
- xr80 = hiqvideoxi(Xrx, 0x80);
- hiqvideoxo(Xrx, 0x80, xr80|0x01);
- vgao(PaddrW, 0x04);
- vgao(Pdata, Pwhite);
- vgao(Pdata, Pwhite);
- vgao(Pdata, Pwhite);
- vgao(Pdata, Pblack);
- vgao(Pdata, Pblack);
- vgao(Pdata, Pblack);
- hiqvideoxo(Xrx, 0x80, xr80|0x10);
-
- hiqvideoxo(Xrx, 0xA2, (scr->storage>>12)<<4);
- hiqvideoxo(Xrx, 0xA3, (scr->storage>>16) & 0x3F);
-
- /*
- * Load, locate and enable the 32x32 cursor.
- * Cursor enable in Xr80 better be set already.
- */
- hiqvideocurload(scr, &arrow);
- hiqvideocurmove(scr, ZP);
- hiqvideoxo(Xrx, 0xA0, 0x11);
-}
-
-VGAdev vgahiqvideodev = {
- "hiqvideo",
-
- hiqvideoenable, /* enable */
- nil, /* disable */
- nil, /* page */
- hiqvideolinear, /* linear */
-};
-
-VGAcur vgahiqvideocur = {
- "hiqvideohwgc",
-
- hiqvideocurenable, /* enable */
- hiqvideocurdisable, /* disable */
- hiqvideocurload, /* load */
- hiqvideocurmove, /* move */
-};
diff --git a/os/pc/vgai81x.c b/os/pc/vgai81x.c
deleted file mode 100644
index ac840fe6..00000000
--- a/os/pc/vgai81x.c
+++ /dev/null
@@ -1,282 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-typedef struct
-{
- ushort ctl;
- ushort pad;
- ulong base;
- ulong pos;
-} CursorI81x;
-
-enum {
- Fbsize = 8*MB,
-
- hwCur = 0x70080,
-};
-
-static Pcidev *
-i81xpcimatch(void)
-{
- Pcidev *p;
-
- p = nil;
- while((p = pcimatch(p, 0x8086, 0)) != nil){
- switch(p->did){
- default:
- continue;
- case 0x7121:
- case 0x7123:
- case 0x7125:
- case 0x1102:
- case 0x1112:
- case 0x1132:
- case 0x3577: /* IBM R31 uses intel 830M chipset */
- return p;
- }
- }
- return nil;
-}
-
-static ulong
-i81xlinear(VGAscr* scr, int* size, int* align)
-{
- Pcidev *p;
- int oapsize, wasupamem;
- ulong aperture, oaperture, fbuf, fbend, *rp;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- aperture = 0;
- p = i81xpcimatch();
- if(p != nil) {
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
- if(*size > Fbsize)
- *size = Fbsize;
- }
-
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- /* allocate space for frame buffer, populate page table */
- if(oapsize == 0) {
- fbuf = PADDR(xspanalloc(*size, BY2PG, 0));
- fbend = PGROUND(fbuf+*size);
- rp = KADDR(scr->io+0x10000);
- while(fbuf < fbend) {
- *rp++ = fbuf | (1<<0);
- fbuf += BY2PG;
- }
- }
- return aperture;
-}
-
-static void
-i81xenable(VGAscr* scr)
-{
- Pcidev *p;
- int align, size;
- Mach *mach0;
- ulong aperture, pgtbl, *rp, cursor, *pte;
-
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the physical address of
- * the MMIO registers.
- */
- if(scr->io)
- return;
- p = i81xpcimatch();
- if(p == nil)
- return;
- scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
- if(scr->io == 0)
- return;
-
- /* allocate page table */
- pgtbl = PADDR(xspanalloc(64*1024, BY2PG, 0));
- rp = KADDR(scr->io+0x2020);
- *rp = pgtbl | 1;
-
- addvgaseg("i81xmmio", (ulong)scr->io, p->mem[0].size);
-
- size = p->mem[0].size;
- align = 0;
- aperture = i81xlinear(scr, &size, &align);
- if(aperture){
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("i81xscreen", aperture, size);
- }
-
- /*
- * allocate space for the cursor data in system memory.
- * must be uncached.
- */
- cursor = (ulong)xspanalloc(BY2PG, BY2PG, 0);
- mach0 = MACHP(0);
- pte = mmuwalk(mach0->pdb, cursor, 2, 0);
- if(pte == nil)
- panic("i81x cursor");
- *pte |= PTEUNCACHED;
- scr->storage = PADDR(cursor);
-}
-
-static void
-i81xcurdisable(VGAscr* scr)
-{
- CursorI81x *hwcurs;
-
- if(scr->io == 0)
- return;
- hwcurs = KADDR(scr->io+hwCur);
- hwcurs->ctl = (1<<4);
-}
-
-static void
-i81xcurload(VGAscr* scr, Cursor* curs)
-{
- int y;
- uchar *p;
- CursorI81x *hwcurs;
-
- if(scr->io == 0)
- return;
- hwcurs = KADDR(scr->io+hwCur);
-
- /*
- * Disable the cursor then load the new image in
- * the top-left of the 32x32 array.
- * Unused portions of the image have been initialised to be
- * transparent.
- */
- hwcurs->ctl = (1<<4);
- p = KADDR(scr->storage);
- for(y = 0; y < 16; y += 2) {
- *p++ = ~(curs->clr[2*y]|curs->set[2*y]);
- *p++ = ~(curs->clr[2*y+1]|curs->set[2*y+1]);
- p += 2;
- *p++ = ~(curs->clr[2*y+2]|curs->set[2*y+2]);
- *p++ = ~(curs->clr[2*y+3]|curs->set[2*y+3]);
- p += 2;
- *p++ = curs->set[2*y];
- *p++ = curs->set[2*y+1];
- p += 2;
- *p++ = curs->set[2*y+2];
- *p++ = curs->set[2*y+3];
- p += 2;
- }
-
- /*
- * Save the cursor hotpoint and enable the cursor.
- * The 0,0 cursor point is top-left.
- */
- scr->offset.x = curs->offset.x;
- scr->offset.y = curs->offset.y;
- hwcurs->ctl = (1<<4)|1;
-}
-
-static int
-i81xcurmove(VGAscr* scr, Point p)
-{
- int x, y;
- ulong pos;
- CursorI81x *hwcurs;
-
- if(scr->io == 0)
- return 1;
- hwcurs = KADDR(scr->io+hwCur);
-
- x = p.x+scr->offset.x;
- y = p.y+scr->offset.y;
- pos = 0;
- if(x < 0) {
- pos |= (1<<15);
- x = -x;
- }
- if(y < 0) {
- pos |= (1<<31);
- y = -y;
- }
- pos |= ((y&0x7ff)<<16)|(x&0x7ff);
- hwcurs->pos = pos;
-
- return 0;
-}
-
-static void
-i81xcurenable(VGAscr* scr)
-{
- int i;
- uchar *p;
- CursorI81x *hwcurs;
-
- i81xenable(scr);
- if(scr->io == 0)
- return;
- hwcurs = KADDR(scr->io+hwCur);
-
- /*
- * Initialise the 32x32 cursor to be transparent in 2bpp mode.
- */
- hwcurs->base = scr->storage;
- p = KADDR(scr->storage);
- for(i = 0; i < 32/2; i++) {
- memset(p, 0xff, 8);
- memset(p+8, 0, 8);
- p += 16;
- }
- /*
- * Load, locate and enable the 32x32 cursor in 2bpp mode.
- */
- i81xcurload(scr, &arrow);
- i81xcurmove(scr, ZP);
-}
-
-VGAdev vgai81xdev = {
- "i81x",
-
- i81xenable,
- nil,
- nil,
- i81xlinear,
-};
-
-VGAcur vgai81xcur = {
- "i81xhwgc",
-
- i81xcurenable,
- i81xcurdisable,
- i81xcurload,
- i81xcurmove,
-};
diff --git a/os/pc/vgamach64xx.c b/os/pc/vgamach64xx.c
deleted file mode 100644
index 322c449c..00000000
--- a/os/pc/vgamach64xx.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-char Eunsupportedformat[] = "unsupported video format";
-char Enotconfigured[] = "device not configured";
-
-#define SCALE_ZERO_EXTEND 0x0
-#define SCALE_DYNAMIC 0x1
-#define SCALE_RED_TEMP_6500K 0x0
-#define SCALE_RED_TEMP_9800K 0x2
-#define SCALE_HORZ_BLEND 0x0
-#define SCALE_HORZ_REP 0x4
-#define SCALE_VERT_BLEND 0x0
-#define SCALE_VERT_REP 0x8
-#define SCALE_BANDWIDTH_NORMAL 0x0
-#define SCALE_BANDWIDTH_EXCEEDED 0x4000000
-#define SCALE_BANDWIDTH_RESET 0x4000000
-#define SCALE_CLK_ACTIVITY 0x0
-#define SCALE_CLK_CONTINUOUS 0x20000000
-#define OVERLAY_DISABLE 0x0
-#define OVERLAY_ENABLE 0x40000000
-#define SCALE_DISABLE 0x0
-#define SCALE_ENABLE 0x80000000
-
-#define SCALER_FRAME_READ_MODE_FULL 0x0
-#define SCALER_BUF_MODE_SINGLE 0x0
-#define SCALER_BUF_MODE_DOUBLE 0x40000
-#define SCALER_BUF_NEXT_0 0x0
-#define SCALER_BUF_NEXT_1 0x80000
-#define SCALER_BUF_STATUS_0 0x0
-#define SCALER_BUF_STATUS_1 0x100000
-
-#define OVERLAY_MIX_G_CMP 0x0
-#define OVERLAY_MIX_ALWAYS_G 0x100
-#define OVERLAY_MIX_ALWAYS_V 0x200
-#define OVERLAY_MIX_NOT_G 0x300
-#define OVERLAY_MIX_NOT_V 0x400
-#define OVERLAY_MIX_G_XOR_V 0x500
-#define OVERLAY_MIX_NOT_G_XOR_V 0x600
-#define OVERLAY_MIX_V_CMP 0x700
-#define OVERLAY_MIX_NOT_G_OR_NOT_V 0x800
-#define OVERLAY_MIX_G_OR_NOT_V 0x900
-#define OVERLAY_MIX_NOT_G_OR_V 0xA00
-#define OVERLAY_MIX_G_OR_V 0xB00
-#define OVERLAY_MIX_G_AND_V 0xC00
-#define OVERLAY_MIX_NOT_G_AND_V 0xD00
-#define OVERLAY_MIX_G_AND_NOT_V 0xE00
-#define OVERLAY_MIX_NOT_G_AND_NOT_V 0xF00
-#define OVERLAY_EXCLUSIVE_NORMAL 0x0
-#define OVERLAY_EXCLUSIVE_V_ONLY 0x80000000
-
-#define VIDEO_IN_8BPP 0x2
-#define VIDEO_IN_16BPP 0x4
-#define VIDEO_IN_32BPP 0x6
-#define VIDEO_IN_VYUY422 0xB /*16 bpp */
-#define VIDEO_IN_YVYU422 0xC /* 16 bpp */
-#define SCALE_IN_15BPP 0x30000 /* aRGB 1555 */
-#define SCALE_IN_16BPP 0x40000 /* RGB 565 */
-#define SCALE_IN_32BPP 0x60000 /* aRGB 8888 */
-#define SCALE_IN_YUV9 0x90000 /* planar */
-#define SCALE_IN_YUV12 0xA0000 /* planar */
-#define SCALE_IN_VYUY422 0xB0000 /* 16 bpp */
-#define SCALE_IN_YVYU422 0xC0000 /* 16 bpp */
-#define HOST_YUV_APERTURE_UPPER 0x0
-#define HOST_YUV_APERTURE_LOWER 0x20000000
-#define HOST_MEM_MODE_Y 0x40000000
-#define HOST_MEM_MODE_U 0x80000000
-#define HOST_MEM_MODE_V 0xC0000000
-#define HOST_MEM_MODE_NORMAL HOST_YUV_APERTURE_UPPER
-
-static Chan *ovl_chan; /* Channel of controlling process */
-static int ovl_width; /* Width of input overlay buffer */
-static int ovl_height; /* Height of input overlay buffer */
-static int ovl_format; /* Overlay format */
-static ulong ovl_fib; /* Frame in bytes */
-
-enum {
- VTGTB1S1 = 0x01, // Asic description for VTB1S1 and GTB1S1.
- VT4GTIIC = 0x3A, // asic descr for VT4 and RAGE IIC
- GTB1U1 = 0x19, // Asic description for GTB1U1.
- GTB1S2 = 0x41, // Asic description for GTB1S2.
- GTB2U1 = 0x1A,
- GTB2U2 = 0x5A,
- GTB2U3 = 0x9A,
- GTIIIC1U1 = 0x1B, // 3D RAGE PRO asic descrp.
- GTIIIC1U2 = 0x5B, // 3D RAGE PRO asic descrp.
- GTIIIC2U1 = 0x1C, // 3D RAGE PRO asic descrp.
- GTIIIC2U2 = 0x5C, // 3D RAGE PRO asic descrp.
- GTIIIC2U3 = 0x7C, // 3D RAGE PRO asic descrp.
- GTBC = 0x3A, // 3D RAGE IIC asic descrp.
- LTPRO = 0x9C, // 3D RAGE LT PRO
-};
-
-/*
- * ATI Mach64(CT|ET|G*|V*|L*).
- */
-typedef struct Mach64types Mach64types;
-struct Mach64types {
- ushort m64_id; /* Chip ID */
- int m64_vtgt; /* Is this a VT or GT chipset? */
- ulong m64_ovlclock; /* Max. overlay clock frequency */
- int m64_pro; /* Is this a PRO? */
-};
-
-static ulong mach64refclock;
-static Mach64types *mach64type;
-static int mach64revb; /* Revision B or greater? */
-static ulong mach64overlay; /* Overlay buffer */
-
-static Mach64types mach64s[] = {
- ('C'<<8)|'T', 0, 1350000, /*?*/ 0, /* 4354: CT */
- ('E'<<8)|'T', 0, 1350000, /*?*/ 0, /* 4554: ET */
- ('G'<<8)|'B', 1, 1250000, 1, /* 4742: 264GT PRO */
- ('G'<<8)|'D', 1, 1250000, 1, /* 4744: 264GT PRO */
- ('G'<<8)|'I', 1, 1250000, 1, /* 4749: 264GT PRO */
- ('G'<<8)|'M', 0, 1350000, 0, /* 474D: Rage XL */
- ('G'<<8)|'P', 1, 1250000, 1, /* 4750: 264GT PRO */
- ('G'<<8)|'Q', 1, 1250000, 1, /* 4751: 264GT PRO */
- ('G'<<8)|'R', 1, 1250000, 1, /* 4752: */
- ('G'<<8)|'T', 1, 800000, 0, /* 4754: 264GT[B] */
- ('G'<<8)|'U', 1, 1000000, 0, /* 4755: 264GT DVD */
- ('G'<<8)|'V', 1, 1000000, 0, /* 4756: Rage2C */
- ('G'<<8)|'Z', 1, 1000000, 0, /* 475A: Rage2C */
- ('V'<<8)|'T', 1, 800000, 0, /* 5654: 264VT/GT/VTB */
- ('V'<<8)|'U', 1, 800000, 0, /* 5655: 264VT3 */
- ('V'<<8)|'V', 1, 1000000, 0, /* 5656: 264VT4 */
- ('L'<<8)|'B', 0, 1350000, 1, /* 4C42: Rage LTPro AGP */
- ('L'<<8)|'I', 0, 1350000, 0, /* 4C49: Rage LTPro AGP */
- ('L'<<8)|'M', 0, 1350000, 0, /* 4C4D: Rage Mobility */
- ('L'<<8)|'P', 0, 1350000, 1, /* 4C50: 264LT PRO */
-};
-
-
-static int hwfill(VGAscr*, Rectangle, ulong);
-static int hwscroll(VGAscr*, Rectangle, Rectangle);
-static void initengine(VGAscr*);
-
-static Pcidev*
-mach64xxpci(void)
-{
- Pcidev *p;
- int i;
-
- if((p = pcimatch(nil, 0x1002, 0)) == nil)
- return nil;
-
- for (i = 0; i != nelem(mach64s); i++)
- if (mach64s[i].m64_id == p->did) {
- mach64type = &mach64s[i];
- return p;
- }
- return nil;
-}
-
-static void
-mach64xxenable(VGAscr* scr)
-{
- Pcidev *p;
-
- /*
- * Only once, can't be disabled for now.
- */
- if(scr->io)
- return;
- if(p = mach64xxpci()){
- scr->id = p->did;
-
- /*
- * The CT doesn't always have the I/O base address
- * in the PCI base registers. There is a way to find
- * it via the vendor-specific PCI config space but
- * this will do for now.
- */
- scr->io = p->mem[1].bar & ~0x03;
-
- if(scr->io == 0)
- scr->io = 0x2EC;
- }
-}
-
-static ulong
-mach64xxlinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, osize, oaperture;
- int i, oapsize, wasupamem;
- Pcidev *p;
-
- osize = *size;
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- if(p = mach64xxpci()){
- for(i=0; i<nelem(p->mem); i++){
- if(p->mem[i].size >= *size
- && ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0)
- break;
- }
- if(i >= nelem(p->mem)){
- print("vgamach64xx: aperture not found\n");
- return 0;
- }
- aperture = p->mem[i].bar & ~0x0F;
- *size = p->mem[i].size;
- }
- else
- aperture = 0;
-
- if(wasupamem)
- upafree(oaperture, oapsize);
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0))
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 1;
-
- scr->mmio = KADDR(aperture+osize-0x400);
- if(oaperture && oaperture != aperture)
- print("warning (BUG): redefinition of aperture does not change mach64mmio segment\n");
- addvgaseg("mach64mmio", aperture+osize-BY2PG, BY2PG);
- addvgaseg("mach64screen", aperture, osize);
-
- return aperture;
-}
-
-enum {
- CrtcOffPitch = 0x05,
- CrtcGenCtl = 0x07,
- CurClr0 = 0x0B, /* I/O Select */
- CurClr1 = 0x0C,
- CurOffset = 0x0D,
- CurHVposn = 0x0E,
- CurHVoff = 0x0F,
- BusCntl = 0x13,
- GenTestCntl = 0x19,
-
- CrtcHsyncDis = 0x04,
- CrtcVsyncDis = 0x08,
-
- ContextMask = 0x100, /* not accessible via I/O */
- FifoStat,
- GuiStat,
- DpFrgdClr,
- DpBkgdClr,
- DpWriteMask,
- DpMix,
- DpPixWidth,
- DpSrc,
- ClrCmpCntl,
- GuiTrajCntl,
- ScLeftRight,
- ScTopBottom,
- DstOffPitch,
- DstYX,
- DstHeightWidth,
- DstCntl,
- DstHeight,
- DstBresErr,
- DstBresInc,
- DstBresDec,
- SrcCntl,
- SrcHeight1Width1,
- SrcHeight2Width2,
- SrcYX,
- SrcWidth1,
- SrcYXstart,
- HostCntl,
- PatReg0,
- PatReg1,
- PatCntl,
- ScBottom,
- ScLeft,
- ScRight,
- ScTop,
- ClrCmpClr,
- ClrCmpMask,
- DpChainMask,
- SrcOffPitch,
- LcdIndex,
- LcdData,
- ClockCntl,
- OverlayScaleCntl,
- ConfigChipId,
- Buf0Pitch,
- ScalerBuf0Pitch,
- CaptureConfig,
- OverlayKeyCntl,
- ScalerColourCntl,
- ScalerHCoef0,
- ScalerHCoef1,
- ScalerHCoef2,
- ScalerHCoef3,
- ScalerHCoef4,
- VideoFormat,
- Buf0Offset,
- ScalerBuf0Offset,
- CrtcGenCntl,
- OverlayScaleInc,
- OverlayYX,
- OverlayYXEnd,
- ScalerHeightWidth,
- HTotalDisp,
- VTotalDisp,
-};
-
-enum {
- LCD_ConfigPanel = 0,
- LCD_GenCtrl,
- LCD_DstnCntl,
- LCD_HfbPitchAddr,
- LCD_HorzStretch,
- LCD_VertStretch,
- LCD_ExtVertStretch,
- LCD_LtGio,
- LCD_PowerMngmnt,
- LCD_ZvgPio,
- Nlcd,
-};
-
-#define Bank1 (-0x100) /* 1KB */
-
-static int mmoffset[] = {
- [HTotalDisp] 0x00,
- [VTotalDisp] 0x02,
- [CrtcOffPitch] 0x05,
- [CrtcGenCntl] 0x07,
- [CurClr0] 0x18,
- [CurClr1] 0x19,
- [CurOffset] 0x1A,
- [CurHVposn] 0x1B,
- [CurHVoff] 0x1C,
- [ClockCntl] 0x24,
- [BusCntl] 0x28,
- [LcdIndex] 0x29,
- [LcdData] 0x2A,
- [GenTestCntl] 0x34,
- [ConfigChipId] 0x38,
- [DstOffPitch] 0x40,
- [DstYX] 0x43,
- [DstHeight] 0x45,
- [DstHeightWidth] 0x46,
- [DstBresErr] 0x49,
- [DstBresInc] 0x4A,
- [DstBresDec] 0x4B,
- [DstCntl] 0x4C,
- [SrcOffPitch] 0x60,
- [SrcYX] 0x63,
- [SrcWidth1] 0x64,
- [SrcYXstart] 0x69,
- [SrcHeight1Width1] 0x66,
- [SrcHeight2Width2] 0x6C,
- [SrcCntl] 0x6D,
- [HostCntl] 0x90,
- [PatReg0] 0xA0,
- [PatReg1] 0xA1,
- [PatCntl] 0xA2,
- [ScLeft] 0xA8,
- [ScRight] 0xA9,
- [ScLeftRight] 0xAA,
- [ScTop] 0xAB,
- [ScBottom] 0xAC,
- [ScTopBottom] 0xAD,
- [DpBkgdClr] 0xB0,
- [DpFrgdClr] 0xB1,
- [DpWriteMask] 0xB2,
- [DpChainMask] 0xB3,
- [DpPixWidth] 0xB4,
- [DpMix] 0xB5,
- [DpSrc] 0xB6,
- [ClrCmpClr] 0xC0,
- [ClrCmpMask] 0xC1,
- [ClrCmpCntl] 0xC2,
- [FifoStat] 0xC4,
- [ContextMask] 0xC8,
- [GuiTrajCntl] 0xCC,
- [GuiStat] 0xCE,
-
- /* Bank1 */
- [OverlayYX] Bank1 + 0x00,
- [OverlayYXEnd] Bank1 + 0x01,
- [OverlayKeyCntl] Bank1 + 0x06,
- [OverlayScaleInc] Bank1 + 0x08,
- [OverlayScaleCntl] Bank1 + 0x09,
- [ScalerHeightWidth] Bank1 + 0x0A,
- [ScalerBuf0Offset] Bank1 + 0x0D,
- [ScalerBuf0Pitch] Bank1 + 0x0F,
- [VideoFormat] Bank1 + 0x12,
- [CaptureConfig] Bank1 + 0x14,
- [Buf0Offset] Bank1 + 0x20,
- [Buf0Pitch] Bank1 + 0x23,
- [ScalerColourCntl] Bank1 + 0x54,
- [ScalerHCoef0] Bank1 + 0x55,
- [ScalerHCoef1] Bank1 + 0x56,
- [ScalerHCoef2] Bank1 + 0x57,
- [ScalerHCoef3] Bank1 + 0x58,
- [ScalerHCoef4] Bank1 + 0x59,
-};
-
-static ulong
-ior32(VGAscr* scr, int r)
-{
- if(scr->io == 0x2EC || scr->io == 0x1C8)
- return inl((r<<10)+scr->io);
- if(r >= 0x100 && scr->mmio != nil)
- return scr->mmio[mmoffset[r]];
- return inl((mmoffset[r]<<2)+scr->io);
-}
-
-static void
-iow32(VGAscr* scr, int r, ulong l)
-{
- if(scr->io == 0x2EC || scr->io == 0x1C8)
- outl(((r)<<10)+scr->io, l);
- else if(r >= 0x100 && scr->mmio != nil)
- scr->mmio[mmoffset[r]] = l;
- else
- outl((mmoffset[r]<<2)+scr->io, l);
-}
-
-static ulong
-lcdr32(VGAscr *scr, ulong r)
-{
- ulong or;
-
- or = ior32(scr, LcdIndex);
- iow32(scr, LcdIndex, (or&~0x0F) | (r&0x0F));
- return ior32(scr, LcdData);
-}
-
-static void
-lcdw32(VGAscr *scr, ulong r, ulong v)
-{
- ulong or;
-
- or = ior32(scr, LcdIndex);
- iow32(scr, LcdIndex, (or&~0x0F) | (r&0x0F));
- iow32(scr, LcdData, v);
-}
-
-static void
-mach64xxcurdisable(VGAscr* scr)
-{
- ulong r;
-
- r = ior32(scr, GenTestCntl);
- iow32(scr, GenTestCntl, r & ~0x80);
-}
-
-static void
-mach64xxcurload(VGAscr* scr, Cursor* curs)
-{
- uchar *p;
- int i, y;
- ulong c, s, m, r;
-
- /*
- * Disable the cursor.
- */
- r = ior32(scr, GenTestCntl);
- iow32(scr, GenTestCntl, r & ~0x80);
-
- p = KADDR(scr->aperture);
- p += scr->storage;
-
- /*
- * Initialise the 64x64 cursor RAM array.
- * The cursor mode gives the following truth table:
- * p1 p0 colour
- * 0 0 Cursor Colour 0
- * 0 1 Cursor Colour 1
- * 1 0 Transparent
- * 1 1 Complement
- * Put the cursor into the top-right of the 64x64 array.
- */
- for(y = 0; y < 16; y++){
- for(i = 0; i < (64-16)/8; i++){
- *p++ = 0xAA;
- *p++ = 0xAA;
- }
-
- c = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1];
- s = (curs->set[2*y]<<8)|curs->set[y*2 + 1];
-
- m = 0x00000000;
- for(i = 0; i < 16; i++){
- if(s & (1<<(15-i)))
- m |= 0x01<<(2*i);
- else if(c & (1<<(15-i))){
- /* nothing to do */
- }
- else
- m |= 0x02<<(2*i);
- }
- *p++ = m;
- *p++ = m>>8;
- *p++ = m>>16;
- *p++ = m>>24;
- }
- memset(p, 0xAA, (64-16)*16);
-
- /*
- * Set the cursor hotpoint and enable the cursor.
- */
- scr->offset = curs->offset;
- iow32(scr, GenTestCntl, 0x80|r);
-}
-
-static int
-ptalmostinrect(Point p, Rectangle r)
-{
- return p.x>=r.min.x && p.x<=r.max.x &&
- p.y>=r.min.y && p.y<=r.max.y;
-}
-
-/*
- * If necessary, translate the rectangle physr
- * some multiple of [dx dy] so that it includes p.
- * Return 1 if the rectangle changed.
- */
-static int
-screenpan(Point p, Rectangle *physr, int dx, int dy)
-{
- int d;
-
- if(ptalmostinrect(p, *physr))
- return 0;
-
- if(p.y < physr->min.y){
- d = physr->min.y - (p.y&~(dy-1));
- physr->min.y -= d;
- physr->max.y -= d;
- }
- if(p.y > physr->max.y){
- d = ((p.y+dy-1)&~(dy-1)) - physr->max.y;
- physr->min.y += d;
- physr->max.y += d;
- }
-
- if(p.x < physr->min.x){
- d = physr->min.x - (p.x&~(dx-1));
- physr->min.x -= d;
- physr->max.x -= d;
- }
- if(p.x > physr->max.x){
- d = ((p.x+dx-1)&~(dx-1)) - physr->max.x;
- physr->min.x += d;
- physr->max.x += d;
- }
- return 1;
-}
-
-static int
-mach64xxcurmove(VGAscr* scr, Point p)
-{
- int x, xo, y, yo;
- int dx;
- ulong off, pitch;
-
- /*
- * If the point we want to display is outside the current
- * screen rectangle, pan the screen to display it.
- *
- * We have to move in 64-bit chunks.
- */
- if(scr->gscreen->depth == 24)
- dx = (64*3)/24;
- else
- dx = 64 / scr->gscreen->depth;
-
- if(panning && screenpan(p, &physgscreenr, dx, 1)){
- off = (physgscreenr.min.y*Dx(scr->gscreen->r)+physgscreenr.min.x)/dx;
- pitch = Dx(scr->gscreen->r)/8;
- iow32(scr, CrtcOffPitch, (pitch<<22)|off);
- }
-
- p.x -= physgscreenr.min.x;
- p.y -= physgscreenr.min.y;
-
- /*
- * Mustn't position the cursor offscreen even partially,
- * or it disappears. Therefore, if x or y is -ve, adjust the
- * cursor presets instead. If y is negative also have to
- * adjust the starting offset.
- */
- if((x = p.x+scr->offset.x) < 0){
- xo = x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = y;
- y = 0;
- }
- else
- yo = 0;
-
- iow32(scr, CurHVoff, ((64-16-yo)<<16)|(64-16-xo));
- iow32(scr, CurOffset, scr->storage/8 + (-yo*2));
- iow32(scr, CurHVposn, (y<<16)|x);
-
- return 0;
-}
-
-static void
-mach64xxcurenable(VGAscr* scr)
-{
- ulong r, storage;
-
- mach64xxenable(scr);
- if(scr->io == 0)
- return;
-
- r = ior32(scr, GenTestCntl);
- iow32(scr, GenTestCntl, r & ~0x80);
-
- iow32(scr, CurClr0, (Pwhite<<24)|(Pwhite<<16)|(Pwhite<<8)|Pwhite);
- iow32(scr, CurClr1, (Pblack<<24)|(Pblack<<16)|(Pblack<<8)|Pblack);
-
- /*
- * Find a place for the cursor data in display memory.
- * Must be 64-bit aligned.
- */
- storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+7)/8;
- iow32(scr, CurOffset, storage);
- scr->storage = storage*8;
-
- /*
- * Cursor goes in the top right corner of the 64x64 array
- * so the horizontal and vertical presets are 64-16.
- */
- iow32(scr, CurHVposn, (0<<16)|0);
- iow32(scr, CurHVoff, ((64-16)<<16)|(64-16));
-
- /*
- * Load, locate and enable the 64x64 cursor.
- */
- mach64xxcurload(scr, &arrow);
- mach64xxcurmove(scr, ZP);
- iow32(scr, GenTestCntl, 0x80|r);
-}
-
-static void
-waitforfifo(VGAscr *scr, int entries)
-{
- int x;
-
- x = 0;
- while((ior32(scr, FifoStat)&0xFF) > (0x8000>>entries) && x++ < 1000000)
- ;
- if(x >= 1000000)
- iprint("fifo %d stat %.8lux %.8lux scrio %.8lux mmio %p scr %p pc %luX\n", entries, ior32(scr, FifoStat), scr->mmio[mmoffset[FifoStat]], scr->io, scr->mmio, scr, getcallerpc(&scr));
-}
-
-static void
-waitforidle(VGAscr *scr)
-{
- int x;
-
- waitforfifo(scr, 16);
- x = 0;
- while((ior32(scr, GuiStat)&1) && x++ < 1000000)
- ;
- if(x >= 1000000)
- iprint("idle stat %.8lux %.8lux scrio %.8lux mmio %p scr %p pc %luX\n", ior32(scr, GuiStat), scr->mmio[mmoffset[GuiStat]], scr->io, scr->mmio, scr, getcallerpc(&scr));
-}
-
-static void
-resetengine(VGAscr *scr)
-{
- ulong x;
- x = ior32(scr, GenTestCntl);
- iow32(scr, GenTestCntl, x&~0x100);
- iow32(scr, GenTestCntl, x|0x100);
- iow32(scr, BusCntl, ior32(scr, BusCntl)|0x00A00000);
-}
-
-static void
-init_overlayclock(VGAscr *scr)
-{
- uchar *cc, save, pll_ref_div, pll_vclk_cntl, vclk_post_div,
- vclk_fb_div, ecp_div;
- int i;
- ulong dotclock;
-
- /* Taken from GLX */
- /* Get monitor dotclock, check for Overlay Scaler clock limit */
- cc = (uchar *)&scr->mmio[mmoffset[ClockCntl]];
- save = cc[1]; i = cc[0] & 3;
- cc[1] = 2<<2; pll_ref_div = cc[2];
- cc[1] = 5<<2; pll_vclk_cntl = cc[2];
- cc[1] = 6<<2; vclk_post_div = (cc[2]>>(i+i)) & 3;
- cc[1] = (7+i)<<2; vclk_fb_div = cc[2];
-
- dotclock = 2 * mach64refclock * vclk_fb_div /
- (pll_ref_div * (1 << vclk_post_div));
- /* ecp_div: 0=dotclock, 1=dotclock/2, 2=dotclock/4 */
- ecp_div = dotclock / mach64type->m64_ovlclock;
- if (ecp_div>2) ecp_div = 2;
-
- /* Force a scaler clock factor of 1 if refclock *
- * is unknown (VCLK_SRC not PLLVCLK) */
- if ((pll_vclk_cntl & 0x03) != 0x03)
- ecp_div = 0;
- if ((pll_vclk_cntl & 0x30) != ecp_div<<4) {
- cc[1] = (5<<2)|2;
- cc[2] = (pll_vclk_cntl&0xCF) | (ecp_div<<4);
- }
-
- /* Restore PLL Register Index */
- cc[1] = save;
-}
-
-static void
-initengine(VGAscr *scr)
-{
- ulong pitch;
- uchar *bios;
- ushort table;
-
- pitch = Dx(scr->gscreen->r)/8;
- if(scr->gscreen->depth == 24)
- pitch *= 3;
-
- resetengine(scr);
- waitforfifo(scr, 14);
- iow32(scr, ContextMask, ~0);
- iow32(scr, DstOffPitch, pitch<<22);
- iow32(scr, DstYX, 0);
- iow32(scr, DstHeight, 0);
- iow32(scr, DstBresErr, 0);
- iow32(scr, DstBresInc, 0);
- iow32(scr, DstBresDec, 0);
- iow32(scr, DstCntl, 0x23);
- iow32(scr, SrcOffPitch, pitch<<22);
- iow32(scr, SrcYX, 0);
- iow32(scr, SrcHeight1Width1, 1);
- iow32(scr, SrcYXstart, 0);
- iow32(scr, SrcHeight2Width2, 1);
- iow32(scr, SrcCntl, 0x01);
-
- waitforfifo(scr, 13);
- iow32(scr, HostCntl, 0);
- iow32(scr, PatReg0, 0);
- iow32(scr, PatReg1, 0);
- iow32(scr, PatCntl, 0);
- iow32(scr, ScLeft, 0);
- iow32(scr, ScTop, 0);
- iow32(scr, ScBottom, 0xFFFF);
- iow32(scr, ScRight, 0xFFFF);
- iow32(scr, DpBkgdClr, 0);
- iow32(scr, DpFrgdClr, ~0);
- iow32(scr, DpWriteMask, ~0);
- iow32(scr, DpMix, 0x70003);
- iow32(scr, DpSrc, 0x00010100);
-
- waitforfifo(scr, 3);
- iow32(scr, ClrCmpClr, 0);
- iow32(scr, ClrCmpMask, ~0);
- iow32(scr, ClrCmpCntl, 0);
-
- waitforfifo(scr, 2);
- switch(scr->gscreen->depth){
- case 8:
- case 24: /* [sic] */
- iow32(scr, DpPixWidth, 0x00020202);
- iow32(scr, DpChainMask, 0x8080);
- break;
- case 16:
- iow32(scr, DpPixWidth, 0x00040404);
- iow32(scr, DpChainMask, 0x8410);
- break;
- case 32:
- iow32(scr, DpPixWidth, 0x00060606);
- iow32(scr, DpChainMask, 0x8080);
- break;
- }
-
- /* Get the base freq from the BIOS */
- bios = KADDR(0xC000);
- table = *(ushort *)(bios + 0x48);
- table = *(ushort *)(bios + table + 0x10);
- switch (*(ushort *)(bios + table + 0x08)) {
- case 2700:
- mach64refclock = 270000;
- break;
- case 2863:
- case 2864:
- mach64refclock = 286363;
- break;
- case 2950:
- mach64refclock = 294989;
- break;
- case 1432:
- default:
- mach64refclock = 143181;
- break ;
- }
-
- /* Figure out which revision this chip is */
- switch ((scr->mmio[mmoffset[ConfigChipId]] >> 24) & 0xFF) {
- case VTGTB1S1:
- case GTB1U1:
- case GTB1S2:
- case GTB2U1:
- case GTB2U2:
- case GTB2U3:
- case GTBC:
- case GTIIIC1U1:
- case GTIIIC1U2:
- case GTIIIC2U1:
- case GTIIIC2U2:
- case GTIIIC2U3:
- case LTPRO:
- mach64revb = 1;
- break;
- default:
- mach64revb = 0;
- break;
- }
-
- waitforidle(scr);
-}
-
-static int
-mach64hwfill(VGAscr *scr, Rectangle r, ulong sval)
-{
- ulong pitch;
- ulong ctl;
-
-if(drawdebug)
- iprint("hwfill %R val %lux...\n", r, sval);
-
- /* shouldn't happen */
- if(scr->io == 0x2EC || scr->io == 0x1C8 || scr->io == 0)
- return 0;
-
- pitch = Dx(scr->gscreen->r)/8;
- ctl = 1|2; /* left-to-right, top-to-bottom */
- if(scr->gscreen->depth == 24){
- r.min.x *= 3;
- r.max.x *= 3;
- pitch *= 3;
- ctl |= (1<<7)|(((r.min.x/4)%6)<<8);
- }
-
- waitforfifo(scr, 11);
- iow32(scr, DpFrgdClr, sval);
- iow32(scr, DpWriteMask, 0xFFFFFFFF);
- iow32(scr, DpMix, 0x00070003);
- iow32(scr, DpSrc, 0x00000111);
- iow32(scr, ClrCmpCntl, 0x00000000);
- iow32(scr, ScLeftRight, 0x1FFF0000);
- iow32(scr, ScTopBottom, 0x1FFF0000);
- iow32(scr, DstOffPitch, pitch<<22);
- iow32(scr, DstCntl, ctl);
- iow32(scr, DstYX, (r.min.x<<16)|r.min.y);
- iow32(scr, DstHeightWidth, (Dx(r)<<16)|Dy(r));
-
- waitforidle(scr);
- return 1;
-}
-
-static int
-mach64hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
-{
- ulong pitch;
- Point dp, sp;
- ulong ctl;
- int dx, dy;
-
- dx = Dx(r);
- dy = Dy(r);
- pitch = Dx(scr->gscreen->r)/8;
- if(scr->gscreen->depth == 24){
- dx *= 3;
- pitch *= 3;
- r.min.x *= 3;
- sr.min.x *= 3;
- }
-
- ctl = 0;
- if(r.min.x <= sr.min.x){
- ctl |= 1;
- dp.x = r.min.x;
- sp.x = sr.min.x;
- }else{
- dp.x = r.min.x+dx-1;
- sp.x = sr.min.x+dx-1;
- }
-
- if(r.min.y <= sr.min.y){
- ctl |= 2;
- dp.y = r.min.y;
- sp.y = sr.min.y;
- }else{
- dp.y = r.min.y+dy-1;
- sp.y = sr.min.y+dy-1;
- }
-
- if(scr->gscreen->depth == 24)
- ctl |= (1<<7)|(((dp.x/4)%6)<<8);
-
- waitforfifo(scr, 6);
- iow32(scr, ScLeftRight, 0x1FFF0000);
- iow32(scr, ScTopBottom, 0x1FFF0000);
- iow32(scr, DpWriteMask, 0xFFFFFFFF);
- iow32(scr, DpMix, 0x00070003);
- iow32(scr, DpSrc, 0x00000300);
- iow32(scr, ClrCmpCntl, 0x00000000);
-
- waitforfifo(scr, 8);
- iow32(scr, SrcOffPitch, pitch<<22);
- iow32(scr, SrcCntl, 0x00000000);
- iow32(scr, SrcYX, (sp.x<<16)|sp.y);
- iow32(scr, SrcWidth1, dx);
- iow32(scr, DstOffPitch, pitch<<22);
- iow32(scr, DstCntl, ctl);
-
- iow32(scr, DstYX, (dp.x<<16)|dp.y);
- iow32(scr, DstHeightWidth, (dx<<16)|dy);
-
- waitforidle(scr);
-
- return 1;
-}
-
-/*
- * This should work, but doesn't.
- * It messes up the screen timings for some reason.
- */
-static void
-mach64blank(VGAscr *scr, int blank)
-{
- ulong ctl;
-
- ctl = ior32(scr, CrtcGenCtl) & ~(CrtcHsyncDis|CrtcVsyncDis);
- if(blank)
- ctl |= CrtcHsyncDis|CrtcVsyncDis;
- iow32(scr, CrtcGenCtl, ctl);
-}
-
-/*
- * We squirrel away whether the LCD and/or CRT were
- * on when we were called to blank the screen, and
- * restore the old state. If we are called to blank the
- * screen when it is already blank, we don't update the state.
- * Such a call sequence should not happen, though.
- *
- * We could try forcing the chip into power management
- * mode instead, but I'm not sure how that would interact
- * with screen updates going on while the screen is blanked.
- */
-static void
-mach64lcdblank(VGAscr *scr, int blank)
-{
- static int crtlcd;
- ulong x;
-
- if(blank) {
- x = lcdr32(scr, LCD_GenCtrl);
- if(x & 3) {
- crtlcd = x & 3;
- lcdw32(scr, LCD_GenCtrl, x&~3);
- }
- } else {
- if(crtlcd == 0)
- crtlcd = 2; /* lcd only */
- x = lcdr32(scr, LCD_GenCtrl);
- lcdw32(scr, LCD_GenCtrl, x | crtlcd);
- }
-}
-
-static void
-mach64xxdrawinit(VGAscr *scr)
-{
- if(scr->io > 0x2FF){
- initengine(scr);
- scr->fill = mach64hwfill;
- scr->scroll = mach64hwscroll;
- }
-/* scr->blank = mach64blank; */
- switch(scr->id){
- default:
- break;
- case ('L'<<8)|'B': /* 4C42: Rage 3D LTPro */
- case ('L'<<8)|'I': /* 4C49: Rage 3D LTPro */
- case ('L'<<8)|'M': /* 4C4D: Rage Mobility */
- case ('L'<<8)|'P': /* 4C50: Rage 3D LTPro */
- scr->blank = mach64lcdblank;
- hwblank = 1;
- break;
- }
-}
-
-static void
-ovl_configure(VGAscr *scr, Chan *c, char **field)
-{
- int w, h;
- char *format;
-
- w = (int)strtol(field[1], nil, 0);
- h = (int)strtol(field[2], nil, 0);
- format = field[3];
-
- if (c != ovl_chan)
- error(Einuse);
- if (strcmp(format, "YUYV"))
- error(Eunsupportedformat);
-
- ovl_width = w;
- ovl_height = h;
- ovl_fib = w * h * sizeof(ushort);
-
- waitforidle(scr);
- scr->mmio[mmoffset[BusCntl]] |= 0x08000000; /* Enable regblock 1 */
- scr->mmio[mmoffset[OverlayScaleCntl]] =
- SCALE_ZERO_EXTEND|SCALE_RED_TEMP_6500K|
- SCALE_HORZ_BLEND|SCALE_VERT_BLEND;
- scr->mmio[mmoffset[!mach64revb? Buf0Pitch: ScalerBuf0Pitch]] = w;
- scr->mmio[mmoffset[CaptureConfig]] =
- SCALER_FRAME_READ_MODE_FULL|
- SCALER_BUF_MODE_SINGLE|
- SCALER_BUF_NEXT_0;
- scr->mmio[mmoffset[OverlayKeyCntl]] = !mach64revb?
- OVERLAY_MIX_ALWAYS_V|(OVERLAY_EXCLUSIVE_NORMAL << 28):
- 0x011;
-
- if (mach64type->m64_pro) {
- waitforfifo(scr, 6);
-
- /* set the scaler co-efficient registers */
- scr->mmio[mmoffset[ScalerColourCntl]] =
- (0x00) | (0x10 << 8) | (0x10 << 16);
- scr->mmio[mmoffset[ScalerHCoef0]] =
- (0x00) | (0x20 << 8);
- scr->mmio[mmoffset[ScalerHCoef1]] =
- (0x0D) | (0x20 << 8) | (0x06 << 16) | (0x0D << 24);
- scr->mmio[mmoffset[ScalerHCoef2]] =
- (0x0D) | (0x1C << 8) | (0x0A << 16) | (0x0D << 24);
- scr->mmio[mmoffset[ScalerHCoef3]] =
- (0x0C) | (0x1A << 8) | (0x0E << 16) | (0x0C << 24);
- scr->mmio[mmoffset[ScalerHCoef4]] =
- (0x0C) | (0x14 << 8) | (0x14 << 16) | (0x0C << 24);
- }
-
- waitforfifo(scr, 3);
- scr->mmio[mmoffset[VideoFormat]] = SCALE_IN_YVYU422 |
- (!mach64revb? 0xC: 0);
-
- if (mach64overlay == 0)
- mach64overlay = scr->storage + 64 * 64 * sizeof(uchar);
- scr->mmio[mmoffset[!mach64revb? Buf0Offset: ScalerBuf0Offset]] =
- mach64overlay;
-}
-
-static void
-ovl_enable(VGAscr *scr, Chan *c, char **field)
-{
- int x, y, w, h;
- long h_inc, v_inc;
-
- x = (int)strtol(field[1], nil, 0);
- y = (int)strtol(field[2], nil, 0);
- w = (int)strtol(field[3], nil, 0);
- h = (int)strtol(field[4], nil, 0);
-
- if (x < 0 || x + w > physgscreenr.max.x ||
- y < 0 || y + h > physgscreenr.max.y)
- error(Ebadarg);
-
- if (c != ovl_chan)
- error(Einuse);
- if (scr->mmio[mmoffset[CrtcGenCntl]] & 1) { /* double scan enable */
- y *= 2;
- h *= 2;
- }
-
- waitforfifo(scr, 2);
- scr->mmio[mmoffset[OverlayYX]] =
- ((x & 0xFFFF) << 16) | (y & 0xFFFF);
- scr->mmio[mmoffset[OverlayYXEnd]] =
- (((x + w) & 0xFFFF) << 16) | ((y + h) & 0xFFFF);
-
- h_inc = (ovl_width << 12) / (w >> 1); /* ??? */
- v_inc = (ovl_height << 12) / h;
- waitforfifo(scr, 2);
- scr->mmio[mmoffset[OverlayScaleInc]] =
- ((h_inc & 0xFFFF) << 16) | (v_inc & 0xFFFF);
- scr->mmio[mmoffset[ScalerHeightWidth]] =
- ((ovl_width & 0xFFFF) << 16) | (ovl_height & 0xFFFF);
- waitforidle(scr);
- scr->mmio[mmoffset[OverlayScaleCntl]] |=
- (SCALE_ENABLE|OVERLAY_ENABLE);
-}
-
-static void
-ovl_status(VGAscr *scr, Chan *, char **field)
-{
- pprint("%s: %s %.4uX, VT/GT %s, PRO %s, ovlclock %d, rev B %s, refclock %ld\n",
- scr->dev->name, field[0], mach64type->m64_id,
- mach64type->m64_vtgt? "yes": "no",
- mach64type->m64_pro? "yes": "no",
- mach64type->m64_ovlclock,
- mach64revb? "yes": "no",
- mach64refclock);
- pprint("%s: storage @%.8luX, aperture @%8.ulX, ovl buf @%.8ulX\n",
- scr->dev->name, scr->storage, scr->aperture,
- mach64overlay);
-}
-
-static void
-ovl_openctl(VGAscr *, Chan *c, char **)
-{
- if (ovl_chan)
- error(Einuse);
- ovl_chan = c;
-}
-
-static void
-ovl_closectl(VGAscr *scr, Chan *c, char **)
-{
- if (c != ovl_chan) return;
-
- waitforidle(scr);
- scr->mmio[mmoffset[OverlayScaleCntl]] &=
- ~(SCALE_ENABLE|OVERLAY_ENABLE);
- ovl_chan = nil;
- ovl_width = ovl_height = ovl_fib = 0;
-}
-
-enum
-{
- CMclosectl,
- CMconfigure,
- CMenable,
- CMopenctl,
- CMstatus,
-};
-
-static void (*ovl_cmds[])(VGAscr *, Chan *, char **) =
-{
- [CMclosectl] ovl_closectl,
- [CMconfigure] ovl_configure,
- [CMenable] ovl_enable,
- [CMopenctl] ovl_openctl,
- [CMstatus] ovl_status,
-};
-
-static Cmdtab mach64xxcmd[] =
-{
- CMclosectl, "closectl", 1,
- CMconfigure, "configure", 4,
- CMenable, "enable", 5,
- CMopenctl, "openctl", 1,
- CMstatus, "status", 1,
-};
-
-static void
-mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int n)
-{
- Cmdbuf *cb;
- Cmdtab *ct;
-
- if(!mach64type->m64_vtgt)
- error(Enodev);
-
- if(!scr->overlayinit){
- scr->overlayinit = 1;
- init_overlayclock(scr);
- }
- cb = parsecmd(a, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
-
- ct = lookupcmd(cb, mach64xxcmd, nelem(mach64xxcmd));
-
- ovl_cmds[ct->index](scr, c, cb->f);
-
- poperror();
- free(cb);
-}
-
-static int
-mach64xxovlwrite(VGAscr *scr, void *a, int len, vlong offs)
-{
- uchar *src;
- int _len;
-
- if (ovl_chan == nil) return len; /* Acts as a /dev/null */
-
- /* Calculate the destination address */
- _len = len;
- src = (uchar *)a;
- while (len > 0) {
- ulong _offs;
- int nb;
-
- _offs = (ulong)(offs % ovl_fib);
- nb = (_offs + len > ovl_fib)? ovl_fib - _offs: len;
- memmove((uchar *)KADDR(scr->aperture + mach64overlay + _offs),
- src, nb);
- offs += nb;
- src += nb;
- len -= nb;
- }
- return _len;
-}
-
-VGAdev vgamach64xxdev = {
- "mach64xx",
-
- mach64xxenable, /* enable */
- 0, /* disable */
- 0, /* page */
- mach64xxlinear, /* linear */
- mach64xxdrawinit, /* drawinit */
- 0,
- mach64xxovlctl, /* overlay control */
- mach64xxovlwrite, /* write the overlay */
-};
-
-VGAcur vgamach64xxcur = {
- "mach64xxhwgc",
-
- mach64xxcurenable, /* enable */
- mach64xxcurdisable, /* disable */
- mach64xxcurload, /* load */
- mach64xxcurmove, /* move */
-
- 1 /* doespanning */
-};
-
diff --git a/os/pc/vgamga2164w.c b/os/pc/vgamga2164w.c
deleted file mode 100644
index 6332236a..00000000
--- a/os/pc/vgamga2164w.c
+++ /dev/null
@@ -1,289 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-/*
- * Matrox Millennium and Matrox Millennium II.
- * Matrox MGA-2064W, MGA-2164W 3D graphics accelerators.
- * Texas Instruments Tvp3026 RAMDAC.
- */
-
-enum {
- /* pci chip manufacturer */
- MATROX = 0x102B,
-
- /* pci chip device ids */
- MGA2064 = 0x0519,
- MGA2164 = 0x051B,
- MGA2164AGP = 0x051F
-};
-
-static Pcidev*
-mgapcimatch(void)
-{
- Pcidev *p;
-
- p = pcimatch(nil, MATROX, MGA2164AGP);
- if(p == nil) {
- p = pcimatch(nil, MATROX, MGA2164);
- if(p == nil)
- p = pcimatch(nil, MATROX, MGA2064);
- }
- return p;
-}
-
-static ulong
-mga2164wlinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- Pcidev *p;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- if(p = mgapcimatch()){
- aperture = p->mem[p->did==MGA2064? 1 : 0].bar & ~0x0F;
- *size = (p->did==MGA2064? 8 :16)*1024*1024;
- }
- else
- aperture = 0;
-
- if(wasupamem) {
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)) {
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-mga2164wenable(VGAscr* scr)
-{
- Pcidev *p;
- int size, align, immio;
- ulong aperture;
-
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the virtual address of
- * the MMIO registers.
- */
- if(scr->io)
- return;
-
- p = mgapcimatch();
- if(p == nil)
- return;
-
- immio = p->did==MGA2064? 0 : 1;
- scr->io = upamalloc(p->mem[immio].bar & ~0x0F, p->mem[immio].size, 0);
- if(scr->io == 0)
- return;
- addvgaseg("mga2164wmmio", scr->io, p->mem[immio].size);
-
- scr->io = (ulong)KADDR(scr->io);
-
- /* need to map frame buffer here too, so vga can find memory size */
- size = (p->did==MGA2064? 8 :16)*1024*1024;
- align = 0;
- aperture = mga2164wlinear(scr, &size, &align);
- if(aperture) {
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("mga2164wscreen", aperture, size);
- }
-}
-
-enum {
- Index = 0x00, /* Index */
- Data = 0x0A, /* Data */
-
- CaddrW = 0x04, /* Colour Write Address */
- Cdata = 0x05, /* Colour Data */
-
- Cctl = 0x09, /* Direct Cursor Control */
- Cram = 0x0B, /* Cursor Ram Data */
- Cxlsb = 0x0C, /* Cursor X LSB */
- Cxmsb = 0x0D, /* Cursor X MSB */
- Cylsb = 0x0E, /* Cursor Y LSB */
- Cymsb = 0x0F, /* Cursor Y MSB */
-
- Icctl = 0x06, /* Indirect Cursor Control */
-};
-
-static void
-tvp3026disable(VGAscr* scr)
-{
- uchar *tvp3026;
-
- if(scr->io == 0)
- return;
- tvp3026 = KADDR(scr->io+0x3C00);
-
- /*
- * Make sure cursor is off
- * and direct control enabled.
- */
- *(tvp3026+Index) = Icctl;
- *(tvp3026+Data) = 0x90;
- *(tvp3026+Cctl) = 0x00;
-}
-
-static void
-tvp3026load(VGAscr* scr, Cursor* curs)
-{
- int x, y;
- uchar *tvp3026;
-
- if(scr->io == 0)
- return;
- tvp3026 = KADDR(scr->io+0x3C00);
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults.
- * Write to the indirect control register to make sure
- * direct register is enabled and upper 2 bits of cursor
- * RAM address are 0.
- * Put 0 in index register for lower 8 bits of cursor RAM address.
- */
- tvp3026disable(scr);
- *(tvp3026+Index) = 0;
-
- /*
- * Initialise the 64x64 cursor RAM array. There are 2 planes,
- * p0 and p1. Data is written 8 pixels per byte, with p0 in the
- * first 512 bytes of the array and p1 in the second.
- * The cursor is set in 3-colour mode which gives the following
- * truth table:
- * p1 p0 colour
- * 0 0 transparent
- * 0 1 cursor colour 0
- * 1 0 cursor colour 1
- * 1 1 cursor colour 2
- * Put the cursor into the top-left of the 64x64 array.
- * The 0,0 cursor point is bottom-right, so positioning will
- * have to take that into account.
- */
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16)
- *(tvp3026+Cram) = curs->clr[x+y*2];
- else
- *(tvp3026+Cram) = 0x00;
- }
- }
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16)
- *(tvp3026+Cram) = curs->set[x+y*2];
- else
- *(tvp3026+Cram) = 0x00;
- }
- }
-
- /*
- * Initialise the cursor hotpoint
- * and enable the cursor in 3-colour mode.
- */
- scr->offset.x = 64+curs->offset.x;
- scr->offset.y = 64+curs->offset.y;
- *(tvp3026+Cctl) = 0x01;
-}
-
-static int
-tvp3026move(VGAscr* scr, Point p)
-{
- int x, y;
- uchar *tvp3026;
-
- if(scr->io == 0)
- return 1;
- tvp3026 = KADDR(scr->io+0x3C00);
-
- x = p.x+scr->offset.x;
- y = p.y+scr->offset.y;
-
- *(tvp3026+Cxlsb) = x & 0xFF;
- *(tvp3026+Cxmsb) = (x>>8) & 0x0F;
- *(tvp3026+Cylsb) = y & 0xFF;
- *(tvp3026+Cymsb) = (y>>8) & 0x0F;
-
- return 0;
-}
-
-static void
-tvp3026enable(VGAscr* scr)
-{
- int i;
- uchar *tvp3026;
-
- if(scr->io == 0)
- return;
- tvp3026 = KADDR(scr->io+0x3C00);
-
- tvp3026disable(scr);
-
- /*
- * Overscan colour,
- * cursor colour 1 (white),
- * cursor colour 2, 3 (black).
- */
- *(tvp3026+CaddrW) = 0x00;
- for(i = 0; i < 6; i++)
- *(tvp3026+Cdata) = Pwhite;
- for(i = 0; i < 6; i++)
- *(tvp3026+Cdata) = Pblack;
-
- /*
- * Load, locate and enable the
- * 64x64 cursor in 3-colour mode.
- */
- tvp3026load(scr, &arrow);
- tvp3026move(scr, ZP);
- *(tvp3026+Cctl) = 0x01;
-}
-
-VGAdev vgamga2164wdev = {
- "mga2164w",
-
- mga2164wenable, /* enable */
- 0, /* disable */
- 0, /* page */
- mga2164wlinear, /* linear */
-};
-
-VGAcur vgamga2164wcur = {
- "mga2164whwgc",
-
- tvp3026enable,
- tvp3026disable,
- tvp3026load,
- tvp3026move,
-};
diff --git a/os/pc/vgamga4xx.c b/os/pc/vgamga4xx.c
deleted file mode 100644
index 7ddeebf1..00000000
--- a/os/pc/vgamga4xx.c
+++ /dev/null
@@ -1,603 +0,0 @@
-
-/*
- * Matrox G200, G400 and G450.
- * see /sys/src/cmd/aux/vga/mga4xx.c
- */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum {
- MATROX = 0x102B,
- MGA4xx = 0x0525,
- MGA200 = 0x0521,
-
- Kilo = 1024,
- Meg = 1024*1024,
-
- FCOL = 0x1c24,
- FXRIGHT = 0x1cac,
- FXLEFT = 0x1ca8,
- YDST = 0x1c90,
- YLEN = 0x1c5c,
- DWGCTL = 0x1c00,
- DWG_TRAP = 0x04,
- DWG_BITBLT = 0x08,
- DWG_ILOAD = 0x09,
- DWG_LINEAR = 0x0080,
- DWG_SOLID = 0x0800,
- DWG_ARZERO = 0x1000,
- DWG_SGNZERO = 0x2000,
- DWG_SHIFTZERO = 0x4000,
- DWG_REPLACE = 0x000C0000,
- DWG_REPLACE2 = (DWG_REPLACE | 0x40),
- DWG_XOR = 0x00060010,
- DWG_BFCOL = 0x04000000,
- DWG_BMONOWF = 0x08000000,
- DWG_TRANSC = 0x40000000,
- SRCORG = 0x2cb4,
- PITCH = 0x1c8c,
- DSTORG = 0x2cb8,
- PLNWRT = 0x1c1c,
- ZORG = 0x1c0c,
- MACCESS = 0x1c04,
- STATUS = 0x1e14,
- FXBNDRY = 0x1C84,
- CXBNDRY = 0x1C80,
- YTOP = 0x1C98,
- YBOT = 0x1C9C,
- YDSTLEN = 0x1C88,
- AR0 = 0x1C60,
- AR1 = 0x1C64,
- AR2 = 0x1C68,
- AR3 = 0x1C6C,
- AR4 = 0x1C70,
- AR5 = 0x1C74,
- SGN = 0x1C58,
- SGN_SCANLEFT = 1,
- SGN_SCANRIGHT = 0,
- SGN_SDY_POSITIVE = 0,
- SGN_SDY_NEGATIVE = 4,
-
- GO = 0x0100,
- FIFOSTATUS = 0x1E10,
- CACHEFLUSH = 0x1FFF,
-
- CRTCEXTIDX = 0x1FDE, /* CRTC Extension Index */
- CRTCEXTDATA = 0x1FDF, /* CRTC Extension Data */
-
- FILL_OPERAND = 0x800c7804,
-};
-
-static Pcidev*
-mgapcimatch(void)
-{
- Pcidev* p;
-
- p = pcimatch(nil, MATROX, MGA4xx);
- if (p == nil)
- p = pcimatch(nil, MATROX, MGA200);
- return p;
-}
-
-static ulong
-mga4xxlinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- Pcidev * p;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- if(p = mgapcimatch()){
- aperture = p->mem[0].bar & ~0x0F;
- if(p->did == MGA4xx)
- *size = 32*Meg;
- else
- *size = 8*Meg;
- }
- else
- aperture = 0;
-
- if(wasupamem) {
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)) {
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-mgawrite8(VGAscr* scr, int index, uchar val)
-{
- ((uchar*)scr->io)[index] = val;
-}
-
-static uchar
-mgaread8(VGAscr* scr, int index)
-{
- return ((uchar*)scr->io)[index];
-}
-
-static uchar
-crtcextset(VGAscr* scr, int index, uchar set, uchar clr)
-{
- uchar tmp;
-
- mgawrite8(scr, CRTCEXTIDX, index);
- tmp = mgaread8(scr, CRTCEXTDATA);
- mgawrite8(scr, CRTCEXTIDX, index);
- mgawrite8(scr, CRTCEXTDATA, (tmp & ~clr) | set);
-
- return tmp;
-}
-
-static void
-mga4xxenable(VGAscr* scr)
-{
- Pcidev * pci;
- int size, align;
- ulong aperture;
- int i, n, k;
- uchar * p;
- uchar x[16];
- uchar crtcext3;
-
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the virtual address of
- * the MMIO registers.
- */
- if(scr->io)
- return;
-
- pci = mgapcimatch();
- if(pci == nil)
- return;
-
- scr->io = upamalloc(pci->mem[1].bar & ~0x0F, 16*1024, 0);
- if(scr->io == 0)
- return;
-
- addvgaseg("mga4xxmmio", scr->io, pci->mem[1].size);
-
- scr->io = (ulong)KADDR(scr->io);
-
- /* need to map frame buffer here too, so vga can find memory size */
- size = 8*Meg;
- align = 0;
- aperture = mga4xxlinear(scr, &size, &align);
- if(aperture) {
- scr->aperture = aperture;
- addvgaseg("mga4xxscreen", aperture, size);
-
- /* Find out how much memory is here, some multiple of 2 Meg */
-
- /* First Set MGA Mode ... */
- crtcext3 = crtcextset(scr, 3, 0x80, 0x00);
-
- p = (uchar*)aperture;
- n = (size / Meg) / 2;
- for (i = 0; i < n; i++) {
- k = (2*i+1)*Meg;
- p[k] = 0;
- p[k] = i+1;
- *((uchar*)(scr->io + CACHEFLUSH)) = 0;
- x[i] = p[k];
- }
- for(i = 1; i < n; i++)
- if(x[i] != i+1)
- break;
- scr->apsize = 2*i*Meg;
-
- crtcextset(scr, 3, crtcext3, 0xff);
- }
-}
-
-enum {
- Index = 0x00, /* Index */
- Data = 0x0A, /* Data */
-
- Cxlsb = 0x0C, /* Cursor X LSB */
- Cxmsb = 0x0D, /* Cursor X MSB */
- Cylsb = 0x0E, /* Cursor Y LSB */
- Cymsb = 0x0F, /* Cursor Y MSB */
-
- Icuradrl = 0x04, /* Cursor Base Address Low */
- Icuradrh = 0x05, /* Cursor Base Address High */
- Icctl = 0x06, /* Indirect Cursor Control */
-};
-
-static void
-dac4xxdisable(VGAscr* scr)
-{
- uchar * dac4xx;
-
- if(scr->io == 0)
- return;
-
- dac4xx = KADDR(scr->io+0x3C00);
-
- *(dac4xx+Index) = Icctl;
- *(dac4xx+Data) = 0x00;
-}
-
-static void
-dac4xxload(VGAscr* scr, Cursor* curs)
-{
- int y;
- uchar * p;
- uchar * dac4xx;
-
- if(scr->io == 0)
- return;
-
- dac4xx = KADDR(scr->io+0x3C00);
-
- dac4xxdisable(scr);
-
- p = KADDR(scr->storage);
- for(y = 0; y < 64; y++){
- *p++ = 0; *p++ = 0; *p++ = 0;
- *p++ = 0; *p++ = 0; *p++ = 0;
- if(y <16){
- *p++ = curs->set[1+y*2]|curs->clr[1+2*y];
- *p++ = curs->set[y*2]|curs->clr[2*y];
- } else{
- *p++ = 0; *p++ = 0;
- }
-
- *p++ = 0; *p++ = 0; *p++ = 0;
- *p++ = 0; *p++ = 0; *p++ = 0;
- if(y <16){
- *p++ = curs->set[1+y*2];
- *p++ = curs->set[y*2];
- } else{
- *p++ = 0; *p++ = 0;
- }
- }
- scr->offset.x = 64 + curs->offset.x;
- scr->offset.y = 64 + curs->offset.y;
-
- *(dac4xx+Index) = Icctl;
- *(dac4xx+Data) = 0x03;
-}
-
-static int
-dac4xxmove(VGAscr* scr, Point p)
-{
- int x, y;
- uchar * dac4xx;
-
- if(scr->io == 0)
- return 1;
-
- dac4xx = KADDR(scr->io + 0x3C00);
-
- x = p.x + scr->offset.x;
- y = p.y + scr->offset.y;
-
- *(dac4xx+Cxlsb) = x & 0xFF;
- *(dac4xx+Cxmsb) = (x>>8) & 0x0F;
-
- *(dac4xx+Cylsb) = y & 0xFF;
- *(dac4xx+Cymsb) = (y>>8) & 0x0F;
-
- return 0;
-}
-
-static void
-dac4xxenable(VGAscr* scr)
-{
- uchar * dac4xx;
- ulong storage;
-
- if(scr->io == 0)
- return;
- dac4xx = KADDR(scr->io+0x3C00);
-
- dac4xxdisable(scr);
-
- storage = (scr->apsize - 4096) & ~0x3ff;
-
- *(dac4xx+Index) = Icuradrl;
- *(dac4xx+Data) = 0xff & (storage >> 10);
- *(dac4xx+Index) = Icuradrh;
- *(dac4xx+Data) = 0xff & (storage >> 18);
-
- scr->storage = (ulong) KADDR((ulong)scr->aperture + (ulong)storage);
-
- /* Show X11-Like Cursor */
- *(dac4xx+Index) = Icctl;
- *(dac4xx+Data) = 0x03;
-
- /* Cursor Color 0 : White */
- *(dac4xx+Index) = 0x08;
- *(dac4xx+Data) = 0xff;
- *(dac4xx+Index) = 0x09;
- *(dac4xx+Data) = 0xff;
- *(dac4xx+Index) = 0x0a;
- *(dac4xx+Data) = 0xff;
-
- /* Cursor Color 1 : Black */
- *(dac4xx+Index) = 0x0c;
- *(dac4xx+Data) = 0x00;
- *(dac4xx+Index) = 0x0d;
- *(dac4xx+Data) = 0x00;
- *(dac4xx+Index) = 0x0e;
- *(dac4xx+Data) = 0x00;
-
- /* Cursor Color 2 : Red */
- *(dac4xx+Index) = 0x10;
- *(dac4xx+Data) = 0xff;
- *(dac4xx+Index) = 0x11;
- *(dac4xx+Data) = 0x00;
- *(dac4xx+Index) = 0x12;
- *(dac4xx+Data) = 0x00;
-
- /*
- * Load, locate and enable the
- * 64x64 cursor in X11 mode.
- */
- dac4xxload(scr, &arrow);
- dac4xxmove(scr, ZP);
-}
-
-static void
-mga4xxblank(VGAscr* scr, int blank)
-{
- char * cp;
- uchar * mga;
- uchar seq1, crtcext1;
-
- /* blank = 0 -> turn screen on */
- /* blank = 1 -> turn screen off */
-
- if(scr->io == 0)
- return;
- mga = KADDR(scr->io);
-
- if (blank == 0) {
- seq1 = 0x00;
- crtcext1 = 0x00;
- } else {
- seq1 = 0x20;
- crtcext1 = 0x10; /* Default value ... : standby */
- cp = getconf("*dpms");
- if (cp) {
- if (cistrcmp(cp, "standby") == 0) {
- crtcext1 = 0x10;
- } else if (cistrcmp(cp, "suspend") == 0) {
- crtcext1 = 0x20;
- } else if (cistrcmp(cp, "off") == 0) {
- crtcext1 = 0x30;
- }
- }
- }
-
- *(mga + 0x1fc4) = 1;
- seq1 |= *(mga + 0x1fc5) & ~0x20;
- *(mga + 0x1fc5) = seq1;
-
- *(mga + 0x1fde) = 1;
- crtcext1 |= *(mga + 0x1fdf) & ~0x30;
- *(mga + 0x1fdf) = crtcext1;
-}
-
-static void
-mgawrite32(uchar * mga, ulong reg, ulong val)
-{
- ulong * l;
-
- l = (ulong *)(&mga[reg]);
- l[0] = val;
-}
-
-static ulong
-mgaread32(uchar * mga, ulong reg)
-{
- return *((ulong *)(&mga[reg]));
-}
-
-static int
-mga4xxfill(VGAscr* scr, Rectangle r, ulong color)
-{
- uchar * mga;
-
- /* Constant Shaded Trapezoids / Rectangle Fills */
- if(scr->io == 0)
- return 0;
- mga = KADDR(scr->io);
-
- mgawrite32(mga, DWGCTL, 0);
- mgawrite32(mga, FCOL, color);
- mgawrite32(mga, FXRIGHT, r.max.x);
- mgawrite32(mga, FXLEFT, r.min.x);
- mgawrite32(mga, YDST, r.min.y);
- mgawrite32(mga, YLEN, Dy(r));
- mgawrite32(mga, DWGCTL + GO, FILL_OPERAND);
-
- while (mgaread32(mga, STATUS) & 0x00010000)
- ;
- return 1;
-}
-
-#define mga_fifo(n) do {} while ((mgaread32(mga, FIFOSTATUS) & 0xFF) < (n))
-
-static int
-mga4xxscroll(VGAscr* scr, Rectangle r_dst, Rectangle r_src)
-{
- uchar * mga;
- ulong pitch, y;
- ulong width, height, start, end, scandir;
- int ydir;
-
- /* Two-operand Bitblts */
- if(scr->io == 0)
- return 0;
-
- mga = KADDR(scr->io);
-
- pitch = Dx(scr->gscreen->r);
-
- mgawrite32(mga, DWGCTL, 0);
-
- scandir = 0;
-
- height = abs(Dy(r_src));
- width = abs(Dx(r_src));
-
- assert(height == abs(Dy(r_dst)));
- assert(width == abs(Dx(r_dst)));
-
- if ((r_src.min.y == r_dst.min.y) && (r_src.min.x == r_dst.min.x))
- {
- if (0)
- print("move x,y to x,y !\n");
- return 1;
- }
-
- ydir = 1;
- if (r_dst.min.y > r_src.min.y)
- {
- if (0)
- print("ydir = -1\n");
- ydir = -1;
- scandir |= 4; // Blit UP
- }
-
- if (r_dst.min.x > r_src.min.x)
- {
- if (0)
- print("xdir = -1\n");
- scandir |= 1; // Blit Left
- }
-
- mga_fifo(4);
- if (scandir)
- {
- mgawrite32(mga, DWGCTL, DWG_BITBLT | DWG_SHIFTZERO |
- DWG_SGNZERO | DWG_BFCOL | DWG_REPLACE);
- mgawrite32(mga, SGN, scandir);
- } else
- {
- mgawrite32(mga, DWGCTL, DWG_BITBLT | DWG_SHIFTZERO |
- DWG_BFCOL | DWG_REPLACE);
- }
- mgawrite32(mga, AR5, ydir * pitch);
-
- width--;
- start = end = r_src.min.x + (r_src.min.y * pitch);
- if ((scandir & 1) == 1)
- {
- start += width;
- } else
- {
- end += width;
- }
-
- y = r_dst.min.y;
- if ((scandir & 4) == 4)
- {
- start += (height - 1) * pitch;
- end += (height - 1) * pitch;
- y += (height - 1);
- }
-
- mga_fifo(4);
- mgawrite32(mga, AR0, end);
- mgawrite32(mga, AR3, start);
- mgawrite32(mga, FXBNDRY, ((r_dst.min.x+width)<<16) | r_dst.min.x);
- mgawrite32(mga, YDSTLEN + GO, (y << 16) | height);
-
- if (1)
- {
- while (mgaread32(mga, STATUS) & 0x00010000)
- ;
- }
-
- return 1;
-}
-
-static void
-mga4xxdrawinit(VGAscr* scr)
-{
- uchar * mga;
- Pcidev* p;
-
- p = pcimatch(nil, MATROX, MGA4xx);
- if (p == nil)
- return ;
-
- if(scr->io == 0)
- return;
- mga = KADDR(scr->io);
-
- mgawrite32(mga, SRCORG, 0);
- mgawrite32(mga, DSTORG, 0);
- mgawrite32(mga, ZORG, 0);
- mgawrite32(mga, PLNWRT, ~0);
- mgawrite32(mga, FCOL, 0xffff0000);
- mgawrite32(mga, CXBNDRY, 0xFFFF0000);
- mgawrite32(mga, YTOP, 0);
- mgawrite32(mga, YBOT, 0x01FFFFFF);
- mgawrite32(mga, PITCH, Dx(scr->gscreen->r) & ((1 << 13) - 1));
- switch(scr->gscreen->depth) {
- case 8:
- mgawrite32(mga, MACCESS, 0);
- break;
- case 32:
- mgawrite32(mga, MACCESS, 2);
- break;
- default:
- return; /* depth not supported ! */
- }
- scr->fill = mga4xxfill;
- scr->scroll = mga4xxscroll;
- scr->blank = mga4xxblank;
-}
-
-VGAdev vgamga4xxdev = {
- "mga4xx",
-
- mga4xxenable, /* enable */
- 0, /* disable */
- 0, /* page */
- mga4xxlinear, /* linear */
- mga4xxdrawinit,
-};
-
-VGAcur vgamga4xxcur = {
- "mga4xxhwgc",
- dac4xxenable,
- dac4xxdisable,
- dac4xxload,
- dac4xxmove,
-};
diff --git a/os/pc/vganeomagic.c b/os/pc/vganeomagic.c
deleted file mode 100644
index ba25a581..00000000
--- a/os/pc/vganeomagic.c
+++ /dev/null
@@ -1,541 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-typedef struct CursorNM CursorNM;
-struct CursorNM {
- int enable;
- int x;
- int y;
- int colour1;
- int colour2;
- int addr;
-};
-
-static ulong
-neomagiclinear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- Pcidev *p;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- aperture = 0;
- if(p = pcimatch(nil, 0x10C8, 0)){
- switch(p->did){
- case 0x0004: /* MagicGraph 128XD */
- case 0x0005: /* MagicMedia 256AV */
- case 0x0006: /* MagicMedia 256ZX */
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
- break;
- default:
- break;
- }
- }
-
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-neomagicenable(VGAscr* scr)
-{
- Pcidev *p;
- int align, curoff, size, vmsize;
- ulong aperture;
-
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the physical address of the cursor registers
- * in the MMIO space. This may need to change for older chips
- * which have the MMIO space offset in the framebuffer region.
- */
- if(scr->io)
- return;
- if(p = pcimatch(nil, 0x10C8, 0)){
- switch(p->did){
- case 0x0004: /* MagicGraph 128XD */
- curoff = 0x100;
- vmsize = 2048*1024;
- break;
- case 0x0005: /* MagicMedia 256AV */
- curoff = 0x1000;
- vmsize = 2560*1024;
- break;
- case 0x0006: /* MagicMedia 256ZX */
- curoff = 0x1000;
- vmsize = 4096*1024;
- break;
- default:
- return;
- }
- }
- else
- return;
- scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
- if(scr->io == 0)
- return;
- addvgaseg("neomagicmmio", scr->io, p->mem[1].size);
- scr->mmio = KADDR(scr->io);
-
- /*
- * Find a place for the cursor data in display memory.
- * 2 cursor images might be needed, 1KB each so use the
- * last 2KB of the framebuffer.
- */
- scr->storage = vmsize-2*1024;
- scr->io += curoff;
-
- size = p->mem[0].size;
- align = 0;
- aperture = neomagiclinear(scr, &size, &align);
- if(aperture) {
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("neomagicscreen", aperture, size);
- }
-}
-
-static void
-neomagiccurdisable(VGAscr* scr)
-{
- CursorNM *cursornm;
-
- if(scr->io == 0)
- return;
- cursornm = KADDR(scr->io);
- cursornm->enable = 0;
-}
-
-static void
-neomagicinitcursor(VGAscr* scr, int xo, int yo, int index)
-{
- uchar *p;
- uint p0, p1;
- int x, y;
-
- p = KADDR(scr->aperture);
- p += scr->storage + index*1024;
-
- for(y = yo; y < 16; y++){
- p0 = scr->set[2*y];
- p1 = scr->set[2*y+1];
- if(xo){
- p0 = (p0<<xo)|(p1>>(8-xo));
- p1 <<= xo;
- }
- *p++ = p0;
- *p++ = p1;
-
- for(x = 16; x < 64; x += 8)
- *p++ = 0x00;
-
- p0 = scr->clr[2*y]|scr->set[2*y];
- p1 = scr->clr[2*y+1]|scr->set[2*y+1];
- if(xo){
- p0 = (p0<<xo)|(p1>>(8-xo));
- p1 <<= xo;
- }
- *p++ = p0;
- *p++ = p1;
-
- for(x = 16; x < 64; x += 8)
- *p++ = 0x00;
- }
- while(y < 64+yo){
- for(x = 0; x < 64; x += 8){
- *p++ = 0x00;
- *p++ = 0x00;
- }
- y++;
- }
-}
-
-static void
-neomagiccurload(VGAscr* scr, Cursor* curs)
-{
- CursorNM *cursornm;
-
- if(scr->io == 0)
- return;
- cursornm = KADDR(scr->io);
-
- cursornm->enable = 0;
- memmove(&scr->Cursor, curs, sizeof(Cursor));
- neomagicinitcursor(scr, 0, 0, 0);
- cursornm->enable = 1;
-}
-
-static int
-neomagiccurmove(VGAscr* scr, Point p)
-{
- CursorNM *cursornm;
- int addr, index, x, xo, y, yo;
-
- if(scr->io == 0)
- return 1;
- cursornm = KADDR(scr->io);
-
- index = 0;
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- if(xo || yo){
- index = 1;
- neomagicinitcursor(scr, xo, yo, index);
- }
- addr = ((scr->storage+(1024*index))>>10) & 0xFFF;
- addr = ((addr & 0x00F)<<8)|((addr>>4) & 0xFF);
- if(cursornm->addr != addr)
- cursornm->addr = addr;
-
- cursornm->x = x;
- cursornm->y = y;
-
- return 0;
-}
-
-static void
-neomagiccurenable(VGAscr* scr)
-{
- CursorNM *cursornm;
-
- neomagicenable(scr);
- if(scr->io == 0)
- return;
- cursornm = KADDR(scr->io);
- cursornm->enable = 0;
-
- /*
- * Cursor colours.
- */
- cursornm->colour1 = (Pblack<<16)|(Pblack<<8)|Pblack;
- cursornm->colour2 = (Pwhite<<16)|(Pwhite<<8)|Pwhite;
-
- /*
- * Load, locate and enable the 64x64 cursor.
- */
- neomagiccurload(scr, &arrow);
- neomagiccurmove(scr, ZP);
- cursornm->enable = 1;
-}
-
-static int neomagicbltflags;
-
-/* registers */
-enum {
- BltStat = 0,
- BltCntl = 1,
- XPColor = 2,
- FGColor = 3,
- BGColor = 4,
- Pitch = 5,
- ClipLT = 6,
- ClipRB = 7,
- SrcBitOff = 8,
- SrcStartOff = 9,
-
- DstStartOff = 11,
- XYExt = 12,
-
- PageCntl = 20,
- PageBase,
- PostBase,
- PostPtr,
- DataPtr,
-};
-
-/* flags */
-enum {
- NEO_BS0_BLT_BUSY = 0x00000001,
- NEO_BS0_FIFO_AVAIL = 0x00000002,
- NEO_BS0_FIFO_PEND = 0x00000004,
-
- NEO_BC0_DST_Y_DEC = 0x00000001,
- NEO_BC0_X_DEC = 0x00000002,
- NEO_BC0_SRC_TRANS = 0x00000004,
- NEO_BC0_SRC_IS_FG = 0x00000008,
- NEO_BC0_SRC_Y_DEC = 0x00000010,
- NEO_BC0_FILL_PAT = 0x00000020,
- NEO_BC0_SRC_MONO = 0x00000040,
- NEO_BC0_SYS_TO_VID = 0x00000080,
-
- NEO_BC1_DEPTH8 = 0x00000100,
- NEO_BC1_DEPTH16 = 0x00000200,
- NEO_BC1_DEPTH24 = 0x00000300,
- NEO_BC1_X_320 = 0x00000400,
- NEO_BC1_X_640 = 0x00000800,
- NEO_BC1_X_800 = 0x00000c00,
- NEO_BC1_X_1024 = 0x00001000,
- NEO_BC1_X_1152 = 0x00001400,
- NEO_BC1_X_1280 = 0x00001800,
- NEO_BC1_X_1600 = 0x00001c00,
- NEO_BC1_DST_TRANS = 0x00002000,
- NEO_BC1_MSTR_BLT = 0x00004000,
- NEO_BC1_FILTER_Z = 0x00008000,
-
- NEO_BC2_WR_TR_DST = 0x00800000,
-
- NEO_BC3_SRC_XY_ADDR = 0x01000000,
- NEO_BC3_DST_XY_ADDR = 0x02000000,
- NEO_BC3_CLIP_ON = 0x04000000,
- NEO_BC3_FIFO_EN = 0x08000000,
- NEO_BC3_BLT_ON_ADDR = 0x10000000,
- NEO_BC3_SKIP_MAPPING = 0x80000000,
-
- NEO_MODE1_DEPTH8 = 0x0100,
- NEO_MODE1_DEPTH16 = 0x0200,
- NEO_MODE1_DEPTH24 = 0x0300,
- NEO_MODE1_X_320 = 0x0400,
- NEO_MODE1_X_640 = 0x0800,
- NEO_MODE1_X_800 = 0x0c00,
- NEO_MODE1_X_1024 = 0x1000,
- NEO_MODE1_X_1152 = 0x1400,
- NEO_MODE1_X_1280 = 0x1800,
- NEO_MODE1_X_1600 = 0x1c00,
- NEO_MODE1_BLT_ON_ADDR = 0x2000,
-};
-
-/* Raster Operations */
-enum {
- GXclear = 0x000000, /* 0x0000 */
- GXand = 0x080000, /* 0x1000 */
- GXandReverse = 0x040000, /* 0x0100 */
- GXcopy = 0x0c0000, /* 0x1100 */
- GXandInvert = 0x020000, /* 0x0010 */
- GXnoop = 0x0a0000, /* 0x1010 */
- GXxor = 0x060000, /* 0x0110 */
- GXor = 0x0e0000, /* 0x1110 */
- GXnor = 0x010000, /* 0x0001 */
- GXequiv = 0x090000, /* 0x1001 */
- GXinvert = 0x050000, /* 0x0101 */
- GXorReverse = 0x0d0000, /* 0x1101 */
- GXcopyInvert = 0x030000, /* 0x0011 */
- GXorInverted = 0x0b0000, /* 0x1011 */
- GXnand = 0x070000, /* 0x0111 */
- GXset = 0x0f0000, /* 0x1111 */
-};
-
-static void
-waitforidle(VGAscr *scr)
-{
- ulong *mmio;
- long x;
-
- mmio = scr->mmio;
- x = 0;
- while((mmio[BltStat] & NEO_BS0_BLT_BUSY) && x++ < 1000000)
- ;
- //if(x >= 1000000)
- // iprint("idle stat %lud scrmmio %.8lux scr %p pc %luX\n", mmio[BltStat], scr->mmio, scr, getcallerpc(&scr));
-}
-
-static void
-waitforfifo(VGAscr *scr, int entries)
-{
- ulong *mmio;
- long x;
-
- mmio = scr->mmio;
- x = 0;
- while(((mmio[BltStat]>>8) < entries) && x++ < 1000000)
- ;
- //if(x >= 1000000)
- // iprint("fifo stat %d scrmmio %.8lux scr %p pc %luX\n", mmio[BltStat]>>8, scr->mmio, scr, getcallerpc(&scr));
- /* DirectFB says the above doesn't work. if so... */
- /* waitforidle(scr); */
-}
-
-static int
-neomagichwfill(VGAscr *scr, Rectangle r, ulong sval)
-{
- ulong *mmio;
-
- mmio = scr->mmio;
-
- waitforfifo(scr, 1);
- mmio[FGColor] = sval;
- waitforfifo(scr, 3);
- mmio[BltCntl] = neomagicbltflags
- | NEO_BC3_FIFO_EN
- | NEO_BC0_SRC_IS_FG
- | NEO_BC3_SKIP_MAPPING
- | GXcopy;
- mmio[DstStartOff] = scr->aperture
- + r.min.y*scr->gscreen->width*BY2WD
- + r.min.x*scr->gscreen->depth/BI2BY;
- mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
- waitforidle(scr);
- return 1;
-}
-
-static int
-neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
-{
- ulong *mmio;
- int pitch, pixel;
-
- mmio = scr->mmio;
-
- pitch = scr->gscreen->width*BY2WD;
- pixel = scr->gscreen->depth/BI2BY;
-
- waitforfifo(scr, 4);
- if (r.min.y < sr.min.y || (r.min.y == sr.min.y && r.min.x < sr.min.x)) {
- /* start from upper-left */
- mmio[BltCntl] = neomagicbltflags
- | NEO_BC3_FIFO_EN
- | NEO_BC3_SKIP_MAPPING
- | GXcopy;
- mmio[SrcStartOff] = scr->aperture
- + sr.min.y*pitch + sr.min.x*pixel;
- mmio[DstStartOff] = scr->aperture
- + r.min.y*pitch + r.min.x*pixel;
- } else {
- /* start from lower-right */
- mmio[BltCntl] = neomagicbltflags
- | NEO_BC0_X_DEC
- | NEO_BC0_DST_Y_DEC
- | NEO_BC0_SRC_Y_DEC
- | NEO_BC3_FIFO_EN
- | NEO_BC3_SKIP_MAPPING
- | GXcopy;
- mmio[SrcStartOff] = scr->aperture
- + (sr.max.y-1)*pitch + (sr.max.x-1)*pixel;
- mmio[DstStartOff] = scr->aperture
- + (r.max.y-1)*pitch + (r.max.x-1)*pixel;
- }
- mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
- waitforidle(scr);
- return 1;
-}
-
-static void
-neomagicdrawinit(VGAscr *scr)
-{
- ulong *mmio;
- uint bltmode, pitch;
-
- mmio = scr->mmio;
-
- pitch = scr->gscreen->width*BY2WD;
-
- neomagicbltflags = bltmode = 0;
-
- switch(scr->gscreen->depth) {
- case 8:
- bltmode |= NEO_MODE1_DEPTH8;
- neomagicbltflags |= NEO_BC1_DEPTH8;
- break;
- case 16:
- bltmode |= NEO_MODE1_DEPTH16;
- neomagicbltflags |= NEO_BC1_DEPTH16;
- break;
- case 24: /* I can't get it to work, and XFree86 doesn't either. */
- default: /* give up */
- return;
- }
-
- switch(Dx(scr->gscreen->r)) {
- case 320:
- bltmode |= NEO_MODE1_X_320;
- neomagicbltflags |= NEO_BC1_X_320;
- break;
- case 640:
- bltmode |= NEO_MODE1_X_640;
- neomagicbltflags |= NEO_BC1_X_640;
- break;
- case 800:
- bltmode |= NEO_MODE1_X_800;
- neomagicbltflags |= NEO_BC1_X_800;
- break;
- case 1024:
- bltmode |= NEO_MODE1_X_1024;
- neomagicbltflags |= NEO_BC1_X_1024;
- break;
- case 1152:
- bltmode |= NEO_MODE1_X_1152;
- neomagicbltflags |= NEO_BC1_X_1152;
- break;
- case 1280:
- bltmode |= NEO_MODE1_X_1280;
- neomagicbltflags |= NEO_BC1_X_1280;
- break;
- case 1600:
- bltmode |= NEO_MODE1_X_1600;
- neomagicbltflags |= NEO_BC1_X_1600;
- break;
- default:
- /* don't worry about it */
- break;
- }
-
- waitforidle(scr);
- mmio[BltStat] = bltmode << 16;
- mmio[Pitch] = (pitch << 16) | (pitch & 0xffff);
-
- scr->fill = neomagichwfill;
- scr->scroll = neomagichwscroll;
-}
-
-VGAdev vganeomagicdev = {
- "neomagic",
-
- neomagicenable,
- nil,
- nil,
- neomagiclinear,
- neomagicdrawinit,
-};
-
-VGAcur vganeomagiccur = {
- "neomagichwgc",
-
- neomagiccurenable,
- neomagiccurdisable,
- neomagiccurload,
- neomagiccurmove,
-};
-
diff --git a/os/pc/vganvidia.c b/os/pc/vganvidia.c
deleted file mode 100644
index e057ef1f..00000000
--- a/os/pc/vganvidia.c
+++ /dev/null
@@ -1,373 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum {
- Pramin = 0x00710000,
- Pramdac = 0x00680000,
- Fifo = 0x00800000,
- Pgraph = 0x00400000
-};
-
-enum {
- hwCurPos = Pramdac + 0x0300,
- hwCurImage = Pramin + (0x00010000 - 0x0800),
-};
-
-/* Nvidia is good about backwards compatibility -- any did >= 0x20 is fine */
-static Pcidev*
-nvidiapci(void)
-{
- Pcidev *p;
-
- p = nil;
- while((p = pcimatch(p, 0x10DE, 0)) != nil){
- if(p->did >= 0x20 && p->ccrb == 3) /* video card */
- return p;
- }
- return nil;
-}
-
-static ulong
-nvidialinear(VGAscr* scr, int* size, int* align)
-{
- Pcidev *p;
- int oapsize, wasupamem;
- ulong aperture, oaperture;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- aperture = 0;
- if(p = nvidiapci()){
- aperture = p->mem[1].bar & ~0x0F;
- *size = p->mem[1].size;
- }
-
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-nvidiaenable(VGAscr* scr)
-{
- Pcidev *p;
- ulong aperture;
- int align, size;
-
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the physical address of
- * the MMIO registers.
- */
- if(scr->io)
- return;
- p = nvidiapci();
- if(p == nil)
- return;
- scr->id = p->did;
-
- scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
- if(scr->io == 0)
- return;
- addvgaseg("nvidiammio", scr->io, p->mem[0].size);
-
- size = p->mem[1].size;
- align = 0;
- aperture = nvidialinear(scr, &size, &align);
- if(aperture){
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("nvidiascreen", aperture, size);
- }
-}
-
-static void
-nvidiacurdisable(VGAscr* scr)
-{
- if(scr->io == 0)
- return;
-
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
-}
-
-static void
-nvidiacurload(VGAscr* scr, Cursor* curs)
-{
- ulong* p;
- int i,j;
- ushort c,s;
- ulong tmp;
-
- if(scr->io == 0)
- return;
-
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
-
- p = KADDR(scr->io + hwCurImage);
-
- for(i=0; i<16; i++) {
- switch(scr->id){
- default:
- c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
- s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
- break;
- case 0x171: /* for Geforece4 MX bug, K.Okamoto */
- case 0x181:
- c = (curs->clr[2 * i+1] << 8) | curs->clr[2 * i];
- s = (curs->set[2 * i+1] << 8) | curs->set[2 * i];
- break;
- }
- tmp = 0;
- for (j=0; j<16; j++){
- if(s&0x8000)
- tmp |= 0x80000000;
- else if(c&0x8000)
- tmp |= 0xFFFF0000;
- if (j&0x1){
- *p++ = tmp;
- tmp = 0;
- } else {
- tmp>>=16;
- }
- c<<=1;
- s<<=1;
- }
- for (j=0; j<8; j++)
- *p++ = 0;
- }
- for (i=0; i<256; i++)
- *p++ = 0;
-
- scr->offset = curs->offset;
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
-
- return;
-}
-
-static int
-nvidiacurmove(VGAscr* scr, Point p)
-{
- ulong* cursorpos;
-
- if(scr->io == 0)
- return 1;
-
- cursorpos = KADDR(scr->io + hwCurPos);
- *cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);
-
- return 0;
-}
-
-static void
-nvidiacurenable(VGAscr* scr)
-{
- nvidiaenable(scr);
- if(scr->io == 0)
- return;
-
- vgaxo(Crtx, 0x1F, 0x57);
-
- nvidiacurload(scr, &arrow);
- nvidiacurmove(scr, ZP);
-
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
-}
-
-enum {
- RopFifo = 0x00000000,
- ClipFifo = 0x00002000,
- PattFifo = 0x00004000,
- BltFifo = 0x00008000,
- BitmapFifo = 0x0000A000,
-};
-
-enum {
- RopRop3 = RopFifo + 0x300,
-
- ClipTopLeft = ClipFifo + 0x300,
- ClipWidthHeight = ClipFifo + 0x304,
-
- PattShape = PattFifo + 0x0308,
- PattColor0 = PattFifo + 0x0310,
- PattColor1 = PattFifo + 0x0314,
- PattMonochrome0 = PattFifo + 0x0318,
- PattMonochrome1 = PattFifo + 0x031C,
-
- BltTopLeftSrc = BltFifo + 0x0300,
- BltTopLeftDst = BltFifo + 0x0304,
- BltWidthHeight = BltFifo + 0x0308,
-
- BitmapColor1A = BitmapFifo + 0x03FC,
- BitmapURect0TopLeft = BitmapFifo + 0x0400,
- BitmapURect0WidthHeight = BitmapFifo + 0x0404,
-};
-
-static void
-waitforidle(VGAscr *scr)
-{
- ulong* pgraph;
- int x;
-
- pgraph = KADDR(scr->io + Pgraph);
-
- x = 0;
- while(pgraph[0x00000700/4] & 0x01 && x++ < 1000000)
- ;
-
- if(x >= 1000000)
- iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->io, scr, getcallerpc(&scr));
-}
-
-static void
-waitforfifo(VGAscr *scr, int fifo, int entries)
-{
- ushort* fifofree;
- int x;
-
- x = 0;
- fifofree = KADDR(scr->io + Fifo + fifo + 0x10);
-
- while(((*fifofree >> 2) < entries) && x++ < 1000000)
- ;
-
- if(x >= 1000000)
- iprint("fifo stat %d scrio %.8lux scr %p pc %luX\n", *fifofree, scr->io, scr, getcallerpc(&scr));
-}
-
-static int
-nvidiahwfill(VGAscr *scr, Rectangle r, ulong sval)
-{
- ulong* fifo;
-
- fifo = KADDR(scr->io + Fifo);
-
- waitforfifo(scr, BitmapFifo, 1);
-
- fifo[BitmapColor1A/4] = sval;
-
- waitforfifo(scr, BitmapFifo, 2);
-
- fifo[BitmapURect0TopLeft/4] = (r.min.x << 16) | r.min.y;
- fifo[BitmapURect0WidthHeight/4] = (Dx(r) << 16) | Dy(r);
-
- waitforidle(scr);
-
- return 1;
-}
-
-static int
-nvidiahwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
-{
- ulong* fifo;
-
- fifo = KADDR(scr->io + Fifo);
-
- waitforfifo(scr, BltFifo, 3);
-
- fifo[BltTopLeftSrc/4] = (sr.min.y << 16) | sr.min.x;
- fifo[BltTopLeftDst/4] = (r.min.y << 16) | r.min.x;
- fifo[BltWidthHeight/4] = (Dy(r) << 16) | Dx(r);
-
- waitforidle(scr);
-
- return 1;
-}
-
-void
-nvidiablank(VGAscr*, int blank)
-{
- uchar seq1, crtc1A;
-
- seq1 = vgaxi(Seqx, 1) & ~0x20;
- crtc1A = vgaxi(Crtx, 0x1A) & ~0xC0;
-
- if(blank){
- seq1 |= 0x20;
-// crtc1A |= 0xC0;
- crtc1A |= 0x80;
- }
-
- vgaxo(Seqx, 1, seq1);
- vgaxo(Crtx, 0x1A, crtc1A);
-}
-
-static void
-nvidiadrawinit(VGAscr *scr)
-{
- ulong* fifo;
-
- fifo = KADDR(scr->io + Fifo);
-
- waitforfifo(scr, ClipFifo, 2);
-
- fifo[ClipTopLeft/4] = 0x0;
- fifo[ClipWidthHeight/4] = 0x80008000;
-
- waitforfifo(scr, PattFifo, 5);
-
- fifo[PattShape/4] = 0;
- fifo[PattColor0/4] = 0xffffffff;
- fifo[PattColor1/4] = 0xffffffff;
- fifo[PattMonochrome0/4] = 0xffffffff;
- fifo[PattMonochrome1/4] = 0xffffffff;
-
- waitforfifo(scr, RopFifo, 1);
-
- fifo[RopRop3/4] = 0xCC;
-
- waitforidle(scr);
-
- scr->blank = nvidiablank;
- hwblank = 1;
- scr->fill = nvidiahwfill;
- scr->scroll = nvidiahwscroll;
-}
-
-VGAdev vganvidiadev = {
- "nvidia",
-
- nvidiaenable,
- nil,
- nil,
- nvidialinear,
- nvidiadrawinit,
-};
-
-VGAcur vganvidiacur = {
- "nvidiahwgc",
-
- nvidiacurenable,
- nvidiacurdisable,
- nvidiacurload,
- nvidiacurmove,
-};
diff --git a/os/pc/vgargb524.c b/os/pc/vgargb524.c
deleted file mode 100644
index 89c2129d..00000000
--- a/os/pc/vgargb524.c
+++ /dev/null
@@ -1,236 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-/*
- * IBM RGB524.
- * 170/220MHz High Performance Palette DAC.
- *
- * Assumes hooked up to an S3 Vision96[48].
- */
-enum {
- IndexLo = 0x00,
- IndexHi = 0x01,
- Data = 0x02,
- IndexCtl = 0x03,
-};
-
-enum { /* index registers */
- CursorCtl = 0x30,
- CursorXLo = 0x31,
- CursorXHi = 0x32,
- CursorYLo = 0x33,
- CursorYHi = 0x34,
- CursorHotX = 0x35,
- CursorHotY = 0x36,
-
- CursorR1 = 0x40,
- CursorG1 = 0x41,
- CursorB1 = 0x42,
- CursorR2 = 0x43,
- CursorG2 = 0x44,
- CursorB2 = 0x45,
- CursorR3 = 0x46,
- CursorG3 = 0x47,
- CursorB3 = 0x48,
-
- CursorArray = 0x100,
-};
-
-/*
- * Lower 2-bits of indirect DAC register
- * addressing.
- */
-static ushort dacxreg[4] = {
- PaddrW, Pdata, Pixmask, PaddrR
-};
-
-static uchar
-rgb524setrs2(void)
-{
- uchar rs2;
-
- rs2 = vgaxi(Crtx, 0x55);
- vgaxo(Crtx, 0x55, (rs2 & 0xFC)|0x01);
-
- return rs2;
-}
-
-static void
-rgb524xo(int index, uchar data)
-{
- vgao(dacxreg[IndexLo], index & 0xFF);
- vgao(dacxreg[IndexHi], (index>>8) & 0xFF);
- vgao(dacxreg[Data], data);
-}
-
-static void
-rgb524disable(VGAscr*)
-{
- uchar rs2;
-
- rs2 = rgb524setrs2();
- rgb524xo(CursorCtl, 0x00);
- vgaxo(Crtx, 0x55, rs2);
-}
-
-static void
-rgb524enable(VGAscr*)
-{
- uchar rs2;
-
- rs2 = rgb524setrs2();
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults.
- */
- rgb524xo(CursorCtl, 0x00);
-
- /*
- * Cursor colour 1 (white),
- * cursor colour 2 (black).
- */
- rgb524xo(CursorR1, Pwhite); rgb524xo(CursorG1, Pwhite); rgb524xo(CursorB1, Pwhite);
- rgb524xo(CursorR2, Pblack); rgb524xo(CursorG2, Pblack); rgb524xo(CursorB2, Pblack);
-
- /*
- * Enable the cursor, 32x32, mode 2.
- */
- rgb524xo(CursorCtl, 0x23);
-
- vgaxo(Crtx, 0x55, rs2);
-}
-
-static void
-rgb524load(VGAscr*, Cursor* curs)
-{
- uchar p, p0, p1, rs2;
- int x, y;
-
- rs2 = rgb524setrs2();
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults.
- */
- rgb524xo(CursorCtl, 0x00);
-
- /*
- * Set auto-increment mode for index-register addressing
- * and initialise the cursor array index.
- */
- vgao(dacxreg[IndexCtl], 0x01);
- vgao(dacxreg[IndexLo], CursorArray & 0xFF);
- vgao(dacxreg[IndexHi], (CursorArray>>8) & 0xFF);
-
- /*
- * Initialise the 32x32 cursor RAM array. There are 2 planes,
- * p0 and p1. Data is written 4 pixels per byte, with p1 the
- * MS bit of each pixel.
- * The cursor is set in X-Windows mode which gives the following
- * truth table:
- * p1 p0 colour
- * 0 0 underlying pixel colour
- * 0 1 underlying pixel colour
- * 1 0 cursor colour 1
- * 1 1 cursor colour 2
- * Put the cursor into the top-left of the 32x32 array.
- */
- for(y = 0; y < 32; y++){
- for(x = 0; x < 32/8; x++){
- if(x < 16/8 && y < 16){
- p0 = curs->clr[x+y*2];
- p1 = curs->set[x+y*2];
-
- p = 0x00;
- if(p1 & 0x80)
- p |= 0xC0;
- else if(p0 & 0x80)
- p |= 0x80;
- if(p1 & 0x40)
- p |= 0x30;
- else if(p0 & 0x40)
- p |= 0x20;
- if(p1 & 0x20)
- p |= 0x0C;
- else if(p0 & 0x20)
- p |= 0x08;
- if(p1 & 0x10)
- p |= 0x03;
- else if(p0 & 0x10)
- p |= 0x02;
- vgao(dacxreg[Data], p);
-
- p = 0x00;
- if(p1 & 0x08)
- p |= 0xC0;
- else if(p0 & 0x08)
- p |= 0x80;
- if(p1 & 0x04)
- p |= 0x30;
- else if(p0 & 0x04)
- p |= 0x20;
- if(p1 & 0x02)
- p |= 0x0C;
- else if(p0 & 0x02)
- p |= 0x08;
- if(p1 & 0x01)
- p |= 0x03;
- else if(p0 & 0x01)
- p |= 0x02;
- vgao(dacxreg[Data], p);
- }
- else{
- vgao(dacxreg[Data], 0x00);
- vgao(dacxreg[Data], 0x00);
- }
- }
- }
-
- /*
- * Initialise the cursor hotpoint,
- * enable the cursor and restore state.
- */
- rgb524xo(CursorHotX, -curs->offset.x);
- rgb524xo(CursorHotY, -curs->offset.y);
-
- rgb524xo(CursorCtl, 0x23);
-
- vgaxo(Crtx, 0x55, rs2);
-}
-
-static int
-rgb524move(VGAscr*, Point p)
-{
- uchar rs2;
-
- rs2 = rgb524setrs2();
-
- rgb524xo(CursorXLo, p.x & 0xFF);
- rgb524xo(CursorXHi, (p.x>>8) & 0x0F);
- rgb524xo(CursorYLo, p.y & 0xFF);
- rgb524xo(CursorYHi, (p.y>>8) & 0x0F);
-
- vgaxo(Crtx, 0x55, rs2);
-
- return 0;
-}
-
-VGAcur vgargb524cur = {
- "rgb524hwgc",
-
- rgb524enable,
- rgb524disable,
- rgb524load,
- rgb524move,
-};
diff --git a/os/pc/vgas3.c b/os/pc/vgas3.c
deleted file mode 100644
index b23657e6..00000000
--- a/os/pc/vgas3.c
+++ /dev/null
@@ -1,620 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum {
- PCIS3 = 0x5333, /* PCI VID */
-
- SAVAGE3D = 0x8A20, /* PCI DID */
- SAVAGE3DMV = 0x8A21,
- SAVAGE4 = 0x8A22,
- PROSAVAGEP = 0x8A25,
- PROSAVAGEK = 0x8A26,
- PROSAVAGE8 = 0x8D04,
- SAVAGEMXMV = 0x8C10,
- SAVAGEMX = 0x8C11,
- SAVAGEIXMV = 0x8C12,
- SAVAGEIX = 0x8C13,
- SUPERSAVAGEIXC16 = 0x8C2E,
- SAVAGE2000 = 0x9102,
-
- VIRGE = 0x5631,
- VIRGEGX2 = 0x8A10,
- VIRGEDXGX = 0x8A01,
- VIRGEVX = 0x883D,
- VIRGEMX = 0x8C01,
- VIRGEMXP = 0x8C03,
-
- VIRTUALPC2004 = 0x8810,
- AURORA64VPLUS = 0x8812,
-};
-
-static int
-s3pageset(VGAscr* scr, int page)
-{
- uchar crt35, crt51;
- int opage;
-
- crt35 = vgaxi(Crtx, 0x35);
- if(scr->gscreen->depth >= 8){
- /*
- * The S3 registers need to be unlocked for this.
- * Let's hope they are already:
- * vgaxo(Crtx, 0x38, 0x48);
- * vgaxo(Crtx, 0x39, 0xA0);
- *
- * The page is 6 bits, the lower 4 bits in Crt35<3:0>,
- * the upper 2 in Crt51<3:2>.
- */
- vgaxo(Crtx, 0x35, page & 0x0F);
- crt51 = vgaxi(Crtx, 0x51);
- vgaxo(Crtx, 0x51, (crt51 & ~0x0C)|((page & 0x30)>>2));
- opage = ((crt51 & 0x0C)<<2)|(crt35 & 0x0F);
- }
- else{
- vgaxo(Crtx, 0x35, (page<<2) & 0x0C);
- opage = (crt35>>2) & 0x03;
- }
-
- return opage;
-}
-
-static void
-s3page(VGAscr* scr, int page)
-{
- int id;
-
- id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
- switch(id){
-
- case VIRGEGX2:
- break;
-
- default:
- lock(&scr->devlock);
- s3pageset(scr, page);
- unlock(&scr->devlock);
- break;
- }
-}
-
-static ulong
-s3linear(VGAscr* scr, int* size, int* align)
-{
- char *mmioname;
- ulong aperture, oaperture, mmiobase, mmiosize;
- int i, id, j, osize, oapsize, wasupamem;
- Pcidev *p;
-
- osize = *size;
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- mmiosize = 0;
- mmiobase = 0;
- mmioname = nil;
-
- /*
- * S3 makes cards other than display controllers, so
- * look for the first S3 display controller (device class 3)
- * and not one of their sound cards.
- */
- p = nil;
- while(p = pcimatch(p, PCIS3, 0)){
- if(p->ccrb == 0x03)
- break;
- }
- if(p != nil){
- for(i=0; i<nelem(p->mem); i++){
- if(p->mem[i].size >= *size
- && ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0)
- break;
- }
- if(i >= nelem(p->mem)){
- print("vgas3: aperture not found\n");
- return 0;
- }
- aperture = p->mem[i].bar & ~0x0F;
- *size = p->mem[i].size;
-
- id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
- switch(id){ /* find mmio */
- case SAVAGE4:
- case PROSAVAGEP:
- case PROSAVAGEK:
- case PROSAVAGE8:
- case SUPERSAVAGEIXC16:
- /*
- * We could assume that the MMIO registers
- * will be in the screen segment and just use
- * that, but PCI software is allowed to move them
- * if it feels like it, so we look for an aperture of
- * the right size; only the first 512k actually means
- * anything. The S3 engineers overestimated how
- * much space they would need in the first design.
- */
- for(j=0; j<nelem(p->mem); j++){
- if(i == j)
- continue;
- if(p->mem[j].size==512*1024 || p->mem[j].size==16*1024*1024){
- mmiobase = p->mem[j].bar & ~0x0F;
- mmiosize = 512*1024;
- scr->mmio = (ulong*)upamalloc(mmiobase, mmiosize, 0);
- mmioname = "savagemmio";
- break;
- }
- }
- if(mmiosize == 0){
- print("savage4: mmio not found\n");
- return 0;
- }
- }
- }else
- aperture = 0;
-
- if(wasupamem)
- upafree(oaperture, oapsize);
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0))
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 1;
-
- if(oaperture && oaperture != aperture)
- print("warning (BUG): redefinition of aperture does not change s3screen segment\n");
- addvgaseg("s3screen", aperture, osize);
-
- if(mmiosize)
- addvgaseg(mmioname, mmiobase, mmiosize);
-
- return aperture;
-}
-
-static void
-s3vsyncactive(void)
-{
- /*
- * Hardware cursor information is fetched from display memory
- * during the horizontal blank active time. The 80x chips may hang
- * if the cursor is turned on or off during this period.
- */
- while((vgai(Status1) & 0x08) == 0)
- ;
-}
-
-static void
-s3disable(VGAscr*)
-{
- uchar crt45;
-
- /*
- * Turn cursor off.
- */
- crt45 = vgaxi(Crtx, 0x45) & 0xFE;
- s3vsyncactive();
- vgaxo(Crtx, 0x45, crt45);
-}
-
-static void
-s3load(VGAscr* scr, Cursor* curs)
-{
- uchar *p;
- int id, dolock, opage, x, y;
-
- /*
- * Disable the cursor and
- * set the pointer to the two planes.
- */
- s3disable(scr);
-
- opage = 0;
- p = KADDR(scr->aperture);
- id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
- switch(id){
-
- case VIRTUALPC2004:
- case VIRGE:
- case VIRGEDXGX:
- case VIRGEGX2:
- case VIRGEVX:
- case SAVAGEMXMV:
- case SAVAGEIXMV:
- case SAVAGE4:
- case PROSAVAGEP:
- case PROSAVAGEK:
- case PROSAVAGE8:
- case SUPERSAVAGEIXC16:
- dolock = 0;
- p += scr->storage;
- break;
-
- default:
- dolock = 1;
- lock(&scr->devlock);
- opage = s3pageset(scr, scr->storage>>16);
- p += (scr->storage & 0xFFFF);
- break;
- }
-
- /*
- * The cursor is set in Microsoft Windows format (the ViRGE/GX2 doesn't
- * support the X11 format) which gives the following truth table:
- * and xor colour
- * 0 0 background colour
- * 0 1 foreground colour
- * 1 0 current screen pixel
- * 1 1 NOT current screen pixel
- * Put the cursor into the top-left of the 64x64 array.
- *
- * The cursor pattern in memory is interleaved words of
- * AND and XOR patterns.
- */
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x += 2){
- if(x < 16/8 && y < 16){
- *p++ = ~(curs->clr[2*y + x]|curs->set[2*y + x]);
- *p++ = ~(curs->clr[2*y + x+1]|curs->set[2*y + x+1]);
- *p++ = curs->set[2*y + x];
- *p++ = curs->set[2*y + x+1];
- }
- else {
- *p++ = 0xFF;
- *p++ = 0xFF;
- *p++ = 0x00;
- *p++ = 0x00;
- }
- }
- }
-
- if(dolock){
- s3pageset(scr, opage);
- unlock(&scr->devlock);
- }
-
- /*
- * Save the cursor hotpoint and enable the cursor.
- */
- scr->offset = curs->offset;
- s3vsyncactive();
- vgaxo(Crtx, 0x45, 0x01);
-}
-
-static int
-s3move(VGAscr* scr, Point p)
-{
- int x, xo, y, yo;
-
- /*
- * Mustn't position the cursor offscreen even partially,
- * or it disappears. Therefore, if x or y is -ve, adjust the
- * cursor offset instead.
- * There seems to be a bug in that if the offset is 1, the
- * cursor doesn't disappear off the left edge properly, so
- * round it up to be even.
- */
- if((x = p.x+scr->offset.x) < 0){
- xo = -x;
- xo = ((xo+1)/2)*2;
- x = 0;
- }
- else
- xo = 0;
- if((y = p.y+scr->offset.y) < 0){
- yo = -y;
- y = 0;
- }
- else
- yo = 0;
-
- vgaxo(Crtx, 0x46, (x>>8) & 0x07);
- vgaxo(Crtx, 0x47, x & 0xFF);
- vgaxo(Crtx, 0x49, y & 0xFF);
- vgaxo(Crtx, 0x4E, xo);
- vgaxo(Crtx, 0x4F, yo);
- vgaxo(Crtx, 0x48, (y>>8) & 0x07);
-
- return 0;
-}
-
-static void
-s3enable(VGAscr* scr)
-{
- int i;
- ulong storage;
-
- s3disable(scr);
-
- /*
- * Cursor colours. Set both the CR0[EF] and the colour
- * stack in case we are using a 16-bit RAMDAC.
- */
- vgaxo(Crtx, 0x0E, Pwhite);
- vgaxo(Crtx, 0x0F, Pblack);
- vgaxi(Crtx, 0x45);
-
- for(i = 0; i < 3; i++)
- vgaxo(Crtx, 0x4A, Pblack);
- vgaxi(Crtx, 0x45);
- for(i = 0; i < 3; i++)
- vgaxo(Crtx, 0x4B, Pwhite);
-
- /*
- * Find a place for the cursor data in display memory.
- * Must be on a 1024-byte boundary.
- */
- storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024;
- vgaxo(Crtx, 0x4C, storage>>8);
- vgaxo(Crtx, 0x4D, storage & 0xFF);
- storage *= 1024;
- scr->storage = storage;
-
- /*
- * Load, locate and enable the cursor
- * in Microsoft Windows format.
- */
- s3load(scr, &arrow);
- s3move(scr, ZP);
- vgaxo(Crtx, 0x55, vgaxi(Crtx, 0x55) & ~0x10);
- s3vsyncactive();
- vgaxo(Crtx, 0x45, 0x01);
-}
-
-/*
- * The manual gives byte offsets, but we want ulong offsets, hence /4.
- */
-enum {
- SrcBase = 0xA4D4/4,
- DstBase = 0xA4D8/4,
- Stride = 0xA4E4/4,
- FgrdData = 0xA4F4/4,
- WidthHeight = 0xA504/4,
- SrcXY = 0xA508/4,
- DestXY = 0xA50C/4,
- Command = 0xA500/4,
- SubStat = 0x8504/4,
- FifoStat = 0x850C/4,
-};
-
-/*
- * Wait for writes to VGA memory via linear aperture to flush.
- */
-enum {Maxloop = 1<<24};
-struct {
- ulong linear;
- ulong fifo;
- ulong idle;
- ulong lineartimeout;
- ulong fifotimeout;
- ulong idletimeout;
-} waitcount;
-
-static void
-waitforlinearfifo(VGAscr *scr)
-{
- ulong *mmio;
- long x;
- static ulong nwaitforlinearfifo;
- ulong mask, val;
-
- switch(scr->id){
- default:
- panic("unknown scr->id in s3 waitforlinearfifo");
- case 0x8A01: /* ViRGE/[DG]X. XFree86 says no waiting necessary */
- return;
- case 0x5631: /* ViRGE */
- case 0x883D: /* ViRGE/VX */
- mask = 0x0F<<6;
- val = 0x08<<6;
- break;
- case 0x8A10: /* ViRGE/GX2 */
- mask = 0x1F<<6;
- val = 0x10<<6;
- break;
- }
- mmio = scr->mmio;
- x = 0;
- while((mmio[FifoStat]&mask) != val && x++ < Maxloop)
- waitcount.linear++;
- if(x >= Maxloop)
- waitcount.lineartimeout++;
-}
-
-static void
-waitforfifo(VGAscr *scr, int entries)
-{
- ulong *mmio;
- long x;
- static ulong nwaitforfifo;
-
- mmio = scr->mmio;
- x = 0;
- while((mmio[SubStat]&0x1F00) < ((entries+2)<<8) && x++ < Maxloop)
- waitcount.fifo++;
- if(x >= Maxloop)
- waitcount.fifotimeout++;
-}
-
-static void
-waitforidle(VGAscr *scr)
-{
- ulong *mmio;
- long x;
-
- mmio = scr->mmio;
- x = 0;
- while((mmio[SubStat]&0x3F00) != 0x3000 && x++ < Maxloop)
- waitcount.idle++;
- if(x >= Maxloop)
- waitcount.idletimeout++;
-}
-
-static int
-hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
-{
- enum { Bitbltop = 0xCC }; /* copy source */
- ulong *mmio;
- ulong cmd, stride;
- Point dp, sp;
- int did, d;
-
- d = scr->gscreen->depth;
- did = (d-8)/8;
- cmd = 0x00000020|(Bitbltop<<17)|(did<<2);
- stride = Dx(scr->gscreen->r)*d/8;
-
- if(r.min.x <= sr.min.x){
- cmd |= 1<<25;
- dp.x = r.min.x;
- sp.x = sr.min.x;
- }else{
- dp.x = r.max.x-1;
- sp.x = sr.max.x-1;
- }
-
- if(r.min.y <= sr.min.y){
- cmd |= 1<<26;
- dp.y = r.min.y;
- sp.y = sr.min.y;
- }else{
- dp.y = r.max.y-1;
- sp.y = sr.max.y-1;
- }
-
- mmio = scr->mmio;
- waitforlinearfifo(scr);
- waitforfifo(scr, 7);
- mmio[SrcBase] = scr->aperture;
- mmio[DstBase] = scr->aperture;
- mmio[Stride] = (stride<<16)|stride;
- mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
- mmio[SrcXY] = (sp.x<<16)|sp.y;
- mmio[DestXY] = (dp.x<<16)|dp.y;
- mmio[Command] = cmd;
- waitforidle(scr);
- return 1;
-}
-
-static int
-hwfill(VGAscr *scr, Rectangle r, ulong sval)
-{
- enum { Bitbltop = 0xCC }; /* copy source */
- ulong *mmio;
- ulong cmd, stride;
- int did, d;
-
- d = scr->gscreen->depth;
- did = (d-8)/8;
- cmd = 0x16000120|(Bitbltop<<17)|(did<<2);
- stride = Dx(scr->gscreen->r)*d/8;
- mmio = scr->mmio;
- waitforlinearfifo(scr);
- waitforfifo(scr, 8);
- mmio[SrcBase] = scr->aperture;
- mmio[DstBase] = scr->aperture;
- mmio[DstBase] = scr->aperture;
- mmio[Stride] = (stride<<16)|stride;
- mmio[FgrdData] = sval;
- mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
- mmio[DestXY] = (r.min.x<<16)|r.min.y;
- mmio[Command] = cmd;
- waitforidle(scr);
- return 1;
-}
-
-enum {
- CursorSyncCtl = 0x0D, /* in Seqx */
- VsyncHi = 0x80,
- VsyncLo = 0x40,
- HsyncHi = 0x20,
- HsyncLo = 0x10,
-};
-
-static void
-s3blank(VGAscr*, int blank)
-{
- uchar x;
-
- x = vgaxi(Seqx, CursorSyncCtl);
- x &= ~0xF0;
- if(blank)
- x |= VsyncLo | HsyncLo;
- vgaxo(Seqx, CursorSyncCtl, x);
-}
-
-static void
-s3drawinit(VGAscr *scr)
-{
- extern void savageinit(VGAscr*); /* vgasavage.c */
- ulong id;
-
- id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
- scr->id = id;
-
- /*
- * It's highly likely that other ViRGEs will work without
- * change to the driver, with the exception of the size of
- * the linear aperture memory write FIFO. Since we don't
- * know that size, I'm not turning them on. See waitforlinearfifo
- * above.
- */
- scr->blank = s3blank;
- /* hwblank = 1; not known to work well */
-
- switch(id){
- case VIRGE:
- case VIRGEVX:
- case VIRGEGX2:
- scr->mmio = (ulong*)(scr->aperture+0x1000000);
- scr->fill = hwfill;
- scr->scroll = hwscroll;
- break;
- case SAVAGEMXMV:
- case SAVAGEIXMV:
- scr->mmio = (ulong*)(scr->aperture+0x1000000);
- savageinit(scr);
- break;
- case SUPERSAVAGEIXC16:
- case SAVAGE4:
- case PROSAVAGEP:
- case PROSAVAGE8:
- case PROSAVAGEK:
- /* scr->mmio is set by s3linear */
- savageinit(scr);
- break;
- }
-}
-
-VGAdev vgas3dev = {
- "s3",
-
- 0,
- 0,
- s3page,
- s3linear,
- s3drawinit,
-};
-
-VGAcur vgas3cur = {
- "s3hwgc",
-
- s3enable,
- s3disable,
- s3load,
- s3move,
-};
-
diff --git a/os/pc/vgasavage.c b/os/pc/vgasavage.c
deleted file mode 100644
index 263b688b..00000000
--- a/os/pc/vgasavage.c
+++ /dev/null
@@ -1,571 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum {
- PCIS3 = 0x5333, /* PCI VID */
-
- SAVAGE3D = 0x8A20, /* PCI DID */
- SAVAGE3DMV = 0x8A21,
- SAVAGE4 = 0x8A22,
- PROSAVAGEP = 0x8A25,
- PROSAVAGEK = 0x8A26,
- PROSAVAGE8 = 0x8D04,
- SAVAGEMXMV = 0x8C10,
- SAVAGEMX = 0x8C11,
- SAVAGEIXMV = 0x8C12,
- SAVAGEIX = 0x8C13,
- SUPERSAVAGEIXC16 = 0x8C2E,
- SAVAGE2000 = 0x9102,
-
- VIRGE = 0x5631,
- VIRGEGX2 = 0x8A10,
- VIRGEDXGX = 0x8A01,
- VIRGEVX = 0x883D,
- VIRGEMX = 0x8C01,
- VIRGEMXP = 0x8C03,
-
- AURORA64VPLUS = 0x8812,
-};
-
-/*
- * Savage4 et al. acceleration.
- *
- * This is based only on the Savage4 documentation.
- * It is expected to work on other Savage cards as well,
- * but has not been tried.
- *
- * There are five ways to access the 2D graphics engine registers:
- * - Old MMIO non-packed format
- * - Old MMIO packed format
- * - New MMIO non-packed format
- * - New MMIO packed format
- * - Burst Command Interface (BCI)
- *
- * Of these, the manual hints that the first three are deprecated,
- * and it does not document any of those three well enough to use.
- *
- * I have tried for many hours with no success to understand the BCI
- * interface well enough to use it. It is not well documented, and the
- * XFree86 driver seems to completely contradict what little documentation
- * there is.
- *
- * This leaves the packed new MMIO.
- * The manual contradicts itself here, claming that the registers
- * start at 0x2008100 as well as at 0x0008100 from the base of the
- * mmio segment. Since the segment is only 512k, we assume that
- * the latter is the correct offset.
- *
- * According to the manual, only 16-bit reads of the 2D registers
- * are supported: 32-bit reads will return garbage in the upper word.
- * 32-bit writes must be enabled explicitly.
- *
- * 32-bit reads of the status registers seem just fine.
- */
-
-/* 2D graphics engine registers for Savage4; others appear to be mostly the same */
-enum {
- SubsystemStatus = 0x8504, /* Subsystem Status: read only */
- /* read only: whether we get interrupts on various events */
- VsyncInt = 1<<0, /* vertical sync */
- GeBusyInt = 1<<1, /* 2D graphics engine busy */
- BfifoFullInt = 1<<2, /* BIU FIFO full */
- BfifoEmptyInt = 1<<3, /* BIU FIFO empty */
- CfifoFullInt = 1<<4, /* command FIFO full */
- CfifoEmptyInt = 1<<5, /* command FIFO empty */
- BciInt = 1<<6, /* BCI */
- LpbInt = 1<<7, /* LPB */
- CbHiInt = 1<<16, /* COB upper threshold */
- CbLoInt = 1<<17, /* COB lower threshold */
-
- SubsystemCtl = 0x8504, /* Subsystem Control: write only */
- /* clear interrupts for various events */
- VsyncClr = 1<<0,
- GeBusyClr = 1<<1,
- BfifoFullClr = 1<<2,
- BfifoEmptyClr = 1<<3,
- CfifoFullClr = 1<<4,
- CfifoEmptyClr = 1<<5,
- BciClr = 1<<6,
- LpbClr = 1<<7,
- CbHiClr = 1<<16,
- CbLoClr = 1<<17,
-
- /* enable interrupts for various events */
- VsyncEna = 1<<8,
- Busy2DEna = 1<<9,
- BfifoFullEna = 1<<10,
- BfifoEmptyEna = 1<<11,
- CfifoFullEna = 1<<12,
- CfifoEmptyEna = 1<<13,
- SubsysBciEna = 1<<14,
- CbHiEna = 1<<24,
- CbLoEna = 1<<25,
-
- /* 2D graphics engine software reset */
- GeSoftReset = 1<<15,
-
- FifoStatus = 0x8508, /* FIFO status: read only */
- CwbEmpty = 1<<0, /* command write buffer empty */
- CrbEmpty = 1<<1, /* command read buffer empty */
- CobEmpty = 1<<2, /* command overflow buffer empty */
- CfifoEmpty = 1<<3, /* command FIFO empty */
- CwbFull = 1<<8, /* command write buffer full */
- CrbFull = 1<<9, /* command read buffer full */
- CobFull = 1<<10, /* command overflow buffer full */
- CfifoFull = 1<<11, /* command FIFO full */
-
- AdvFunCtl = 0x850C, /* Advanced Function Control: read/write */
- GeEna = 1<<0, /* enable 2D/3D engine */
- /*
- * according to the manual, BigPixel should be
- * set when bpp >= 8 (bpp != 4), and then CR50_5-4 are
- * used to figure out bpp example. however, it does bad things
- * to the screen in 8bpp mode.
- */
- BigPixel = 1<<2, /* 8 or more bpp enhanced mode */
- LaEna = 1<<3, /* linear addressing ena: or'ed with CR58_4 */
- Mclk_2 = 0<<8, /* 2D engine clock divide: MCLK/2 */
- Mclk_4 = 1<<8, /* " MCLK/4 */
- Mclk = 2<<8, /* " MCLK */
- /* Mclk = 3<<8, /* " MCLK */
- Ic33mhz = 1<<16, /* Internal clock 33 MHz (instead of 66) */
-
- WakeupReg = 0x8510, /* Wakeup: read/write */
- WakeupBit = 1<<0, /* wake up: or'ed with 3C3_0 */
-
- SourceY = 0x8100, /* UL corner of bitblt source */
- SourceX = 0x8102, /* " */
- RectY = 0x8100, /* UL corner of rectangle fill */
- RectX = 0x8102, /* " */
- DestY = 0x8108, /* UL corner of bitblt dest */
- DestX = 0x810A, /* " */
- Height = 0x8148, /* bitblt, image xfer rectangle height */
- Width = 0x814A, /* bitblt, image xfer rectangle width */
-
- StartY = 0x8100, /* Line draw: first point*/
- StartX = 0x8102, /* " */
- /*
- * For line draws, the following must be programmed:
- * axial step constant = 2*min(|dx|,|dy|)
- * diagonal step constant = 2*[min(|dx|,|dy|) - max(|dx|,|dy|)]
- * error term = 2*min(|dx|,|dy|) - max(|dx|,|dy| - 1
- * [sic] when start X < end X
- * error term = 2*min(|dx|,|dy|) - max(|dx|,|dy|
- * [sic] when start X >= end X
- */
- AxialStep = 0x8108,
- DiagonalStep = 0x810A,
- LineError = 0x8110,
- MinorLength = 0x8148, /* pixel count along minor axis */
- MajorLength = 0x814A, /* pixel count along major axis */
-
- DrawCmd = 0x8118, /* Drawing Command: write only */
- CmdMagic = 0<<1,
- AcrossPlane = 1<<1, /* across the plane mode */
- LastPixelOff = 1<<2, /* last pixel of line or vector draw not drawn */
- Radial = 1<<3, /* enable radial direction (else axial) */
- DoDraw = 1<<4, /* draw pixels (else only move current pos) */
-
- DrawRight = 1<<5, /* axial drawing direction: left to right */
- /* DrawLeft = 0<<5, */
- MajorY = 1<<6,
- /* MajorX = 0<<6, */
- DrawDown = 1<<7,
- /* DrawUp = 0<<7, */
- Degree0 = 0<<5, /* drawing direction when Radial */
- Degree45 = 1<<5,
- /* ... */
- Degree315 = 7<<5,
-
- UseCPUData = 1<<8,
-
- /* image write bus transfer width */
- Bus8 = 0<<9,
- Bus16 = 1<<9,
- /*
- * in Bus32 mode, doubleword bits beyond the image rect width are
- * discarded. each line starts on a new doubleword.
- * Bus32AP is intended for across-the-plane mode and
- * rounds to byte boundaries instead.
- */
- Bus32 = 2<<9,
- Bus32AP = 3<<9,
-
- CmdNop = 0<<13, /* nop */
- CmdLine = 1<<13, /* draw line */
- CmdFill = 2<<13, /* fill rectangle */
- CmdBitblt = 6<<13, /* bitblt */
- CmdPatblt = 7<<13, /* 8x8 pattern blt */
-
- SrcGBD = 0<<16,
- SrcPBD = 1<<16,
- SrcSBD = 2<<16,
-
- DstGBD = 0<<18,
- DstPBD = 1<<18,
- DstSBD = 2<<18,
-
- /* color sources, controls */
- BgColor = 0x8120, /* Background Color: read/write */
- FgColor = 0x8124, /* Foreground Color: read/write */
- BitplaneWmask = 0x8128, /* Bitplane Write Mask: read/write */
- BitplaneRmask = 0x812C, /* Bitplane Read Mask: read/write */
- CmpColor = 0x8130, /* Color Compare: read/write */
- BgMix = 0x8134,
- FgMix = 0x8136,
- MixNew = 7,
- SrcBg = 0<<5,
- SrcFg = 1<<5,
- SrcCPU = 2<<5,
- SrcDisp = 3<<5,
-
- /* clipping rectangle */
- TopScissors = 0x8138, /* Top Scissors: write only */
- LeftScissors = 0x813A, /* Left Scissors: write only */
- BottomScissors = 0x813C, /* Bottom Scissors: write only */
- RightScissors = 0x813E, /* Right Scissors: write only */
-
- /*
- * Registers with Magic were indirectly accessed in older modes.
- * It is not clear whether the Magic is necessary.
- * In the older modes, writes to these registers were pipelined,
- * so that you had to issue an engine command and wait for engine
- * idle before reading a write back. It is not clear if this is
- * still the case either.
- */
- PixCtl = 0x8140, /* Pixel Control: write only */
- PixMagic = 0xA<<12,
- PixMixFg = 0<<6, /* foreground mix register always */
- PixMixCPU = 2<<6, /* CPU data determines mix register */
- PixMixDisp = 3<<6, /* display data determines mix register */
-
- MfMisc2Ctl = 0x8142, /* Multifunction Control Misc. 2: write only */
- MfMisc2Magic = 0xD<<12,
- DstShift = 0, /* 3 bits: destination base address in MB */
- SrcShift = 4, /* 3 bits: source base address in MB */
- WaitFifoEmpty = 2<<8, /* wait for write FIFO empty between draws */
-
- MfMiscCtl = 0x8144, /* Multifunction Control Misc: write only */
- MfMiscMagic = 0xE<<12,
- UseHighBits = 1<<4, /* select upper 16 bits for 32-bit reg access */
- ClipInvert = 1<<5, /* only touch pixels outside clip rectangle */
- SkipSame = 0<<6, /* ignore pixels with color CmpColor */
- SkipDifferent = 1<<7, /* ignore pixels not color CmpColor */
- CmpEna = 1<<8, /* enable color compare */
- W32Ena = 1<<9, /* enable 32-bit register write */
- ClipDis = 1<<11, /* disable clipping */
-
- /*
- * The bitmap descriptor 1 registers contain the starting
- * address of the bitmap (in bytes).
- * The bitmap descriptor 2 registesr contain stride (in pixels)
- * in the lower 16 bits, depth (in bits) in the next 8 bits,
- * and whether block write is disabled.
- */
- GBD1 = 0x8168, /* Global Bitmap Descriptor 1: read/write */
- GBD2 = 0x816C, /* Global Bitmap Descriptor 2: read/write */
- /* GBD2-only bits */
- BDS64 = 1<<0, /* bitmap descriptor size 64 bits */
- GBDBciEna = 1<<3, /* BCI enable */
- /* generic BD2 bits */
- BlockWriteDis = 1<<28,
- StrideShift = 0,
- DepthShift = 16,
-
- PBD1 = 0x8170, /* Primary Bitmap Descriptor: read/write */
- PBD2 = 0x8174,
- SBD1 = 0x8178, /* Secondary Bitmap Descriptor: read/write */
- SBD2 = 0x817C,
-};
-
-/* mastered data transfer registers */
-
-/* configuration/status registers */
-enum {
- XStatus0 = 0x48C00, /* Status Word 0: read only */
- /* rev. A silicon differs from rev. B; use AltStatus0 */
- CBEMaskA = 0x1FFFF, /* filled command buffer entries */
- CBEShiftA = 0,
- BciIdleA = 1<<17, /* BCI idle */
- Ge3IdleA = 1<<18, /* 3D engine idle */
- Ge2IdleA = 1<<19, /* 2D engine idle */
- McpIdleA = 1<<20, /* motion compensation processor idle */
- MeIdleA = 1<<22, /* master engine idle */
- PfPendA = 1<<23, /* page flip pending */
-
- CBEMaskB = 0x1FFFFF,
- CBEShiftB = 0,
- BciIdleB = 1<<25,
- Ge3IdleB = 1<<26,
- Ge2IdleB = 1<<27,
- McpIdleB = 1<<28,
- MeIdleB = 1<<30,
- PfPendB = 1<<31,
-
- AltStatus0 = 0x48C60, /* Alternate Status Word 0: read only */
- CBEMask = 0x1FFFF,
- CBEShift = 0,
- /* the Savage4 manual says bits 17..23 for these, like Status0 */
- /* empirically, they are bits 21..26 */
- BciIdle = 1<<21,
- Ge3Idle = 1<<22,
- Ge2Idle = 1<<23,
- McpIdle = 1<<24,
- MeIdle = 1<<25,
- PfPend = 1<<26,
-
- XStatus1 = 0x48C04, /* Status Word 1: read only */
- /* contains event tag 1, event tag 0, both 16 bits */
-
- XStatus2 = 0x48C08, /* Status Word 2: read only */
- ScanMask = 0x3FF, /* current scan line */
- ScanShift = 0,
- VRTMask = 0x7F100, /* vert retrace count */
- VRTShift = 11,
-
- CbThresh = 0x48C10, /* Command Buffer Thresholds: read/write */
- CobOff = 0x48C14, /* Command Overflow Buffer: read/write */
-
- CobPtr = 0x48C18, /* Command Overflow Buffer Pointers: read/write */
- CobEna = 1<<2, /* command overflow buffer enable */
- CobBciEna = 1<<3, /* BCI function enable */
- CbeMask = 0xFFFF8000, /* no. of entries in command buffer */
- CbeShift = 15,
-
- AltStatus1 = 0x48C64, /* Alternate Status Word 1: read onnly */
- /* contains current texture surface tag, vertex buffer tag */
-
-};
-
-struct {
- ulong idletimeout;
- ulong tostatw[16];
-} savagestats;
-
-enum {
- Maxloop = 1<<20
-};
-
-static void
-savagewaitidle(VGAscr *scr)
-{
- long x;
- ulong *statw, mask, goal;
-
- switch(scr->id){
- case SAVAGE4:
- case PROSAVAGEP:
- case PROSAVAGEK:
- case PROSAVAGE8:
- /* wait for engine idle and FIFO empty */
- statw = (ulong*)((uchar*)scr->mmio+AltStatus0);
- mask = CBEMask | Ge2Idle;
- goal = Ge2Idle;
- break;
- /* case SAVAGEMXMV: ? */
- /* case SAVAGEMX: ? */
- /* case SAVAGEIX: ? */
- case SUPERSAVAGEIXC16:
- case SAVAGEIXMV:
- case SAVAGEMXMV:
- /* wait for engine idle and FIFO empty */
- statw = (ulong*)((uchar*)scr->mmio+XStatus0);
- mask = CBEMaskA | Ge2IdleA;
- goal = Ge2IdleA;
- break;
- default:
- /*
- * best we can do: can't print or we'll call ourselves.
- * savageinit is supposed to not let this happen.
- */
- return;
- }
-
- for(x=0; x<Maxloop; x++)
- if((*statw & mask) == goal)
- return;
-
- savagestats.tostatw[savagestats.idletimeout++&15] = *statw;
- savagestats.tostatw[savagestats.idletimeout++&15] = (ulong)statw;
-}
-
-static int
-savagefill(VGAscr *scr, Rectangle r, ulong sval)
-{
- uchar *mmio;
-
- mmio = (uchar*)scr->mmio;
-
- *(ulong*)(mmio+FgColor) = sval;
- *(ulong*)(mmio+BgColor) = sval;
- *(ulong*)(mmio+BgMix) = SrcFg|MixNew;
- *(ulong*)(mmio+FgMix) = SrcFg|MixNew;
- *(ushort*)(mmio+RectY) = r.min.y;
- *(ushort*)(mmio+RectX) = r.min.x;
- *(ushort*)(mmio+Width) = Dx(r)-1;
- *(ushort*)(mmio+Height) = Dy(r)-1;
- *(ulong*)(mmio+DrawCmd) = CmdMagic | DoDraw | CmdFill | DrawRight | DrawDown;
- savagewaitidle(scr);
- return 1;
-}
-
-static int
-savagescroll(VGAscr *scr, Rectangle r, Rectangle sr)
-{
- uchar *mmio;
- ulong cmd;
- Point dp, sp;
-
- cmd = CmdMagic | DoDraw | CmdBitblt | SrcPBD | DstGBD;
-
- if(r.min.x <= sr.min.x){
- cmd |= DrawRight;
- dp.x = r.min.x;
- sp.x = sr.min.x;
- }else{
- dp.x = r.max.x-1;
- sp.x = sr.max.x-1;
- }
-
- if(r.min.y <= sr.min.y){
- cmd |= DrawDown;
- dp.y = r.min.y;
- sp.y = sr.min.y;
- }else{
- dp.y = r.max.y-1;
- sp.y = sr.max.y-1;
- }
-
- mmio = (uchar*)scr->mmio;
-
- *(ushort*)(mmio+SourceX) = sp.x;
- *(ushort*)(mmio+SourceY) = sp.y;
- *(ushort*)(mmio+DestX) = dp.x;
- *(ushort*)(mmio+DestY) = dp.y;
- *(ushort*)(mmio+Width) = Dx(r)-1;
- *(ushort*)(mmio+Height) = Dy(r)-1;
- *(ulong*)(mmio+BgMix) = SrcDisp|MixNew;
- *(ulong*)(mmio+FgMix) = SrcDisp|MixNew;
- *(ulong*)(mmio+DrawCmd) = cmd;
- savagewaitidle(scr);
- return 1;
-}
-
-static void
-savageblank(VGAscr*, int blank)
-{
- uchar seqD;
-
- /*
- * Will handle DPMS to monitor
- */
- vgaxo(Seqx, 8, vgaxi(Seqx,8)|0x06);
- seqD = vgaxi(Seqx, 0xD);
- seqD &= 0x03;
- if(blank)
- seqD |= 0x50;
- vgaxo(Seqx, 0xD, seqD);
-
- /*
- * Will handle LCD
- */
- if(blank)
- vgaxo(Seqx, 0x31, vgaxi(Seqx, 0x31) & ~0x10);
- else
- vgaxo(Seqx, 0x31, vgaxi(Seqx, 0x31) | 0x10);
-}
-
-
-void
-savageinit(VGAscr *scr)
-{
- uchar *mmio;
- ulong bd;
-
- /* if you add chip IDs here be sure to update savagewaitidle */
- switch(scr->id){
- case SAVAGE4:
- case PROSAVAGEP:
- case PROSAVAGEK:
- case PROSAVAGE8:
- case SAVAGEIXMV:
- case SUPERSAVAGEIXC16:
- case SAVAGEMXMV:
- break;
- default:
- print("unknown savage %.4lux\n", scr->id);
- return;
- }
-
- mmio = (uchar*)scr->mmio;
- if(mmio == nil) {
- print("savageinit: no mmio\n");
- return;
- }
-
- /* 2D graphics engine software reset */
- *(ushort*)(mmio+SubsystemCtl) = GeSoftReset;
- delay(2);
- *(ushort*)(mmio+SubsystemCtl) = 0;
- savagewaitidle(scr);
-
- /* disable BCI as much as possible */
- *(ushort*)(mmio+CobPtr) &= ~CobBciEna;
- *(ushort*)(mmio+GBD2) &= ~GBDBciEna;
- savagewaitidle(scr);
-
- /* enable 32-bit writes, disable clipping */
- *(ushort*)(mmio+MfMiscCtl) = MfMiscMagic|W32Ena|ClipDis;
- savagewaitidle(scr);
-
- /* enable all read, write planes */
- *(ulong*)(mmio+BitplaneRmask) = ~0;
- *(ulong*)(mmio+BitplaneWmask) = ~0;
- savagewaitidle(scr);
-
- /* turn on linear access, 2D engine */
- *(ulong*)(mmio+AdvFunCtl) |= GeEna|LaEna;
- savagewaitidle(scr);
-
- /* set bitmap descriptors */
- bd = (scr->gscreen->depth<<DepthShift) |
- (Dx(scr->gscreen->r)<<StrideShift) | BlockWriteDis
- | BDS64;
-
- *(ulong*)(mmio+GBD1) = 0;
- *(ulong*)(mmio+GBD2) = bd;
-
- *(ulong*)(mmio+PBD1) = 0;
- *(ulong*)(mmio+PBD2) = bd;
-
- *(ulong*)(mmio+SBD1) = 0;
- *(ulong*)(mmio+SBD2) = bd;
-
- /*
- * For some reason, the GBD needs to get programmed twice,
- * once before the PBD, SBD, and once after.
- * This empirically makes it get set right.
- * I would like to better understand the ugliness
- * going on here.
- */
- *(ulong*)(mmio+GBD1) = 0;
- *(ulong*)(mmio+GBD2) = bd;
- *(ushort*)(mmio+GBD2+2) = bd>>16;
- savagewaitidle(scr);
-
- scr->fill = savagefill;
- scr->scroll = savagescroll;
- scr->blank = savageblank;
- hwblank = 0;
-}
diff --git a/os/pc/vgat2r4.c b/os/pc/vgat2r4.c
deleted file mode 100644
index b8003b87..00000000
--- a/os/pc/vgat2r4.c
+++ /dev/null
@@ -1,586 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-/*
- * #9 Ticket to Ride IV.
- */
-enum {
- IndexLo = 0x10/4,
- IndexHi = 0x14/4,
- Data = 0x18/4,
- IndexCtl = 0x1C/4,
-
- Zoom = 0x54/4,
-};
-
-enum { /* index registers */
- CursorSyncCtl = 0x03,
- HsyncHi = 0x01,
- HsyncLo = 0x02,
- VsyncHi = 0x04,
- VsyncLo = 0x08,
-
- CursorCtl = 0x30,
- CursorXLo = 0x31,
- CursorXHi = 0x32,
- CursorYLo = 0x33,
- CursorYHi = 0x34,
- CursorHotX = 0x35,
- CursorHotY = 0x36,
-
- CursorR1 = 0x40,
- CursorG1 = 0x41,
- CursorB1 = 0x42,
- CursorR2 = 0x43,
- CursorG2 = 0x44,
- CursorB2 = 0x45,
- CursorR3 = 0x46,
- CursorG3 = 0x47,
- CursorB3 = 0x48,
-
- CursorArray = 0x100,
-
- CursorMode32x32 = 0x23,
- CursorMode64x64 = 0x27,
- CursorMode = CursorMode32x32,
-};
-
-static ulong
-t2r4linear(VGAscr* scr, int* size, int* align)
-{
- ulong aperture, oaperture;
- int oapsize, wasupamem;
- Pcidev *p;
-
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- aperture = 0;
- if(p = pcimatch(nil, 0x105D, 0)){
- switch(p->did){
- case 0x5348:
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
- break;
- default:
- break;
- }
- }
-
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
-
- return aperture;
-}
-
-static void
-t2r4enable(VGAscr* scr)
-{
- Pcidev *p;
- int size, align;
- ulong aperture, mmio;
-
- /*
- * Only once, can't be disabled for now.
- * scr->mmio holds the virtual address of
- * the MMIO registers.
- */
- if(scr->mmio)
- return;
- if(p = pcimatch(nil, 0x105D, 0)){
- switch(p->did){
- case 0x5348:
- break;
- default:
- return;
- }
- }
- else
- return;
- mmio = upamalloc(p->mem[4].bar & ~0x0F, p->mem[4].size, 0);
- if(mmio == 0)
- return;
- addvgaseg("t2r4mmio", mmio, p->mem[4].size);
-
- scr->mmio = KADDR(mmio);
-
- size = p->mem[0].size;
- align = 0;
- aperture = t2r4linear(scr, &size, &align);
- if(aperture){
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("t2r4screen", aperture, size);
- }
-}
-
-static uchar
-t2r4xi(VGAscr* scr, int index)
-{
- ulong *mmio;
-
- mmio = scr->mmio;
- mmio[IndexLo] = index & 0xFF;
- mmio[IndexHi] = (index>>8) & 0xFF;
-
- return mmio[Data];
-}
-
-static void
-t2r4xo(VGAscr* scr, int index, uchar data)
-{
- ulong *mmio;
-
- mmio = scr->mmio;
- mmio[IndexLo] = index & 0xFF;
- mmio[IndexHi] = (index>>8) & 0xFF;
-
- mmio[Data] = data;
-}
-
-static void
-t2r4curdisable(VGAscr* scr)
-{
- if(scr->mmio == 0)
- return;
- t2r4xo(scr, CursorCtl, 0x00);
-}
-
-static void
-t2r4curload(VGAscr* scr, Cursor* curs)
-{
- uchar *data;
- int size, x, y, zoom;
- ulong clr, *mmio, pixels, set;
-
- mmio = scr->mmio;
- if(mmio == 0)
- return;
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults.
- */
- t2r4xo(scr, CursorCtl, 0x00);
-
- /*
- * Set auto-increment mode for index-register addressing
- * and initialise the cursor array index.
- */
- mmio[IndexCtl] = 0x01;
- mmio[IndexLo] = CursorArray & 0xFF;
- mmio[IndexHi] = (CursorArray>>8) & 0xFF;
-
- /*
- * Initialise the cursor RAM array. There are 2 planes,
- * p0 and p1. Data is written 4 pixels per byte, with p1 the
- * MS bit of each pixel.
- * The cursor is set in X-Windows mode which gives the following
- * truth table:
- * p1 p0 colour
- * 0 0 underlying pixel colour
- * 0 1 underlying pixel colour
- * 1 0 cursor colour 1
- * 1 1 cursor colour 2
- * Put the cursor into the top-left of the array.
- *
- * Although this looks a lot like the IBM RGB524 cursor, the
- * scanlines appear to be twice as long as they should be and
- * some of the other features are missing.
- */
- if(mmio[Zoom] & 0x0F)
- zoom = 32;
- else
- zoom = 16;
- data = (uchar*)&mmio[Data];
- for(y = 0; y < zoom; y++){
- clr = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1];
- set = (curs->set[2*y]<<8)|curs->set[y*2 + 1];
- pixels = 0;
- for(x = 0; x < 16; x++){
- if(set & (1<<x))
- pixels |= 0x03<<(x*2);
- else if(clr & (1<<x))
- pixels |= 0x02<<(x*2);
- }
-
- *data = pixels>>24;
- *data = pixels>>16;
- *data = pixels>>8;
- *data = pixels;
-
- *data = 0x00;
- *data = 0x00;
- *data = 0x00;
- *data = 0x00;
-
- if(CursorMode == CursorMode32x32 && zoom == 16)
- continue;
- *data = pixels>>24;
- *data = pixels>>16;
- *data = pixels>>8;
- *data = pixels;
-
- *data = 0x00;
- *data = 0x00;
- *data = 0x00;
- *data = 0x00;
- }
- if(CursorMode == CursorMode32x32)
- size = 32;
- else
- size = 64;
- while(y < size){
- for(x = 0; x < size/8; x++){
- *data = 0x00;
- *data = 0x00;
- }
- y++;
- }
- mmio[IndexCtl] = 0x00;
-
- /*
- * Initialise the hotpoint and enable the cursor.
- */
- t2r4xo(scr, CursorHotX, -curs->offset.x);
- zoom = (scr->mmio[Zoom] & 0x0F)+1;
- t2r4xo(scr, CursorHotY, -curs->offset.y*zoom);
-
- t2r4xo(scr, CursorCtl, CursorMode);
-}
-
-static int
-t2r4curmove(VGAscr* scr, Point p)
-{
- int y, zoom;
-
- if(scr->mmio == 0)
- return 1;
-
- t2r4xo(scr, CursorXLo, p.x & 0xFF);
- t2r4xo(scr, CursorXHi, (p.x>>8) & 0x0F);
-
- zoom = (scr->mmio[Zoom] & 0x0F)+1;
- y = p.y*zoom;
- t2r4xo(scr, CursorYLo, y & 0xFF);
- t2r4xo(scr, CursorYHi, (y>>8) & 0x0F);
-
- return 0;
-}
-
-static void
-t2r4curenable(VGAscr* scr)
-{
- t2r4enable(scr);
- if(scr->mmio == 0)
- return;
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults.
- */
- t2r4xo(scr, CursorCtl, 0x00);
-
- /*
- * Cursor colour 1 (white),
- * cursor colour 2 (black).
- */
- t2r4xo(scr, CursorR1, Pwhite);
- t2r4xo(scr, CursorG1, Pwhite);
- t2r4xo(scr, CursorB1, Pwhite);
-
- t2r4xo(scr, CursorR2, Pblack);
- t2r4xo(scr, CursorG2, Pblack);
- t2r4xo(scr, CursorB2, Pblack);
-
- /*
- * Load, locate and enable the cursor, 64x64, mode 2.
- */
- t2r4curload(scr, &arrow);
- t2r4curmove(scr, ZP);
- t2r4xo(scr, CursorCtl, CursorMode);
-}
-
-enum {
- Flow = 0x08/4,
- Busy = 0x0C/4,
- BufCtl = 0x20/4,
- DeSorg = 0x28/4,
- DeDorg = 0x2C/4,
- DeSptch = 0x40/4,
- DeDptch = 0x44/4,
- CmdOpc = 0x50/4,
- CmdRop = 0x54/4,
- CmdStyle = 0x58/4,
- CmdPatrn = 0x5C/4,
- CmdClp = 0x60/4,
- CmdPf = 0x64/4,
- Fore = 0x68/4,
- Back = 0x6C/4,
- Mask = 0x70/4,
- DeKey = 0x74/4,
- Lpat = 0x78/4,
- Pctrl = 0x7C/4,
- Clptl = 0x80/4,
- Clpbr = 0x84/4,
- XY0 = 0x88/4,
- XY1 = 0x8C/4,
- XY2 = 0x90/4,
- XY3 = 0x94/4,
- XY4 = 0x98/4,
- Alpha = 0x128/4,
- ACtl = 0x16C/4,
-
- RBaseD = 0x4000/4,
-};
-
-/* wait until pipeline ready for new command */
-static void
-waitforfifo(VGAscr *scr)
-{
- int x;
- ulong *d;
- x = 0;
-
- d = scr->mmio + RBaseD;
- while((d[Busy]&1) && x++ < 1000000)
- ;
- if(x >= 1000000) /* shouldn't happen */
- iprint("busy %8lux\n", d[Busy]);
-}
-
-/* wait until command has finished executing */
-static void
-waitforcmd(VGAscr *scr)
-{
- int x;
- ulong *d;
- x = 0;
-
- d = scr->mmio + RBaseD;
- while((d[Flow]&0x1B) && x++ < 1000000)
- ;
- if(x >= 1000000) /* shouldn't happen */
- iprint("flow %8lux\n", d[Flow]);
-}
-
-/* wait until memory controller not busy (i.e. wait for writes to flush) */
-static void
-waitformem(VGAscr *scr)
-{
- int x;
- ulong *d;
- x = 0;
-
- d = scr->mmio + RBaseD;
- while((d[Flow]&2)&& x++ < 1000000)
- ;
- if(x >= 1000000) /* shouldn't happen */
- iprint("mem %8lux\n", d[Busy]);
-}
-
-static int
-t2r4hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
-{
- int ctl;
- Point dp, sp;
- ulong *d;
- int depth;
-
- if(r.min.y == sr.min.y){ /* a purely horizontal scroll */
- depth = scr->gscreen->depth;
- switch(depth){
- case 32:
- /*
- * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal
- * 32-bit scrolls don't work perfectly on rectangles of width <= 24.
- * we bail on a bigger bound for padding.
- */
- if(Dx(r) < 32)
- return 0;
- break;
- case 16:
- /*
- * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal
- * 16-bit scrolls don't work perfectly on rectangles of width <= 96.
- * we bail on a bigger bound for padding.
- */
- if(Dx(r) < 104)
- return 0;
- break;
- }
- }
- waitformem(scr);
- waitforfifo(scr);
- d = scr->mmio + RBaseD;
- ctl = 0;
- if(r.min.x <= sr.min.x){
- dp.x = r.min.x;
- sp.x = sr.min.x;
- }else{
- ctl |= 2;
- dp.x = r.max.x-1;
- sp.x = sr.max.x-1;
- }
-
- if(r.min.y < sr.min.y){
- dp.y = r.min.y;
- sp.y = sr.min.y;
- }else{
- ctl |= 1;
- dp.y = r.max.y-1;
- sp.y = sr.max.y-1;
- }
-
- d[CmdOpc] = 0x1; /* bitblt */
- d[CmdRop] = 0xC; /* copy source */
- d[CmdStyle] = 0;
- d[CmdPatrn] = 0;
- d[Fore] = 0;
- d[Back] = 0;
-
- /* writing XY1 executes cmd */
- d[XY3] = ctl;
- d[XY0] = (sp.x<<16)|sp.y;
- d[XY2] = (Dx(r)<<16)|Dy(r);
- d[XY4] = 0;
- d[XY1] = (dp.x<<16)|dp.y;
- waitforcmd(scr);
-
- return 1;
-}
-
-static int
-t2r4hwfill(VGAscr *scr, Rectangle r, ulong sval)
-{
- ulong *d;
-
- d = scr->mmio + RBaseD;
-
- waitformem(scr);
- waitforfifo(scr);
- d[CmdOpc] = 0x1; /* bitblt */
- d[CmdRop] = 0xC; /* copy source */
- d[CmdStyle] = 1; /* use source from Fore register */
- d[CmdPatrn] = 0; /* no stipple */
- d[Fore] = sval;
- d[Back] = sval;
-
- /* writing XY1 executes cmd */
- d[XY3] = 0;
- d[XY0] = (r.min.x<<16)|r.min.y;
- d[XY2] = (Dx(r)<<16)|Dy(r);
- d[XY4] = 0;
- d[XY1] = (r.min.x<<16)|r.min.y;
- waitforcmd(scr);
-
- return 1;
-}
-
-static void
-t2r4blank(VGAscr *scr, int blank)
-{
- uchar x;
-
- x = t2r4xi(scr, CursorSyncCtl);
- x &= ~0x0F;
- if(blank)
- x |= HsyncLo | VsyncLo;
- t2r4xo(scr, CursorSyncCtl, x);
-}
-
-static void
-t2r4drawinit(VGAscr *scr)
-{
- ulong pitch;
- int depth;
- int fmt;
- ulong *d;
-
- pitch = Dx(scr->gscreen->r);
- depth = scr->gscreen->depth;
-
- switch(scr->gscreen->chan){
- case RGB16:
- fmt = 3;
- break;
- case XRGB32:
- fmt = 2;
- break;
- case RGB15:
- fmt = 1;
- break;
- default:
- scr->fill = nil;
- scr->scroll = nil;
- return;
- }
-
- d = scr->mmio + RBaseD;
-
- d[BufCtl] = fmt<<24;
- d[DeSorg] = 0;
- d[DeDorg] = 0;
- d[DeSptch] = (pitch*depth)/8;
- d[DeDptch] = (pitch*depth)/8;
- d[CmdClp] = 0; /* 2 = inside rectangle */
- d[Mask] = ~0;
- d[DeKey] = 0;
- d[Clptl] = 0;
- d[Clpbr] = 0xFFF0FFF0;
- d[Alpha] = 0;
- d[ACtl] = 0;
-
- scr->fill = t2r4hwfill;
- scr->scroll = t2r4hwscroll;
- scr->blank = t2r4blank;
- hwblank = 1;
-}
-
-VGAdev vgat2r4dev = {
- "t2r4",
-
- t2r4enable,
- nil,
- nil,
- t2r4linear,
- t2r4drawinit,
-};
-
-VGAcur vgat2r4cur = {
- "t2r4hwgc",
-
- t2r4curenable,
- t2r4curdisable,
- t2r4curload,
- t2r4curmove,
-};
-
diff --git a/os/pc/vgatvp3020.c b/os/pc/vgatvp3020.c
deleted file mode 100644
index 08871d4a..00000000
--- a/os/pc/vgatvp3020.c
+++ /dev/null
@@ -1,216 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-/*
- * TVP3020 Viewpoint Video Interface Pallette.
- * Assumes hooked up to an S3 86C928.
- */
-enum {
- Index = 0x06, /* Index register */
- Data = 0x07, /* Data register */
-};
-
-/*
- * Lower 2-bits of indirect DAC register
- * addressing.
- */
-static ushort dacxreg[4] = {
- PaddrW, Pdata, Pixmask, PaddrR
-};
-
-static uchar
-tvp3020io(uchar reg, uchar data)
-{
- uchar crt55;
-
- crt55 = vgaxi(Crtx, 0x55) & 0xFC;
- vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
- vgao(dacxreg[reg & 0x03], data);
-
- return crt55;
-}
-
-static void
-tvp3020xo(uchar index, uchar data)
-{
- uchar crt55;
-
- crt55 = tvp3020io(Index, index);
- vgao(dacxreg[Data & 0x03], data);
- vgaxo(Crtx, 0x55, crt55);
-}
-
-static void
-tvp3020disable(VGAscr*)
-{
- uchar r;
-
- /*
- * Disable
- * cursor;
- * cursor control enable for Bt485 DAC (!);
- * the hardware cursor external operation mode.
- */
- tvp3020xo(0x06, 0x10); /* Cursor Control Register */
-
- r = vgaxi(Crtx, 0x45) & ~0x20;
- vgaxo(Crtx, 0x45, r);
-
- r = vgaxi(Crtx, 0x55) & ~0x20;
- vgaxo(Crtx, 0x55, r);
-}
-
-static void
-tvp3020enable(VGAscr*)
-{
- uchar r;
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults + X-Windows cursor mode.
- */
- tvp3020xo(0x06, 0x10); /* Cursor Control Register */
-
- /*
- * Overscan colour,
- * cursor colour 1 (white),
- * cursor colour 2 (black).
- */
- tvp3020xo(0x20, Pwhite); tvp3020xo(0x21, Pwhite); tvp3020xo(0x22, Pwhite);
- tvp3020xo(0x23, Pwhite); tvp3020xo(0x24, Pwhite); tvp3020xo(0x25, Pwhite);
- tvp3020xo(0x26, Pblack); tvp3020xo(0x27, Pblack); tvp3020xo(0x28, Pblack);
-
- /*
- * Finally, enable
- * the hardware cursor external operation mode;
- * cursor control enable for Bt485 DAC (!).
- */
- r = vgaxi(Crtx, 0x55)|0x20;
- vgaxo(Crtx, 0x55, r);
-
- r = vgaxi(Crtx, 0x45)|0x20;
- vgaxo(Crtx, 0x45, r);
-}
-
-static void
-tvp3020load(VGAscr*, Cursor* curs)
-{
- uchar p, p0, p1;
- int x, y;
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults + X-Windows cursor mode.
- */
- tvp3020xo(0x06, 0x10); /* Cursor Control Register */
-
- /*
- * Initialise the cursor RAM LS and MS address
- * (LS must be first).
- */
- tvp3020xo(0x08, 0x00); /* Cursor RAM LS Address */
- tvp3020xo(0x09, 0x00); /* Cursor RAM MS Address */
-
- /*
- * Initialise the 64x64 cursor RAM array. There are 2 planes,
- * p0 and p1. Data is written 4 pixels per byte, with p1 the
- * MS bit of each pixel.
- * The cursor is set in X-Windows mode which gives the following
- * truth table:
- * p1 p0 colour
- * 0 0 underlying pixel colour
- * 0 1 underlying pixel colour
- * 1 0 cursor colour 1
- * 1 1 cursor colour 2
- * Put the cursor into the top-left of the 64x64 array.
- */
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16){
- p0 = curs->clr[x+y*2];
- p1 = curs->set[x+y*2];
-
- p = 0x00;
- if(p1 & 0x10)
- p |= 0x03;
- else if(p0 & 0x10)
- p |= 0x02;
- if(p1 & 0x20)
- p |= 0x0C;
- else if(p0 & 0x20)
- p |= 0x08;
- if(p1 & 0x40)
- p |= 0x30;
- else if(p0 & 0x40)
- p |= 0x20;
- if(p1 & 0x80)
- p |= 0xC0;
- else if(p0 & 0x80)
- p |= 0x80;
- tvp3020xo(0x0A, p); /* Cursor RAM Data */
-
- p = 0x00;
- if(p1 & 0x01)
- p |= 0x03;
- else if(p0 & 0x01)
- p |= 0x02;
- if(p1 & 0x02)
- p |= 0x0C;
- else if(p0 & 0x02)
- p |= 0x08;
- if(p1 & 0x04)
- p |= 0x30;
- else if(p0 & 0x04)
- p |= 0x20;
- if(p1 & 0x08)
- p |= 0xC0;
- else if(p0 & 0x08)
- p |= 0x80;
- tvp3020xo(0x0A, p); /* Cursor RAM Data */
- }
- else{
- tvp3020xo(0x0A, 0x00); /* Cursor RAM Data */
- tvp3020xo(0x0A, 0x00);
- }
- }
- }
-
- /*
- * Initialise the cursor hotpoint
- * and enable the cursor.
- */
- tvp3020xo(0x04, -curs->offset.x); /* Sprite Origin X */
- tvp3020xo(0x05, -curs->offset.y); /* Sprite Origin Y */
-
- tvp3020xo(0x06, 0x40|0x10); /* Cursor Control Register */
-}
-
-static int
-tvp3020move(VGAscr*, Point p)
-{
- tvp3020xo(0x00, p.x & 0xFF); /* Cursor Position X LSB */
- tvp3020xo(0x01, (p.x>>8) & 0x0F); /* Cursor Position X MSB */
- tvp3020xo(0x02, p.y & 0xFF); /* Cursor Position Y LSB */
- tvp3020xo(0x03, (p.y>>8) & 0x0F); /* Cursor Position Y MSB */
-
- return 0;
-}
-
-VGAcur vgatvp3020cur = {
- "tvp3020hwgc",
-
- tvp3020enable,
- tvp3020disable,
- tvp3020load,
- tvp3020move,
-};
diff --git a/os/pc/vgatvp3026.c b/os/pc/vgatvp3026.c
deleted file mode 100644
index 1b97d1bf..00000000
--- a/os/pc/vgatvp3026.c
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-/*
- * TVP3026 Viewpoint Video Interface Pallette.
- * Assumes hooked up to an S3 Vision968.
- */
-enum {
- Index = 0x00, /* Index */
- Data = 0x0A, /* Data */
-
- CaddrW = 0x04, /* Colour Write Address */
- Cdata = 0x05, /* Colour Data */
-
- Cctl = 0x09, /* Direct Cursor Control */
- Cram = 0x0B, /* Cursor Ram Data */
- Cxlsb = 0x0C, /* Cursor X LSB */
- Cxmsb = 0x0D, /* Cursor X MSB */
- Cylsb = 0x0E, /* Cursor Y LSB */
- Cymsb = 0x0F, /* Cursor Y MSB */
-
- Icctl = 0x06, /* Indirect Cursor Control */
-};
-
-/*
- * Lower 2-bits of indirect DAC register
- * addressing.
- */
-static ushort dacxreg[4] = {
- PaddrW, Pdata, Pixmask, PaddrR
-};
-
-static uchar
-tvp3026io(uchar reg, uchar data)
-{
- uchar crt55;
-
- crt55 = vgaxi(Crtx, 0x55) & 0xFC;
- vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
- vgao(dacxreg[reg & 0x03], data);
-
- return crt55;
-}
-
-static void
-tvp3026o(uchar reg, uchar data)
-{
- uchar crt55;
-
- crt55 = tvp3026io(reg, data);
- vgaxo(Crtx, 0x55, crt55);
-}
-
-void
-tvp3026xo(uchar index, uchar data)
-{
- uchar crt55;
-
- crt55 = tvp3026io(Index, index);
- vgaxo(Crtx, 0x55, crt55|((Data>>2) & 0x03));
- vgao(dacxreg[Data & 0x03], data);
- vgaxo(Crtx, 0x55, crt55);
-}
-
-static void
-tvp3026disable(VGAscr*)
-{
- tvp3026xo(Icctl, 0x90);
- tvp3026o(Cctl, 0x00);
-}
-
-static void
-tvp3026enable(VGAscr*)
-{
- /*
- * Make sure cursor is off and direct control enabled.
- */
- tvp3026xo(Icctl, 0x90);
- tvp3026o(Cctl, 0x00);
-
- /*
- * Overscan colour,
- * cursor colour 1 (white),
- * cursor colour 2, 3 (black).
- */
- tvp3026o(CaddrW, 0x00);
- tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite);
- tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite);
- tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack);
- tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack);
-
- /*
- * Enable the cursor in 3-colour mode.
- */
- tvp3026o(Cctl, 0x01);
-}
-
-static void
-tvp3026load(VGAscr* scr, Cursor* curs)
-{
- int x, y;
-
- /*
- * Make sure cursor is off by initialising the cursor
- * control to defaults.
- * Write to the indirect control register to make sure
- * direct register is enabled and upper 2 bits of cursor
- * RAM address are 0.
- * The LSBs of the cursor RAM address are in PaddrW.
- */
- tvp3026xo(Icctl, 0x90);
- tvp3026o(Cctl, 0x00);
- vgao(PaddrW, 0x00);
-
- /*
- * Initialise the 64x64 cursor RAM array. There are 2 planes,
- * p0 and p1. Data is written 8 pixels per byte, with p0 in the
- * first 512 bytes of the array and p1 in the second.
- * The cursor is set in 3-colour mode which gives the following
- * truth table:
- * p1 p0 colour
- * 0 0 transparent
- * 0 1 cursor colour 0
- * 1 0 cursor colour 1
- * 1 1 cursor colour 2
- * Put the cursor into the top-left of the 64x64 array.
- * The 0,0 cursor point is bottom-right, so positioning will
- * have to take that into account.
- */
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16)
- tvp3026o(Cram, curs->clr[x+y*2]);
- else
- tvp3026o(Cram, 0x00);
- }
- }
- for(y = 0; y < 64; y++){
- for(x = 0; x < 64/8; x++){
- if(x < 16/8 && y < 16)
- tvp3026o(Cram, curs->set[x+y*2]);
- else
- tvp3026o(Cram, 0x00);
- }
- }
-
- /*
- * Initialise the cursor hotpoint
- * and enable the cursor in 3-colour mode.
- */
- scr->offset.x = 64+curs->offset.x;
- scr->offset.y = 64+curs->offset.y;
- tvp3026o(Cctl, 0x01);
-}
-
-static int
-tvp3026move(VGAscr* scr, Point p)
-{
- int x, y;
-
- x = p.x+scr->offset.x;
- y = p.y+scr->offset.y;
-
- tvp3026o(Cxlsb, x & 0xFF);
- tvp3026o(Cxmsb, (x>>8) & 0x0F);
- tvp3026o(Cylsb, y & 0xFF);
- tvp3026o(Cymsb, (y>>8) & 0x0F);
-
- return 0;
-}
-
-VGAcur vgatvp3026cur = {
- "tvp3026hwgc",
-
- tvp3026enable,
- tvp3026disable,
- tvp3026load,
- tvp3026move,
-};
diff --git a/os/pc/vgavmware.c b/os/pc/vgavmware.c
deleted file mode 100644
index 4cf09e48..00000000
--- a/os/pc/vgavmware.c
+++ /dev/null
@@ -1,386 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum {
- PCIVMWARE = 0x15AD, /* PCI VID */
-
- VMWARE1 = 0x0710, /* PCI DID */
- VMWARE2 = 0x0405,
-};
-
-enum {
- Rid = 0,
- Renable,
- Rwidth,
- Rheight,
- Rmaxwidth,
-
- Rmaxheight,
- Rdepth,
- Rbpp,
- Rpseudocolor,
- Rrmask,
-
- Rgmask,
- Rbmask,
- Rbpl,
- Rfbstart,
- Rfboffset,
-
- Rfbmaxsize,
- Rfbsize,
- Rcap,
- Rmemstart,
- Rmemsize,
-
- Rconfigdone,
- Rsync,
- Rbusy,
- Rguestid,
- Rcursorid,
-
- Rcursorx,
- Rcursory,
- Rcursoron,
- Nreg,
-
- Crectfill = 1<<0,
- Crectcopy = 1<<1,
- Crectpatfill = 1<<2,
- Coffscreen = 1<<3,
- Crasterop = 1<<4,
- Ccursor = 1<<5,
- Ccursorbypass = 1<<6,
- Ccursorbypass2 = 1<<7,
- C8bitemulation = 1<<8,
- Calphacursor = 1<<9,
-
- FifoMin = 0,
- FifoMax = 1,
- FifoNextCmd = 2,
- FifoStop = 3,
- FifoUser = 4,
-
- Xupdate = 1,
- Xrectfill = 2,
- Xrectcopy = 3,
- Xdefinebitmap = 4,
- Xdefinebitmapscanline = 5,
- Xdefinepixmap = 6,
- Xdefinepixmapscanline = 7,
- Xrectbitmapfill = 8,
- Xrectpixmapfill = 9,
- Xrectbitmapcopy = 10,
- Xrectpixmapcopy = 11,
- Xfreeobject = 12,
- Xrectropfill = 13,
- Xrectropcopy = 14,
- Xrectropbitmapfill = 15,
- Xrectroppixmapfill = 16,
- Xrectropbitmapcopy = 17,
- Xrectroppixmapcopy = 18,
- Xdefinecursor = 19,
- Xdisplaycursor = 20,
- Xmovecursor = 21,
- Xdefinealphacursor = 22,
- Xcmdmax = 23,
-
- CursorOnHide = 0,
- CursorOnShow = 1,
- CursorOnRemoveFromFb = 2,
- CursorOnRestoreToFb = 3,
-
- Rpalette = 1024,
-};
-
-typedef struct Vmware Vmware;
-struct Vmware {
- ulong fb;
-
- ulong ra;
- ulong rd;
-
- ulong r[Nreg];
- ulong *mmio;
- ulong mmiosize;
-
- char chan[32];
- int depth;
-};
-
-Vmware xvm;
-Vmware *vm=&xvm;
-
-static ulong
-vmrd(Vmware *vm, int i)
-{
- outl(vm->ra, i);
- return inl(vm->rd);
-}
-
-static void
-vmwr(Vmware *vm, int i, ulong v)
-{
- outl(vm->ra, i);
- outl(vm->rd, v);
-}
-
-static void
-vmwait(Vmware *vm)
-{
- vmwr(vm, Rsync, 1);
- while(vmrd(vm, Rbusy))
- ;
-}
-
-static ulong
-vmwarelinear(VGAscr* scr, int* size, int* align)
-{
- char err[64];
- ulong aperture, oaperture;
- int osize, oapsize, wasupamem;
- Pcidev *p;
-
- osize = *size;
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
-
- p = pcimatch(nil, PCIVMWARE, 0);
- if(p == nil)
- error("no vmware card found");
-
- switch(p->did){
- default:
- snprint(err, sizeof err, "unknown vmware id %.4ux", p->did);
- error(err);
-
- case VMWARE1:
- vm->ra = 0x4560;
- vm->rd = 0x4560+4;
- break;
-
- case VMWARE2:
- vm->ra = p->mem[0].bar&~3;
- vm->rd = vm->ra + 1;
- }
-
- aperture = (ulong)(vmrd(vm, Rfbstart));
- *size = vmrd(vm, Rfbsize);
-
- if(wasupamem)
- upafree(oaperture, oapsize);
- scr->isupamem = 0;
-
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0))
- scr->isupamem = 1;
- }else
- scr->isupamem = 1;
-
- if(oaperture && aperture != oaperture)
- print("warning (BUG): redefinition of aperture does not change vmwarescreen segment\n");
- addvgaseg("vmwarescreen", aperture, osize);
-
- return aperture;
-}
-
-static void
-vmfifowr(Vmware *vm, ulong v)
-{
- ulong *mm;
-
- mm = vm->mmio;
- if(mm == nil){
- iprint("!");
- return;
- }
-
- if(mm[FifoNextCmd]+sizeof(ulong) == mm[FifoStop]
- || (mm[FifoNextCmd]+sizeof(ulong) == mm[FifoMax]
- && mm[FifoStop] == mm[FifoMin]))
- vmwait(vm);
-
- mm[mm[FifoNextCmd]/sizeof(ulong)] = v;
-
- /* must do this way so mm[FifoNextCmd] is never mm[FifoMax] */
- v = mm[FifoNextCmd] + sizeof(ulong);
- if(v == mm[FifoMax])
- v = mm[FifoMin];
- mm[FifoNextCmd] = v;
-}
-
-static void
-vmwareflush(VGAscr*, Rectangle r)
-{
- if(vm->mmio == nil)
- return;
-
- vmfifowr(vm, Xupdate);
- vmfifowr(vm, r.min.x);
- vmfifowr(vm, r.min.y);
- vmfifowr(vm, r.max.x-r.min.x);
- vmfifowr(vm, r.max.y-r.min.y);
- vmwait(vm);
-}
-
-static void
-vmwareload(VGAscr*, Cursor *c)
-{
- int i;
- ulong clr, set;
- ulong and[16];
- ulong xor[16];
-
- if(vm->mmio == nil)
- return;
- vmfifowr(vm, Xdefinecursor);
- vmfifowr(vm, 1); /* cursor id */
- vmfifowr(vm, -c->offset.x);
- vmfifowr(vm, -c->offset.y);
-
- vmfifowr(vm, 16); /* width */
- vmfifowr(vm, 16); /* height */
- vmfifowr(vm, 1); /* depth for and mask */
- vmfifowr(vm, 1); /* depth for xor mask */
-
- for(i=0; i<16; i++){
- clr = (c->clr[i*2+1]<<8) | c->clr[i*2];
- set = (c->set[i*2+1]<<8) | c->set[i*2];
- and[i] = ~(clr|set); /* clr and set pixels => black */
- xor[i] = clr&~set; /* clr pixels => white */
- }
- for(i=0; i<16; i++)
- vmfifowr(vm, and[i]);
- for(i=0; i<16; i++)
- vmfifowr(vm, xor[i]);
-
- vmwait(vm);
-}
-
-static int
-vmwaremove(VGAscr*, Point p)
-{
- vmwr(vm, Rcursorid, 1);
- vmwr(vm, Rcursorx, p.x);
- vmwr(vm, Rcursory, p.y);
- vmwr(vm, Rcursoron, CursorOnShow);
- return 0;
-}
-
-static void
-vmwaredisable(VGAscr*)
-{
- vmwr(vm, Rcursorid, 1);
- vmwr(vm, Rcursoron, CursorOnHide);
-}
-
-static void
-vmwareenable(VGAscr*)
-{
- vmwr(vm, Rcursorid, 1);
- vmwr(vm, Rcursoron, CursorOnShow);
-}
-
-static void
-vmwareblank(int)
-{
-}
-
-static int
-vmwarescroll(VGAscr*, Rectangle r, Rectangle sr)
-{
- if(vm->mmio == nil)
- return 0;
- vmfifowr(vm, Xrectcopy);
- vmfifowr(vm, sr.min.x);
- vmfifowr(vm, sr.min.y);
- vmfifowr(vm, r.min.x);
- vmfifowr(vm, r.min.y);
- vmfifowr(vm, Dx(r));
- vmfifowr(vm, Dy(r));
- vmwait(vm);
- return 1;
-}
-
-static int
-vmwarefill(VGAscr*, Rectangle r, ulong sval)
-{
- if(vm->mmio == nil)
- return 0;
- vmfifowr(vm, Xrectfill);
- vmfifowr(vm, sval);
- vmfifowr(vm, r.min.x);
- vmfifowr(vm, r.min.y);
- vmfifowr(vm, r.max.x-r.min.x);
- vmfifowr(vm, r.max.y-r.min.y);
- vmwait(vm);
- return 1;
-}
-
-static void
-vmwaredrawinit(VGAscr *scr)
-{
- ulong offset;
- ulong mmiobase, mmiosize;
-
- if(scr->mmio==nil){
- mmiobase = vmrd(vm, Rmemstart);
- if(mmiobase == 0)
- return;
- mmiosize = vmrd(vm, Rmemsize);
- scr->mmio = KADDR(upamalloc(mmiobase, mmiosize, 0));
- vm->mmio = scr->mmio;
- vm->mmiosize = mmiosize;
- if(scr->mmio == nil)
- return;
- addvgaseg("vmwaremmio", mmiobase, mmiosize);
- }
-
- scr->mmio[FifoMin] = 4*sizeof(ulong);
- scr->mmio[FifoMax] = vm->mmiosize;
- scr->mmio[FifoNextCmd] = 4*sizeof(ulong);
- scr->mmio[FifoStop] = 4*sizeof(ulong);
- vmwr(vm, Rconfigdone, 1);
-
- scr->scroll = vmwarescroll;
- scr->fill = vmwarefill;
-
- offset = vmrd(vm, Rfboffset);
- scr->gscreendata->bdata += offset;
-}
-
-VGAdev vgavmwaredev = {
- "vmware",
-
- 0,
- 0,
- 0,
- vmwarelinear,
- vmwaredrawinit,
- 0,
- 0,
- 0,
- vmwareflush,
-};
-
-VGAcur vgavmwarecur = {
- "vmwarehwgc",
-
- vmwareenable,
- vmwaredisable,
- vmwareload,
- vmwaremove,
-};
diff --git a/os/pc/vgax.c b/os/pc/vgax.c
deleted file mode 100644
index c765508e..00000000
--- a/os/pc/vgax.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static Lock vgaxlock; /* access to index registers */
-
-int
-vgaxi(long port, uchar index)
-{
- uchar data;
-
- ilock(&vgaxlock);
- switch(port){
-
- case Seqx:
- case Crtx:
- case Grx:
- outb(port, index);
- data = inb(port+1);
- break;
-
- case Attrx:
- /*
- * Allow processor access to the colour
- * palette registers. Writes to Attrx must
- * be preceded by a read from Status1 to
- * initialise the register to point to the
- * index register and not the data register.
- * Processor access is allowed by turning
- * off bit 0x20.
- */
- inb(Status1);
- if(index < 0x10){
- outb(Attrx, index);
- data = inb(Attrx+1);
- inb(Status1);
- outb(Attrx, 0x20|index);
- }
- else{
- outb(Attrx, 0x20|index);
- data = inb(Attrx+1);
- }
- break;
-
- default:
- iunlock(&vgaxlock);
- return -1;
- }
- iunlock(&vgaxlock);
-
- return data & 0xFF;
-}
-
-int
-vgaxo(long port, uchar index, uchar data)
-{
- ilock(&vgaxlock);
- switch(port){
-
- case Seqx:
- case Crtx:
- case Grx:
- /*
- * We could use an outport here, but some chips
- * (e.g. 86C928) have trouble with that for some
- * registers.
- */
- outb(port, index);
- outb(port+1, data);
- break;
-
- case Attrx:
- inb(Status1);
- if(index < 0x10){
- outb(Attrx, index);
- outb(Attrx, data);
- inb(Status1);
- outb(Attrx, 0x20|index);
- }
- else{
- outb(Attrx, 0x20|index);
- outb(Attrx, data);
- }
- break;
-
- default:
- iunlock(&vgaxlock);
- return -1;
- }
- iunlock(&vgaxlock);
-
- return 0;
-}
diff --git a/os/pc/wavelan.c b/os/pc/wavelan.c
deleted file mode 100644
index 0916f460..00000000
--- a/os/pc/wavelan.c
+++ /dev/null
@@ -1,1268 +0,0 @@
-/*
- Lucent Wavelan IEEE 802.11 pcmcia.
- There is almost no documentation for the card.
- the driver is done using both the FreeBSD, Linux and
- original Plan 9 drivers as `documentation'.
-
- Has been used with the card plugged in during all up time.
- no cards removals/insertions yet.
-
- For known BUGS see the comments below. Besides,
- the driver keeps interrupts disabled for just too
- long. When it gets robust, locks should be revisited.
-
- BUGS: check endian, alignment and mem/io issues;
- multicast;
- receive watchdog interrupts.
- TODO: automatic power management;
- improve locking.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-#include "etherif.h"
-#include "wavelan.h"
-
-enum
-{
- MSperTick= 50, /* ms between ticks of kproc */
-};
-
-/*
- * When we're using a PCI device and memory-mapped I/O,
- * the registers are spaced out as though each takes 32 bits,
- * even though they are only 16-bit registers. Thus,
- * ctlr->mmb[reg] is the right way to access register reg,
- * even though a priori you'd expect to use ctlr->mmb[reg/2].
- */
-void
-csr_outs(Ctlr *ctlr, int reg, ushort arg)
-{
- if(ctlr->mmb)
- ctlr->mmb[reg] = arg;
- else
- outs(ctlr->iob+reg, arg);
-}
-
-ushort
-csr_ins(Ctlr *ctlr, int reg)
-{
- if(ctlr->mmb)
- return ctlr->mmb[reg];
- else
- return ins(ctlr->iob+reg);
-}
-
-static void
-csr_ack(Ctlr *ctlr, int ev)
-{
- csr_outs(ctlr, WR_EvAck, ev);
-}
-
-static void
-csr_inss(Ctlr *ctlr, int reg, void *dat, int ndat)
-{
- ushort *rp, *wp;
-
- if(ctlr->mmb){
- rp = &ctlr->mmb[reg];
- wp = dat;
- while(ndat-- > 0)
- *wp++ = *rp;
- }else
- inss(ctlr->iob+reg, dat, ndat);
-}
-
-static void
-csr_outss(Ctlr *ctlr, int reg, void *dat, int ndat)
-{
- ushort *rp, *wp;
-
- if(ctlr->mmb){
- rp = dat;
- wp = &ctlr->mmb[reg];
- while(ndat-- > 0)
- *wp = *rp++;
- }else
- outss(ctlr->iob+reg, dat, ndat);
-}
-
-// w_... routines do not ilock the Ctlr and should
-// be called locked.
-
-void
-w_intdis(Ctlr* ctlr)
-{
- csr_outs(ctlr, WR_IntEna, 0);
- csr_ack(ctlr, 0xffff);
-}
-
-static void
-w_intena(Ctlr* ctlr)
-{
- csr_outs(ctlr, WR_IntEna, WEvs);
-}
-
-int
-w_cmd(Ctlr *ctlr, ushort cmd, ushort arg)
-{
- int i, rc;
-
- for(i=0; i<WTmOut; i++)
- if((csr_ins(ctlr, WR_Cmd)&WCmdBusy) == 0)
- break;
- if(i==WTmOut){
- print("#l%d: issuing cmd %.4ux: %.4ux\n", ctlr->ctlrno, cmd, csr_ins(ctlr, WR_Cmd));
- return -1;
- }
-
- csr_outs(ctlr, WR_Parm0, arg);
- csr_outs(ctlr, WR_Cmd, cmd);
-
- for(i=0; i<WTmOut; i++)
- if(csr_ins(ctlr, WR_EvSts)&WCmdEv)
- break;
- if(i==WTmOut){
- /*
- * WCmdIni can take a really long time.
- */
- enum { IniTmOut = 2000 };
- for(i=0; i<IniTmOut; i++){
- if(csr_ins(ctlr, WR_EvSts)&WCmdEv)
- break;
- microdelay(100);
- }
- if(i < IniTmOut)
- if(0) print("#l%d: long cmd %.4ux %d\n", ctlr->ctlrno, cmd, i);
- if(i == IniTmOut){
- print("#l%d: execing cmd %.4ux: %.4ux\n", ctlr->ctlrno, cmd, csr_ins(ctlr, WR_EvSts));
- return -1;
- }
- }
- rc = csr_ins(ctlr, WR_Sts);
- csr_ack(ctlr, WCmdEv);
-
- if((rc&WCmdMsk) != (cmd&WCmdMsk)){
- print("#l%d: cmd %.4ux: status %.4ux\n", ctlr->ctlrno, cmd, rc);
- return -1;
- }
- if(rc&WResSts){
- /*
- * Don't print; this happens on every WCmdAccWr for some reason.
- */
- if(0) print("#l%d: cmd %.4ux: status %.4ux\n", ctlr->ctlrno, cmd, rc);
- return -1;
- }
- return 0;
-}
-
-static int
-w_seek(Ctlr* ctlr, ushort id, ushort offset, int chan)
-{
- int i, rc;
- static ushort sel[] = { WR_Sel0, WR_Sel1 };
- static ushort off[] = { WR_Off0, WR_Off1 };
-
- if(chan != 0 && chan != 1)
- panic("wavelan: bad chan\n");
- csr_outs(ctlr, sel[chan], id);
- csr_outs(ctlr, off[chan], offset);
- for (i=0; i<WTmOut; i++){
- rc = csr_ins(ctlr, off[chan]);
- if((rc & (WBusyOff|WErrOff)) == 0)
- return 0;
- }
- return -1;
-}
-
-int
-w_inltv(Ctlr* ctlr, Wltv* ltv)
-{
- int len;
- ushort code;
-
- if(w_cmd(ctlr, WCmdAccRd, ltv->type)){
- DEBUG("wavelan: access read failed\n");
- return -1;
- }
- if(w_seek(ctlr,ltv->type,0,1)){
- DEBUG("wavelan: seek failed\n");
- return -1;
- }
- len = csr_ins(ctlr, WR_Data1);
- if(len > ltv->len)
- return -1;
- ltv->len = len;
- if((code=csr_ins(ctlr, WR_Data1)) != ltv->type){
- USED(code);
- DEBUG("wavelan: type %x != code %x\n",ltv->type,code);
- return -1;
- }
- if(ltv->len > 0)
- csr_inss(ctlr, WR_Data1, &ltv->val, ltv->len-1);
-
- return 0;
-}
-
-static void
-w_outltv(Ctlr* ctlr, Wltv* ltv)
-{
- if(w_seek(ctlr,ltv->type, 0, 1))
- return;
- csr_outss(ctlr, WR_Data1, ltv, ltv->len+1);
- w_cmd(ctlr, WCmdAccWr, ltv->type);
-}
-
-void
-ltv_outs(Ctlr* ctlr, int type, ushort val)
-{
- Wltv ltv;
-
- ltv.len = 2;
- ltv.type = type;
- ltv.val = val;
- w_outltv(ctlr, &ltv);
-}
-
-int
-ltv_ins(Ctlr* ctlr, int type)
-{
- Wltv ltv;
-
- ltv.len = 2;
- ltv.type = type;
- ltv.val = 0;
- if(w_inltv(ctlr, &ltv))
- return -1;
- return ltv.val;
-}
-
-static void
-ltv_outstr(Ctlr* ctlr, int type, char* val)
-{
- Wltv ltv;
- int len;
-
- len = strlen(val);
- if(len > sizeof(ltv.s))
- len = sizeof(ltv.s);
- memset(&ltv, 0, sizeof(ltv));
- ltv.len = (sizeof(ltv.type)+sizeof(ltv.slen)+sizeof(ltv.s))/2;
- ltv.type = type;
-
-// This should be ltv.slen = len; according to Axel Belinfante
- ltv.slen = len;
-
- strncpy(ltv.s, val, len);
- w_outltv(ctlr, &ltv);
-}
-
-static char Unkname[] = "who knows";
-static char Nilname[] = "card does not tell";
-
-static char*
-ltv_inname(Ctlr* ctlr, int type)
-{
- static Wltv ltv;
- int len;
-
- memset(&ltv,0,sizeof(ltv));
- ltv.len = WNameLen/2+2;
- ltv.type = type;
- if(w_inltv(ctlr, &ltv))
- return Unkname;
- len = ltv.slen;
- if(len == 0 || ltv.s[0] == 0)
- return Nilname;
- if(len >= sizeof ltv.s)
- len = sizeof ltv.s - 1;
- ltv.s[len] = '\0';
- return ltv.s;
-}
-
-static int
-w_read(Ctlr* ctlr, int type, int off, void* buf, ulong len)
-{
- if(w_seek(ctlr, type, off, 1)){
- DEBUG("wavelan: w_read: seek failed");
- return 0;
- }
- csr_inss(ctlr, WR_Data1, buf, len/2);
-
- return len;
-}
-
-static int
-w_write(Ctlr* ctlr, int type, int off, void* buf, ulong len)
-{
- int tries;
-
- for (tries=0; tries < WTmOut; tries++){
- if(w_seek(ctlr, type, off, 0)){
- DEBUG("wavelan: w_write: seek failed\n");
- return 0;
- }
-
- csr_outss(ctlr, WR_Data0, buf, len/2);
-
- csr_outs(ctlr, WR_Data0, 0xdead);
- csr_outs(ctlr, WR_Data0, 0xbeef);
- if(w_seek(ctlr, type, off + len, 0)){
- DEBUG("wavelan: write seek failed\n");
- return 0;
- }
- if(csr_ins(ctlr, WR_Data0) == 0xdead)
- if(csr_ins(ctlr, WR_Data0) == 0xbeef)
- return len;
- DEBUG("wavelan: Hermes bug byte.\n");
- return 0;
- }
- DEBUG("wavelan: tx timeout\n");
- return 0;
-}
-
-static int
-w_alloc(Ctlr* ctlr, int len)
-{
- int rc;
- int i,j;
-
- if(w_cmd(ctlr, WCmdMalloc, len)==0)
- for (i = 0; i<WTmOut; i++)
- if(csr_ins(ctlr, WR_EvSts) & WAllocEv){
- csr_ack(ctlr, WAllocEv);
- rc=csr_ins(ctlr, WR_Alloc);
- if(w_seek(ctlr, rc, 0, 0))
- return -1;
- len = len/2;
- for (j=0; j<len; j++)
- csr_outs(ctlr, WR_Data0, 0);
- return rc;
- }
- return -1;
-}
-
-static int
-w_enable(Ether* ether)
-{
- Wltv ltv;
- Ctlr* ctlr = (Ctlr*) ether->ctlr;
-
- if(!ctlr)
- return -1;
-
- w_intdis(ctlr);
- w_cmd(ctlr, WCmdDis, 0);
- w_intdis(ctlr);
- if(w_cmd(ctlr, WCmdIni, 0))
- return -1;
- w_intdis(ctlr);
-
- ltv_outs(ctlr, WTyp_Tick, 8);
- ltv_outs(ctlr, WTyp_MaxLen, ctlr->maxlen);
- ltv_outs(ctlr, WTyp_Ptype, ctlr->ptype);
- ltv_outs(ctlr, WTyp_CreateIBSS, ctlr->createibss);
- ltv_outs(ctlr, WTyp_RtsThres, ctlr->rtsthres);
- ltv_outs(ctlr, WTyp_TxRate, ctlr->txrate);
- ltv_outs(ctlr, WTyp_ApDens, ctlr->apdensity);
- ltv_outs(ctlr, WTyp_PMWait, ctlr->pmwait);
- ltv_outs(ctlr, WTyp_PM, ctlr->pmena);
- if(*ctlr->netname)
- ltv_outstr(ctlr, WTyp_NetName, ctlr->netname);
- if(*ctlr->wantname)
- ltv_outstr(ctlr, WTyp_WantName, ctlr->wantname);
- ltv_outs(ctlr, WTyp_Chan, ctlr->chan);
- if(*ctlr->nodename)
- ltv_outstr(ctlr, WTyp_NodeName, ctlr->nodename);
- ltv.len = 4;
- ltv.type = WTyp_Mac;
- memmove(ltv.addr, ether->ea, Eaddrlen);
- w_outltv(ctlr, &ltv);
-
- ltv_outs(ctlr, WTyp_Prom, (ether->prom?1:0));
-
- if(ctlr->hascrypt && ctlr->crypt){
- ltv_outs(ctlr, WTyp_Crypt, ctlr->crypt);
- ltv_outs(ctlr, WTyp_TxKey, ctlr->txkey);
- w_outltv(ctlr, &ctlr->keys);
- ltv_outs(ctlr, WTyp_XClear, ctlr->xclear);
- }
-
- // BUG: set multicast addresses
-
- if(w_cmd(ctlr, WCmdEna, 0)){
- DEBUG("wavelan: Enable failed");
- return -1;
- }
- ctlr->txdid = w_alloc(ctlr, 1518 + sizeof(WFrame) + 8);
- ctlr->txmid = w_alloc(ctlr, 1518 + sizeof(WFrame) + 8);
- if(ctlr->txdid == -1 || ctlr->txmid == -1)
- DEBUG("wavelan: alloc failed");
- ctlr->txbusy = 0;
- w_intena(ctlr);
- return 0;
-}
-
-static void
-w_rxdone(Ether* ether)
-{
- Ctlr* ctlr = (Ctlr*) ether->ctlr;
- int len, sp;
- WFrame f;
- Block* bp=0;
- Etherpkt* ep;
-
- sp = csr_ins(ctlr, WR_RXId);
- len = w_read(ctlr, sp, 0, &f, sizeof(f));
- if(len == 0){
- DEBUG("wavelan: read frame error\n");
- goto rxerror;
- }
- if(f.sts&WF_Err){
- goto rxerror;
- }
- switch(f.sts){
- case WF_1042:
- case WF_Tunnel:
- case WF_WMP:
- len = f.dlen + WSnapHdrLen;
- bp = iallocb(ETHERHDRSIZE + len + 2);
- if(!bp)
- goto rxerror;
- ep = (Etherpkt*) bp->wp;
- memmove(ep->d, f.addr1, Eaddrlen);
- memmove(ep->s, f.addr2, Eaddrlen);
- memmove(ep->type,&f.type,2);
- bp->wp += ETHERHDRSIZE;
- if(w_read(ctlr, sp, WF_802_11_Off, bp->wp, len+2) == 0){
- DEBUG("wavelan: read 802.11 error\n");
- goto rxerror;
- }
- bp->wp = bp->rp+(ETHERHDRSIZE+f.dlen);
- break;
- default:
- len = ETHERHDRSIZE + f.dlen + 2;
- bp = iallocb(len);
- if(!bp)
- goto rxerror;
- if(w_read(ctlr, sp, WF_802_3_Off, bp->wp, len) == 0){
- DEBUG("wavelan: read 800.3 error\n");
- goto rxerror;
- }
- bp->wp += len;
- }
-
- ctlr->nrx++;
- etheriq(ether,bp,1);
- ctlr->signal = ((ctlr->signal*15)+((f.qinfo>>8) & 0xFF))/16;
- ctlr->noise = ((ctlr->noise*15)+(f.qinfo & 0xFF))/16;
- return;
-
-rxerror:
- freeb(bp);
- ctlr->nrxerr++;
-}
-
-static void
-w_txstart(Ether* ether)
-{
- Etherpkt *pkt;
- Ctlr *ctlr;
- Block *bp;
- int len, off;
-
- if((ctlr = ether->ctlr) == nil || (ctlr->state & (Attached|Power)) != (Attached|Power) || ctlr->txbusy)
- return;
-
- if((bp = qget(ether->oq)) == nil)
- return;
- pkt = (Etherpkt*)bp->rp;
-
- //
- // If the packet header type field is > 1500 it is an IP or
- // ARP datagram, otherwise it is an 802.3 packet. See RFC1042.
- //
- memset(&ctlr->txf, 0, sizeof(ctlr->txf));
- if(((pkt->type[0]<<8)|pkt->type[1]) > 1500){
- ctlr->txf.framectl = WF_Data;
- memmove(ctlr->txf.addr1, pkt->d, Eaddrlen);
- memmove(ctlr->txf.addr2, pkt->s, Eaddrlen);
- memmove(ctlr->txf.dstaddr, pkt->d, Eaddrlen);
- memmove(ctlr->txf.srcaddr, pkt->s, Eaddrlen);
- memmove(&ctlr->txf.type, pkt->type, 2);
- bp->rp += ETHERHDRSIZE;
- len = BLEN(bp);
- off = WF_802_11_Off;
- ctlr->txf.dlen = len+ETHERHDRSIZE-WSnapHdrLen;
- hnputs((uchar*)&ctlr->txf.dat[0], WSnap0);
- hnputs((uchar*)&ctlr->txf.dat[1], WSnap1);
- hnputs((uchar*)&ctlr->txf.len, len+ETHERHDRSIZE-WSnapHdrLen);
- }
- else{
- len = BLEN(bp);
- off = WF_802_3_Off;
- ctlr->txf.dlen = len;
- }
- w_write(ctlr, ctlr->txdid, 0, &ctlr->txf, sizeof(ctlr->txf));
- w_write(ctlr, ctlr->txdid, off, bp->rp, len+2);
-
- if(w_cmd(ctlr, WCmdReclaim|WCmdTx, ctlr->txdid)){
- DEBUG("wavelan: transmit failed\n");
- ctlr->ntxerr++;
- }
- else{
- ctlr->txbusy = 1;
- ctlr->txtmout = 2;
- }
- freeb(bp);
-}
-
-static void
-w_txdone(Ctlr* ctlr, int sts)
-{
- ctlr->txbusy = 0;
- ctlr->txtmout = 0;
- if(sts & WTxErrEv)
- ctlr->ntxerr++;
- else
- ctlr->ntx++;
-}
-
-/* save the stats info in the ctlr struct */
-static void
-w_stats(Ctlr* ctlr, int len)
-{
- int i, rc;
- ulong* p = (ulong*)&ctlr->WStats;
- ulong* pend = (ulong*)&ctlr->end;
-
- for (i = 0; i < len && p < pend; i++){
- rc = csr_ins(ctlr, WR_Data1);
- if(rc > 0xf000)
- rc = ~rc & 0xffff;
- p[i] += rc;
- }
-}
-
-/* send the base station scan info to any readers */
-static void
-w_scaninfo(Ether* ether, Ctlr *ctlr, int len)
-{
- int i, j;
- Netfile **ep, *f, **fp;
- Block *bp;
- WScan *wsp;
- ushort *scanbuf;
-
- scanbuf = malloc(len*2);
- if(scanbuf == nil)
- return;
-
- for (i = 0; i < len ; i++)
- scanbuf[i] = csr_ins(ctlr, WR_Data1);
-
- /* calculate number of samples */
- len /= 25;
- if(len == 0)
- goto out;
-
- i = ether->scan;
- ep = &ether->f[Ntypes];
- for(fp = ether->f; fp < ep && i > 0; fp++){
- f = *fp;
- if(f == nil || f->scan == 0)
- continue;
-
- bp = iallocb(100*len);
- if(bp == nil)
- break;
- for(j = 0; j < len; j++){
- wsp = (WScan*)(&scanbuf[j*25]);
- if(wsp->ssid_len > 32)
- wsp->ssid_len = 32;
- bp->wp = (uchar*)seprint((char*)bp->wp, (char*)bp->lim,
- "ssid=%.*s;bssid=%E;signal=%d;noise=%d;chan=%d%s\n",
- wsp->ssid_len, wsp->ssid, wsp->bssid, wsp->signal,
- wsp->noise, wsp->chan, (wsp->capinfo&(1<<4))?";wep":"");
- }
- qpass(f->in, bp);
- i--;
- }
-out:
- free(scanbuf);
-}
-
-static int
-w_info(Ether *ether, Ctlr* ctlr)
-{
- int sp;
- Wltv ltv;
-
- sp = csr_ins(ctlr, WR_InfoId);
- ltv.len = ltv.type = 0;
- w_read(ctlr, sp, 0, &ltv, 4);
- ltv.len--;
- switch(ltv.type){
- case WTyp_Stats:
- w_stats(ctlr, ltv.len);
- return 0;
- case WTyp_Scan:
- w_scaninfo(ether, ctlr, ltv.len);
- return 0;
- }
- return -1;
-}
-
-/* set scanning interval */
-static void
-w_scanbs(void *a, uint secs)
-{
- Ether *ether = a;
- Ctlr* ctlr = (Ctlr*) ether->ctlr;
-
- ctlr->scanticks = secs*(1000/MSperTick);
-}
-
-static void
-w_intr(Ether *ether)
-{
- int rc, txid;
- Ctlr* ctlr = (Ctlr*) ether->ctlr;
-
- if((ctlr->state & Power) == 0)
- return;
-
- if((ctlr->state & Attached) == 0){
- csr_ack(ctlr, 0xffff);
- csr_outs(ctlr, WR_IntEna, 0);
- return;
- }
-
- rc = csr_ins(ctlr, WR_EvSts);
- csr_ack(ctlr, ~WEvs); // Not interested in them
- if(rc & WRXEv){
- w_rxdone(ether);
- csr_ack(ctlr, WRXEv);
- }
- if(rc & WTXEv){
- w_txdone(ctlr, rc);
- csr_ack(ctlr, WTXEv);
- }
- if(rc & WAllocEv){
- ctlr->nalloc++;
- txid = csr_ins(ctlr, WR_Alloc);
- csr_ack(ctlr, WAllocEv);
- if(txid == ctlr->txdid){
- if((rc & WTXEv) == 0)
- w_txdone(ctlr, rc);
- }
- }
- if(rc & WInfoEv){
- ctlr->ninfo++;
- w_info(ether, ctlr);
- csr_ack(ctlr, WInfoEv);
- }
- if(rc & WTxErrEv){
- w_txdone(ctlr, rc);
- csr_ack(ctlr, WTxErrEv);
- }
- if(rc & WIDropEv){
- ctlr->nidrop++;
- csr_ack(ctlr, WIDropEv);
- }
- w_txstart(ether);
-}
-
-// Watcher to ensure that the card still works properly and
-// to request WStats updates once a minute.
-// BUG: it runs much more often, see the comment below.
-
-static void
-w_timer(void* arg)
-{
- Ether* ether = (Ether*) arg;
- Ctlr* ctlr = (Ctlr*)ether->ctlr;
-
- ctlr->timerproc = up;
- for(;;){
- tsleep(&up->sleep, return0, 0, MSperTick);
- ctlr = (Ctlr*)ether->ctlr;
- if(ctlr == 0)
- break;
- if((ctlr->state & (Attached|Power)) != (Attached|Power))
- continue;
- ctlr->ticks++;
-
- ilock(ctlr);
-
- // Seems that the card gets frames BUT does
- // not send the interrupt; this is a problem because
- // I suspect it runs out of receive buffers and
- // stops receiving until a transmit watchdog
- // reenables the card.
- // The problem is serious because it leads to
- // poor rtts.
- // This can be seen clearly by commenting out
- // the next if and doing a ping: it will stop
- // receiving (although the icmp replies are being
- // issued from the remote) after a few seconds.
- // Of course this `bug' could be because I'm reading
- // the card frames in the wrong way; due to the
- // lack of documentation I cannot know.
-
- if(csr_ins(ctlr, WR_EvSts)&WEvs){
- ctlr->tickintr++;
- w_intr(ether);
- }
-
- if((ctlr->ticks % 10) == 0) {
- if(ctlr->txtmout && --ctlr->txtmout == 0){
- ctlr->nwatchdogs++;
- w_txdone(ctlr, WTxErrEv);
- if(w_enable(ether)){
- DEBUG("wavelan: wdog enable failed\n");
- }
- w_txstart(ether);
- }
- if((ctlr->ticks % 120) == 0)
- if(ctlr->txbusy == 0)
- w_cmd(ctlr, WCmdEnquire, WTyp_Stats);
- if(ctlr->scanticks > 0)
- if((ctlr->ticks % ctlr->scanticks) == 0)
- if(ctlr->txbusy == 0)
- w_cmd(ctlr, WCmdEnquire, WTyp_Scan);
- }
- iunlock(ctlr);
- }
- pexit("terminated", 0);
-}
-
-void
-w_multicast(void*, uchar*, int)
-{
- // BUG: to be added.
-}
-
-void
-w_attach(Ether* ether)
-{
- Ctlr* ctlr;
- char name[64];
- int rc;
-
- if(ether->ctlr == 0)
- return;
-
- snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno);
- ctlr = (Ctlr*) ether->ctlr;
- if((ctlr->state & Attached) == 0){
- ilock(ctlr);
- rc = w_enable(ether);
- iunlock(ctlr);
- if(rc == 0){
- ctlr->state |= Attached;
- kproc(name, w_timer, ether, 0);
- } else
- print("#l%d: enable failed\n",ether->ctlrno);
- }
-}
-
-void
-w_detach(Ether* ether)
-{
- Ctlr* ctlr;
- char name[64];
-
- if(ether->ctlr == nil)
- return;
-
- snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno);
- ctlr = (Ctlr*) ether->ctlr;
- if(ctlr->state & Attached){
- ilock(ctlr);
- w_intdis(ctlr);
- if(ctlr->timerproc){
- if(!postnote(ctlr->timerproc, 1, "kill", 0))
- print("timerproc note not posted\n");
- print("w_detach, killing 0x%p\n", ctlr->timerproc);
- }
- ctlr->state &= ~Attached;
- iunlock(ctlr);
- }
- ether->ctlr = nil;
-}
-
-void
-w_power(Ether* ether, int on)
-{
- Ctlr *ctlr;
-
- ctlr = (Ctlr*) ether->ctlr;
- ilock(ctlr);
-iprint("w_power %d\n", on);
- if(on){
- if((ctlr->state & Power) == 0){
- if (wavelanreset(ether, ctlr) < 0){
- iprint("w_power: reset failed\n");
- iunlock(ctlr);
- w_detach(ether);
- free(ctlr);
- return;
- }
- if(ctlr->state & Attached)
- w_enable(ether);
- ctlr->state |= Power;
- }
- }else{
- if(ctlr->state & Power){
- if(ctlr->state & Attached)
- w_intdis(ctlr);
- ctlr->state &= ~Power;
- }
- }
- iunlock(ctlr);
-}
-
-#define PRINTSTAT(fmt,val) l += snprint(p+l, READSTR-l, (fmt), (val))
-#define PRINTSTR(fmt) l += snprint(p+l, READSTR-l, (fmt))
-
-long
-w_ifstat(Ether* ether, void* a, long n, ulong offset)
-{
- Ctlr *ctlr = (Ctlr*) ether->ctlr;
- char *k, *p;
- int i, l, txid;
-
- ether->oerrs = ctlr->ntxerr;
- ether->crcs = ctlr->nrxfcserr;
- ether->frames = 0;
- ether->buffs = ctlr->nrxdropnobuf;
- ether->overflows = 0;
-
- //
- // Offset must be zero or there's a possibility the
- // new data won't match the previous read.
- //
- if(n == 0 || offset != 0)
- return 0;
-
- p = malloc(READSTR);
- l = 0;
-
- PRINTSTAT("Signal: %d\n", ctlr->signal-149);
- PRINTSTAT("Noise: %d\n", ctlr->noise-149);
- PRINTSTAT("SNR: %ud\n", ctlr->signal-ctlr->noise);
- PRINTSTAT("Interrupts: %lud\n", ctlr->nints);
- PRINTSTAT("Double Interrupts: %lud\n", ctlr->ndoubleint);
- PRINTSTAT("TxPackets: %lud\n", ctlr->ntx);
- PRINTSTAT("RxPackets: %lud\n", ctlr->nrx);
- PRINTSTAT("TxErrors: %lud\n", ctlr->ntxerr);
- PRINTSTAT("RxErrors: %lud\n", ctlr->nrxerr);
- PRINTSTAT("TxRequests: %lud\n", ctlr->ntxrq);
- PRINTSTAT("AllocEvs: %lud\n", ctlr->nalloc);
- PRINTSTAT("InfoEvs: %lud\n", ctlr->ninfo);
- PRINTSTAT("InfoDrop: %lud\n", ctlr->nidrop);
- PRINTSTAT("WatchDogs: %lud\n", ctlr->nwatchdogs);
- PRINTSTAT("Ticks: %ud\n", ctlr->ticks);
- PRINTSTAT("TickIntr: %ud\n", ctlr->tickintr);
- k = ((ctlr->state & Attached) ? "attached" : "not attached");
- PRINTSTAT("Card %s", k);
- k = ((ctlr->state & Power) ? "on" : "off");
- PRINTSTAT(", power %s", k);
- k = ((ctlr->txbusy)? ", txbusy" : "");
- PRINTSTAT("%s\n", k);
-
- if(ctlr->hascrypt){
- PRINTSTR("Keys: ");
- for (i = 0; i < WNKeys; i++){
- if(ctlr->keys.keys[i].len == 0)
- PRINTSTR("none ");
- else if(SEEKEYS == 0)
- PRINTSTR("set ");
- else
- PRINTSTAT("%s ", ctlr->keys.keys[i].dat);
- }
- PRINTSTR("\n");
- }
-
- // real card stats
- ilock(ctlr);
- PRINTSTR("\nCard stats: \n");
- PRINTSTAT("Status: %ux\n", csr_ins(ctlr, WR_Sts));
- PRINTSTAT("Event status: %ux\n", csr_ins(ctlr, WR_EvSts));
- i = ltv_ins(ctlr, WTyp_Ptype);
- PRINTSTAT("Port type: %d\n", i);
- PRINTSTAT("Transmit rate: %d\n", ltv_ins(ctlr, WTyp_TxRate));
- PRINTSTAT("Current Transmit rate: %d\n",
- ltv_ins(ctlr, WTyp_CurTxRate));
- PRINTSTAT("Channel: %d\n", ltv_ins(ctlr, WTyp_Chan));
- PRINTSTAT("AP density: %d\n", ltv_ins(ctlr, WTyp_ApDens));
- PRINTSTAT("Promiscuous mode: %d\n", ltv_ins(ctlr, WTyp_Prom));
- if(i == WPTypeAdHoc)
- PRINTSTAT("SSID name: %s\n", ltv_inname(ctlr, WTyp_NetName));
- else {
- Wltv ltv;
- PRINTSTAT("Current name: %s\n", ltv_inname(ctlr, WTyp_CurName));
- ltv.type = WTyp_BaseID;
- ltv.len = 4;
- if(w_inltv(ctlr, &ltv))
- print("#l%d: unable to read base station mac addr\n", ether->ctlrno);
- l += snprint(p+l, READSTR-l, "Base station: %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
- ltv.addr[0], ltv.addr[1], ltv.addr[2], ltv.addr[3], ltv.addr[4], ltv.addr[5]);
- }
- PRINTSTAT("Net name: %s\n", ltv_inname(ctlr, WTyp_WantName));
- PRINTSTAT("Node name: %s\n", ltv_inname(ctlr, WTyp_NodeName));
- if(ltv_ins(ctlr, WTyp_HasCrypt) == 0)
- PRINTSTR("WEP: not supported\n");
- else {
- if(ltv_ins(ctlr, WTyp_Crypt) == 0)
- PRINTSTR("WEP: disabled\n");
- else{
- PRINTSTR("WEP: enabled\n");
- k = ((ctlr->xclear)? "excluded": "included");
- PRINTSTAT("Clear packets: %s\n", k);
- txid = ltv_ins(ctlr, WTyp_TxKey);
- PRINTSTAT("Transmit key id: %d\n", txid);
- }
- }
- iunlock(ctlr);
-
- PRINTSTAT("ntxuframes: %lud\n", ctlr->ntxuframes);
- PRINTSTAT("ntxmframes: %lud\n", ctlr->ntxmframes);
- PRINTSTAT("ntxfrags: %lud\n", ctlr->ntxfrags);
- PRINTSTAT("ntxubytes: %lud\n", ctlr->ntxubytes);
- PRINTSTAT("ntxmbytes: %lud\n", ctlr->ntxmbytes);
- PRINTSTAT("ntxdeferred: %lud\n", ctlr->ntxdeferred);
- PRINTSTAT("ntxsretries: %lud\n", ctlr->ntxsretries);
- PRINTSTAT("ntxmultiretries: %lud\n", ctlr->ntxmultiretries);
- PRINTSTAT("ntxretrylimit: %lud\n", ctlr->ntxretrylimit);
- PRINTSTAT("ntxdiscards: %lud\n", ctlr->ntxdiscards);
- PRINTSTAT("nrxuframes: %lud\n", ctlr->nrxuframes);
- PRINTSTAT("nrxmframes: %lud\n", ctlr->nrxmframes);
- PRINTSTAT("nrxfrags: %lud\n", ctlr->nrxfrags);
- PRINTSTAT("nrxubytes: %lud\n", ctlr->nrxubytes);
- PRINTSTAT("nrxmbytes: %lud\n", ctlr->nrxmbytes);
- PRINTSTAT("nrxfcserr: %lud\n", ctlr->nrxfcserr);
- PRINTSTAT("nrxdropnobuf: %lud\n", ctlr->nrxdropnobuf);
- PRINTSTAT("nrxdropnosa: %lud\n", ctlr->nrxdropnosa);
- PRINTSTAT("nrxcantdecrypt: %lud\n", ctlr->nrxcantdecrypt);
- PRINTSTAT("nrxmsgfrag: %lud\n", ctlr->nrxmsgfrag);
- PRINTSTAT("nrxmsgbadfrag: %lud\n", ctlr->nrxmsgbadfrag);
- USED(l);
- n = readstr(offset, a, n, p);
- free(p);
- return n;
-}
-#undef PRINTSTR
-#undef PRINTSTAT
-
-static int
-parsekey(WKey* key, char* a)
-{
- int i, k, len, n;
- char buf[WMaxKeyLen];
-
- len = strlen(a);
- if(len == WMinKeyLen || len == WMaxKeyLen){
- memset(key->dat, 0, sizeof(key->dat));
- memmove(key->dat, a, len);
- key->len = len;
-
- return 0;
- }
- else if(len == WMinKeyLen*2 || len == WMaxKeyLen*2){
- k = 0;
- for(i = 0; i < len; i++){
- if(*a >= '0' && *a <= '9')
- n = *a++ - '0';
- else if(*a >= 'a' && *a <= 'f')
- n = *a++ - 'a' + 10;
- else if(*a >= 'A' && *a <= 'F')
- n = *a++ - 'A' + 10;
- else
- return -1;
-
- if(i & 1){
- buf[k] |= n;
- k++;
- }
- else
- buf[k] = n<<4;
- }
-
- memset(key->dat, 0, sizeof(key->dat));
- memmove(key->dat, buf, k);
- key->len = k;
-
- return 0;
- }
-
- return -1;
-}
-
-int
-w_option(Ctlr* ctlr, char* buf, long n)
-{
- char *p;
- int i, r;
- Cmdbuf *cb;
-
- r = 0;
-
- cb = parsecmd(buf, n);
- if(cb->nf < 2)
- r = -1;
- else if(cistrcmp(cb->f[0], "essid") == 0){
- if(cistrcmp(cb->f[1],"default") == 0)
- p = "";
- else
- p = cb->f[1];
- if(ctlr->ptype == WPTypeAdHoc){
- memset(ctlr->netname, 0, sizeof(ctlr->netname));
- strncpy(ctlr->netname, p, WNameLen);
- }
- else{
- memset(ctlr->wantname, 0, sizeof(ctlr->wantname));
- strncpy(ctlr->wantname, p, WNameLen);
- }
- }
- else if(cistrcmp(cb->f[0], "station") == 0){
- memset(ctlr->nodename, 0, sizeof(ctlr->nodename));
- strncpy(ctlr->nodename, cb->f[1], WNameLen);
- }
- else if(cistrcmp(cb->f[0], "channel") == 0){
- if((i = atoi(cb->f[1])) >= 1 && i <= 16)
- ctlr->chan = i;
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "mode") == 0){
- if(cistrcmp(cb->f[1], "managed") == 0)
- ctlr->ptype = WPTypeManaged;
- else if(cistrcmp(cb->f[1], "wds") == 0)
- ctlr->ptype = WPTypeWDS;
- else if(cistrcmp(cb->f[1], "adhoc") == 0)
- ctlr->ptype = WPTypeAdHoc;
- else if((i = atoi(cb->f[1])) >= 0 && i <= 3)
- ctlr->ptype = i;
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "ibss") == 0){
- if(cistrcmp(cb->f[1], "on") == 0)
- ctlr->createibss = 1;
- else
- ctlr->createibss = 0;
- }
- else if(cistrcmp(cb->f[0], "crypt") == 0){
- if(cistrcmp(cb->f[1], "off") == 0)
- ctlr->crypt = 0;
- else if(cistrcmp(cb->f[1], "on") == 0 && ctlr->hascrypt)
- ctlr->crypt = 1;
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "clear") == 0){
- if(cistrcmp(cb->f[1], "on") == 0)
- ctlr->xclear = 0;
- else if(cistrcmp(cb->f[1], "off") == 0 && ctlr->hascrypt)
- ctlr->xclear = 1;
- else
- r = -1;
- }
- else if(cistrncmp(cb->f[0], "key", 3) == 0){
- if((i = atoi(cb->f[0]+3)) >= 1 && i <= WNKeys){
- ctlr->txkey = i-1;
- if(parsekey(&ctlr->keys.keys[ctlr->txkey], cb->f[1]))
- r = -1;
- }
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "txkey") == 0){
- if((i = atoi(cb->f[1])) >= 1 && i <= WNKeys)
- ctlr->txkey = i-1;
- else
- r = -1;
- }
- else if(cistrcmp(cb->f[0], "pm") == 0){
- if(cistrcmp(cb->f[1], "off") == 0)
- ctlr->pmena = 0;
- else if(cistrcmp(cb->f[1], "on") == 0){
- ctlr->pmena = 1;
- if(cb->nf == 3){
- i = atoi(cb->f[2]);
- // check range here? what are the units?
- ctlr->pmwait = i;
- }
- }
- else
- r = -1;
- }
- else
- r = -2;
- free(cb);
-
- return r;
-}
-
-long
-w_ctl(Ether* ether, void* buf, long n)
-{
- Ctlr *ctlr;
-
- if((ctlr = ether->ctlr) == nil)
- error(Enonexist);
- if((ctlr->state & Attached) == 0)
- error(Eshutdown);
-
- ilock(ctlr);
- if(w_option(ctlr, buf, n)){
- iunlock(ctlr);
- error(Ebadctl);
- }
- if(ctlr->txbusy)
- w_txdone(ctlr, WTxErrEv);
- w_enable(ether);
- w_txstart(ether);
- iunlock(ctlr);
-
- return n;
-}
-
-void
-w_transmit(Ether* ether)
-{
- Ctlr* ctlr = ether->ctlr;
-
- if(ctlr == 0)
- return;
-
- ilock(ctlr);
- ctlr->ntxrq++;
- w_txstart(ether);
- iunlock(ctlr);
-}
-
-void
-w_promiscuous(void* arg, int on)
-{
- Ether* ether = (Ether*)arg;
- Ctlr* ctlr = ether->ctlr;
-
- if(ctlr == nil)
- error("card not found");
- if((ctlr->state & Attached) == 0)
- error("card not attached");
- ilock(ctlr);
- ltv_outs(ctlr, WTyp_Prom, (on?1:0));
- iunlock(ctlr);
-}
-
-void
-w_interrupt(Ureg* ,void* arg)
-{
- Ether* ether = (Ether*) arg;
- Ctlr* ctlr = (Ctlr*) ether->ctlr;
-
- if(ctlr == 0)
- return;
- ilock(ctlr);
- ctlr->nints++;
- w_intr(ether);
- iunlock(ctlr);
-}
-
-int
-wavelanreset(Ether* ether, Ctlr *ctlr)
-{
- Wltv ltv;
-
- iprint("wavelanreset, iob 0x%ux\n", ctlr->iob);
- w_intdis(ctlr);
- if(w_cmd(ctlr,WCmdIni,0)){
- iprint("#l%d: init failed\n", ether->ctlrno);
- return -1;
- }
- w_intdis(ctlr);
- ltv_outs(ctlr, WTyp_Tick, 8);
-
- ctlr->chan = 0;
- ctlr->ptype = WDfltPType;
- ctlr->txkey = 0;
- ctlr->createibss = 0;
- ctlr->keys.len = sizeof(WKey)*WNKeys/2 + 1;
- ctlr->keys.type = WTyp_Keys;
- if(ctlr->hascrypt = ltv_ins(ctlr, WTyp_HasCrypt))
- ctlr->crypt = 1;
- *ctlr->netname = *ctlr->wantname = 0;
- strcpy(ctlr->nodename, "Plan 9 STA");
-
- ctlr->netname[WNameLen-1] = 0;
- ctlr->wantname[WNameLen-1] = 0;
- ctlr->nodename[WNameLen-1] =0;
-
- ltv.type = WTyp_Mac;
- ltv.len = 4;
- if(w_inltv(ctlr, &ltv)){
- iprint("#l%d: unable to read mac addr\n",
- ether->ctlrno);
- return -1;
- }
- memmove(ether->ea, ltv.addr, Eaddrlen);
-
- if(ctlr->chan == 0)
- ctlr->chan = ltv_ins(ctlr, WTyp_Chan);
- ctlr->apdensity = WDfltApDens;
- ctlr->rtsthres = WDfltRtsThres;
- ctlr->txrate = WDfltTxRate;
- ctlr->maxlen = WMaxLen;
- ctlr->pmena = 0;
- ctlr->pmwait = 100;
- ctlr->signal = 1;
- ctlr->noise = 1;
- ctlr->state |= Power;
-
- // free old Ctlr struct if resetting after suspend
- if(ether->ctlr && ether->ctlr != ctlr)
- free(ether->ctlr);
-
- // link to ether
- ether->ctlr = ctlr;
- ether->mbps = 10;
- ether->attach = w_attach;
- ether->detach = w_detach;
- ether->interrupt = w_interrupt;
- ether->transmit = w_transmit;
- ether->ifstat = w_ifstat;
- ether->ctl = w_ctl;
- ether->power = w_power;
- ether->promiscuous = w_promiscuous;
- ether->multicast = w_multicast;
- ether->scanbs = w_scanbs;
- ether->arg = ether;
-
- DEBUG("#l%d: irq %d port %lx type %s",
- ether->ctlrno, ether->irq, ether->port, ether->type);
- DEBUG(" %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux\n",
- ether->ea[0], ether->ea[1], ether->ea[2],
- ether->ea[3], ether->ea[4], ether->ea[5]);
-
- return 0;
-}
-
-char* wavenames[] = {
- "WaveLAN/IEEE",
- "TrueMobile 1150",
- "Instant Wireless ; Network PC CARD",
- "Instant Wireless Network PC Card",
- "Avaya Wireless PC Card",
- "AirLancer MC-11",
- "INTERSIL;HFA384x/IEEE;Version 01.02;",
- nil,
-};
diff --git a/os/pc/wavelan.h b/os/pc/wavelan.h
deleted file mode 100644
index 7f76149e..00000000
--- a/os/pc/wavelan.h
+++ /dev/null
@@ -1,327 +0,0 @@
-#define DEBUG if(1){}else print
-
-#define SEEKEYS 0
-
-// Lucent's Length-Type-Value records to talk to the wavelan.
-// most operational parameters are read/set using this.
-enum
-{
- WTyp_Stats = 0xf100,
- WTyp_Scan = 0xf101,
- WTyp_Link = 0xf200,
- WTyp_Ptype = 0xfc00,
- WTyp_Mac = 0xfc01,
- WTyp_WantName = 0xfc02,
- WTyp_Chan = 0xfc03,
- WTyp_NetName = 0xfc04,
- WTyp_ApDens = 0xfc06,
- WTyp_MaxLen = 0xfc07,
- WTyp_PM = 0xfc09,
- WTyp_PMWait = 0xfc0c,
- WTyp_NodeName = 0xfc0e,
- WTyp_Crypt = 0xfc20,
- WTyp_XClear = 0xfc22,
- WTyp_CreateIBSS = 0xfc81,
- WTyp_RtsThres = 0xfc83,
- WTyp_TxRate = 0xfc84,
- WTx1Mbps = 0x0,
- WTx2Mbps = 0x1,
- WTxAuto = 0x3,
- WTyp_Prom = 0xfc85,
- WTyp_Keys = 0xfcb0,
- WTyp_TxKey = 0xfcb1,
- WTyp_StationID = 0xfd20,
- WTyp_CurName = 0xfd41,
- WTyp_BaseID = 0xfd42, // ID of the currently connected-to base station
- WTyp_CurTxRate = 0xfd44, // Current TX rate
- WTyp_HasCrypt = 0xfd4f,
- WTyp_Tick = 0xfce0,
-};
-
-// Controller
-enum
-{
- WDfltIRQ = 3, // default irq
- WDfltIOB = 0x180, // default IO base
-
- WIOLen = 0x40, // Hermes IO length
-
- WTmOut = 65536, // Cmd time out
-
- WPTypeManaged = 1,
- WPTypeWDS = 2,
- WPTypeAdHoc = 3,
- WDfltPType = WPTypeManaged,
-
- WDfltApDens = 1,
- WDfltRtsThres = 2347, // == disabled
- WDfltTxRate = WTxAuto, // 2Mbps
-
- WMaxLen = 2304,
- WNameLen = 32,
-
- WNKeys = 4,
- WKeyLen = 14,
- WMinKeyLen = 5,
- WMaxKeyLen = 13,
-
- // Wavelan hermes registers
- WR_Cmd = 0x00,
- WCmdIni = 0x0000,
- WCmdEna = 0x0001,
- WCmdDis = 0x0002,
- WCmdTx = 0x000b,
- WCmdMalloc = 0x000a,
- WCmdEnquire = 0x0011,
- WCmdMsk = 0x003f,
- WCmdAccRd = 0x0021,
- WCmdReclaim = 0x0100,
- WCmdAccWr = 0x0121,
- WCmdBusy = 0x8000,
- WR_Parm0 = 0x02,
- WR_Parm1 = 0x04,
- WR_Parm2 = 0x06,
- WR_Sts = 0x08,
- WR_InfoId = 0x10,
- WR_Sel0 = 0x18,
- WR_Sel1 = 0x1a,
- WR_Off0 = 0x1c,
- WR_Off1 = 0x1e,
- WBusyOff = 0x8000,
- WErrOff = 0x4000,
- WResSts = 0x7f00,
- WR_RXId = 0x20,
- WR_Alloc = 0x22,
- WR_EvSts = 0x30,
- WR_IntEna = 0x32,
- WCmdEv = 0x0010,
- WRXEv = 0x0001,
- WTXEv = 0x0002,
- WTxErrEv = 0x0004,
- WAllocEv = 0x0008,
- WInfoEv = 0x0080,
- WIDropEv = 0x2000,
- WTickEv = 0x8000,
- WEvs = WRXEv|WTXEv|WAllocEv|WInfoEv|WIDropEv,
-
- WR_EvAck = 0x34,
- WR_Data0 = 0x36,
- WR_Data1 = 0x38,
-
- WR_PciCor = 0x26,
- WR_PciHcr = 0x2E,
-
- // Frame stuff
-
- WF_Err = 0x0003,
- WF_1042 = 0x2000,
- WF_Tunnel = 0x4000,
- WF_WMP = 0x6000,
-
- WF_Data = 0x0008,
-
- WSnapK1 = 0xaa,
- WSnapK2 = 0x00,
- WSnapCtlr = 0x03,
- WSnap0 = (WSnapK1|(WSnapK1<<8)),
- WSnap1 = (WSnapK2|(WSnapCtlr<<8)),
- WSnapHdrLen = 6,
-
- WF_802_11_Off = 0x44,
- WF_802_3_Off = 0x2e,
-
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Wltv Wltv;
-typedef struct WFrame WFrame;
-typedef struct Stats Stats;
-typedef struct WStats WStats;
-typedef struct WScan WScan;
-typedef struct WKey WKey;
-
-struct WStats
-{
- ulong ntxuframes; // unicast frames
- ulong ntxmframes; // multicast frames
- ulong ntxfrags; // fragments
- ulong ntxubytes; // unicast bytes
- ulong ntxmbytes; // multicast bytes
- ulong ntxdeferred; // deferred transmits
- ulong ntxsretries; // single retries
- ulong ntxmultiretries; // multiple retries
- ulong ntxretrylimit;
- ulong ntxdiscards;
- ulong nrxuframes; // unicast frames
- ulong nrxmframes; // multicast frames
- ulong nrxfrags; // fragments
- ulong nrxubytes; // unicast bytes
- ulong nrxmbytes; // multicast bytes
- ulong nrxfcserr;
- ulong nrxdropnobuf;
- ulong nrxdropnosa;
- ulong nrxcantdecrypt;
- ulong nrxmsgfrag;
- ulong nrxmsgbadfrag;
- ulong end;
-};
-
-struct WScan
-{
- ushort chan; /* dss channel */
- ushort noise; /* average noise in the air */
- ushort signal; /* signal strength */
- uchar bssid[Eaddrlen]; /* MAC address of the ap */
- ushort interval; /* beacon transmit interval */
- ushort capinfo; /* capability bits (0-ess, 1-ibss, 4-privacy [wep]) */
- ushort ssid_len; /* ssid length */
- char ssid[WNameLen]; /* ssid (ap name) */
-};
-
-struct WFrame
-{
- ushort sts;
- ushort rsvd0;
- ushort rsvd1;
- ushort qinfo;
- ushort rsvd2;
- ushort rsvd3;
- ushort txctl;
- ushort framectl;
- ushort id;
- uchar addr1[Eaddrlen];
- uchar addr2[Eaddrlen];
- uchar addr3[Eaddrlen];
- ushort seqctl;
- uchar addr4[Eaddrlen];
- ushort dlen;
- uchar dstaddr[Eaddrlen];
- uchar srcaddr[Eaddrlen];
- ushort len;
- ushort dat[3];
- ushort type;
-};
-
-struct WKey
-{
- ushort len;
- char dat[WKeyLen];
-};
-
-struct Wltv
-{
- ushort len;
- ushort type;
- union
- {
- struct {
- ushort val;
- ushort pad;
- };
- struct {
- uchar addr[8];
- };
- struct {
- ushort slen;
- char s[WNameLen];
- };
- struct {
- char name[WNameLen];
- };
- struct {
- WKey keys[WNKeys];
- };
- };
-};
-
-// What the driver thinks. Not what the card thinks.
-struct Stats
-{
- ulong nints;
- ulong ndoubleint;
- ulong nrx;
- ulong ntx;
- ulong ntxrq;
- ulong nrxerr;
- ulong ntxerr;
- ulong nalloc; // allocation (reclaim) events
- ulong ninfo;
- ulong nidrop;
- ulong nwatchdogs; // transmit time outs, actually
- int ticks;
- int tickintr;
- int signal;
- int noise;
-};
-
-enum {
- Attached = 0x01,
- Power = 0x02,
-};
-
-struct Ctlr
-{
- Lock;
-
- int state; // Attached | Power
- int slot;
- int iob;
- int createibss;
- int ptype;
- int apdensity;
- int rtsthres;
- int txbusy;
- int txrate;
- int txdid;
- int txmid;
- int txtmout;
- int maxlen;
- int chan;
- int pmena;
- int pmwait;
-
- Proc *timerproc;
- int scanticks;
-
- char netname[WNameLen];
- char wantname[WNameLen];
- char nodename[WNameLen];
- WFrame txf;
- uchar txbuf[1536];
-
- int hascrypt; // card has encryption
- int crypt; // encryption off/on
- int txkey; // transmit key
- Wltv keys; // default keys
- int xclear; // exclude clear packets off/on
-
- int ctlrno;
-
- ushort *mmb;
- /* for PCI-based devices */
- Ctlr *next;
- int active;
- Pcidev *pcidev;
-
- Stats;
- WStats;
-};
-
-extern char* wavenames[];
-
-void csr_outs(Ctlr*, int, ushort);
-ushort csr_ins(Ctlr*, int);
-void w_intdis(Ctlr*);
-int w_cmd(Ctlr *, ushort, ushort);
-void ltv_outs(Ctlr*, int, ushort);
-int ltv_ins(Ctlr*, int);
-int w_option(Ctlr*, char*, long);
-int w_inltv(Ctlr*, Wltv*);
-void w_attach(Ether*);
-void w_interrupt(Ureg*,void*);
-void w_transmit(Ether*);
-long w_ifstat(Ether*, void*, long, ulong);
-long w_ctl(Ether*, void*, long);
-void w_promiscuous(void*, int);
-void w_multicast(void*, uchar*, int);
-int wavelanreset(Ether*, Ctlr*);
diff --git a/os/pc/x86break.c b/os/pc/x86break.c
deleted file mode 100644
index db31fe4f..00000000
--- a/os/pc/x86break.c
+++ /dev/null
@@ -1,138 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-//
-// from trap.c
-//
-
-uchar BREAK = 0xcc;
-static ulong skipflags;
-extern int (*breakhandler)(Ureg *ur, Proc*);
-static Bkpt *skip;
-int breakmatch(BkptCond *cond, Ureg *ur, Proc *p);
-void breaknotify(Bkpt *b, Proc *p);
-void breakrestore(Bkpt *b);
-Bkpt* breakclear(int id);
-
-void
-skiphandler(Ureg *ur, void*)
-{
- if (skip == 0)
- panic("single step outside of skip");
-
- breakrestore( skip );
- skip = 0;
- ur->flags = skipflags;
- if (up != 0)
- up->state = Running;
-}
-
-void
-machbreakinit(void)
-{
- breakhandler = breakhit;
- trapenable(VectorDBG, skiphandler, nil, "bkpt.skip");
-}
-
-Instr
-machinstr(ulong addr)
-{
- if (addr < KTZERO)
- error(Ebadarg);
- return *(uchar*)addr;
-}
-
-void
-machbreakset(ulong addr)
-{
- if (addr < KTZERO)
- error(Ebadarg);
- *(uchar*)addr = BREAK;
-}
-
-void
-machbreakclear(ulong addr, Instr i)
-{
- if (addr < KTZERO)
- error(Ebadarg);
- *(uchar*)addr = i;
-}
-
-//
-// Called from the exception handler when a breakpoint instruction has been
-// hit. This cannot not be called unless at least one breakpoint with this
-// address is in the list of breakpoints. (All breakpoint notifications must
-// previously have been set via setbreak())
-//
-// foreach breakpoint in list
-// if breakpoint matches conditions
-// notify the break handler
-// if no breakpoints matched the conditions
-// pick a random breakpoint set to this address
-//
-// set a breakpoint at the next instruction to be executed,
-// and pass the current breakpoint to the "skiphandler"
-//
-// clear the current breakpoint
-//
-// Tell the scheduler to stop scheduling, so the caller is
-// guaranteed to execute the instruction, followed by the
-// added breakpoint.
-//
-//
-
-extern Bkpt *breakpoints;
-
-
-int
-breakhit(Ureg *ur, Proc *p)
-{
- Bkpt *b;
- int nmatched;
-
- ur->pc--;
-
- nmatched = 0;
- for(b = breakpoints; b != nil; b = b->next) {
- if(breakmatch(b->conditions, ur, p)) {
- breaknotify(b, p);
- ++nmatched;
- }
- }
-
- if (nmatched)
- return 1;
-
- if (skip != nil)
- panic("x86break: non-nil skip in breakhit\n");
-
- for(b = breakpoints; b != (Bkpt*) nil; b = b->next) {
- if(b->addr == ur->pc) {
- if(breakclear(b->id) == 0)
- panic("breakhit: breakclear() failed");
-
- skip = b;
- skipflags = ur->flags;
- if (p != 0)
- p->state = Stopped; /* this should disable scheduling */
-
- if (ur->flags & (1 << 9)) { /* mask all interrupts */
- ur->flags &= ~(1<<9);
- }
- ur->flags |= (1 << 8);
- }
- }
- return 1;
-}
-
-int
-isvalid_va(void*)
-{
- return 1;
-}
diff --git a/os/pc/zoran.h b/os/pc/zoran.h
deleted file mode 100644
index b54305ef..00000000
--- a/os/pc/zoran.h
+++ /dev/null
@@ -1,907 +0,0 @@
-static uchar
-zrmpeg1[] = {
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x66, 0x05,
-0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x5a, 0x00,
-0x00, 0x08, 0x58, 0x01, 0x00, 0x08, 0x6e, 0x00,
-0x00, 0x08, 0x6c, 0x00, 0x00, 0x03, 0x81, 0x03,
-0x00, 0x08, 0x9a, 0x00, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x97, 0x00, 0x06, 0x01, 0xfa,
-0x00, 0x0c, 0xa2, 0xd1, 0x00, 0x08, 0x6a, 0x00,
-0x00, 0x06, 0x01, 0x00, 0x00, 0x0c, 0xa0, 0x6b,
-0x00, 0x06, 0x01, 0xb3, 0x00, 0x0c, 0xa8, 0x09,
-0x00, 0x0c, 0xd8, 0x12, 0x00, 0x08, 0x5c, 0x01,
-0x00, 0x08, 0x02, 0xf0, 0x00, 0x08, 0xe4, 0x33,
-0x00, 0x08, 0x0c, 0x0c, 0x00, 0x08, 0x04, 0x08,
-0x00, 0x00, 0xe3, 0x80, 0x00, 0x04, 0x85, 0x90,
-0x00, 0x08, 0x0c, 0x0c, 0x00, 0x00, 0xe3, 0x80,
-0x00, 0x04, 0x85, 0xb1, 0x00, 0x08, 0x0c, 0x08,
-0x00, 0x04, 0x8d, 0x08, 0x00, 0x06, 0x81, 0x08,
-0x00, 0x0c, 0xa8, 0x22, 0x00, 0x08, 0x64, 0xff,
-0x00, 0x01, 0x01, 0x07, 0x00, 0x08, 0x02, 0x00,
-0x00, 0x06, 0x01, 0x02, 0x00, 0x0c, 0x90, 0x27,
-0x00, 0x08, 0x02, 0x01, 0x00, 0x06, 0x6b, 0x00,
-0x00, 0x08, 0xde, 0x01, 0x00, 0x0c, 0xa8, 0x09,
-0x00, 0x08, 0x0c, 0x0f, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x0c, 0x10, 0x00, 0x06, 0x8d, 0x01,
-0x00, 0x0c, 0xa0, 0x3a, 0x00, 0x08, 0x0a, 0x00,
-0x00, 0x08, 0x60, 0x00, 0x00, 0x08, 0x0c, 0x08,
-0x00, 0x04, 0x9d, 0x08, 0x00, 0x08, 0x8b, 0x41,
-0x00, 0x02, 0x50, 0x05, 0x00, 0x06, 0x0b, 0x40,
-0x00, 0x0c, 0xa8, 0x31, 0x00, 0x06, 0x6b, 0x00,
-0x00, 0x0c, 0xa8, 0x3f, 0x00, 0x0d, 0x00, 0x3b,
-0x00, 0x08, 0x60, 0x01, 0x00, 0x08, 0x0a, 0x40,
-0x00, 0x08, 0x0c, 0x01, 0x00, 0x06, 0x0d, 0x00,
-0x00, 0x0c, 0x98, 0x49, 0x00, 0x08, 0x0a, 0x40,
-0x00, 0x08, 0x0c, 0x08, 0x00, 0x04, 0x9d, 0x08,
-0x00, 0x08, 0x8b, 0x41, 0x00, 0x02, 0x50, 0x05,
-0x00, 0x06, 0x0b, 0x80, 0x00, 0x0c, 0xa8, 0x40,
-0x00, 0x06, 0x6b, 0x00, 0x00, 0x0c, 0xa8, 0x16,
-0x00, 0x0d, 0x00, 0x4e, 0x00, 0x08, 0x02, 0x10,
-0x00, 0x08, 0x8a, 0x41, 0x00, 0x02, 0x50, 0x05,
-0x00, 0x06, 0x0b, 0x80, 0x00, 0x0c, 0xa8, 0x4a,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x97,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x95,
-0x00, 0x06, 0x01, 0xb8, 0x00, 0x0c, 0xa9, 0xff,
-0x00, 0x06, 0x6f, 0x00, 0x00, 0x0c, 0xa0, 0x57,
-0x00, 0x08, 0x58, 0x00, 0x00, 0x08, 0x6e, 0x01,
-0x00, 0x08, 0x0c, 0x10, 0x00, 0x08, 0x0c, 0x09,
-0x00, 0x08, 0x0c, 0x01, 0x00, 0x08, 0x80, 0x06,
-0x00, 0x08, 0x0c, 0x01, 0x00, 0x04, 0x9d, 0x0f,
-0x00, 0x03, 0x12, 0x6c, 0x00, 0x08, 0xd8, 0x01,
-0x00, 0x08, 0x6c, 0x00, 0x00, 0x06, 0x01, 0x00,
-0x00, 0x0c, 0x98, 0x64, 0x00, 0x08, 0x58, 0x00,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x97,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x95,
-0x00, 0x0d, 0x01, 0xf7, 0x00, 0x06, 0x5d, 0x01,
-0x00, 0x0c, 0xa0, 0x6c, 0x00, 0x0c, 0xd8, 0x6b,
-0x00, 0x09, 0x20, 0xe5, 0x00, 0x09, 0x62, 0xe6,
-0x00, 0x09, 0x5e, 0xe3, 0x00, 0x09, 0x60, 0xc2,
-0x00, 0x08, 0x5c, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x02, 0x00, 0x2d, 0x00, 0x0c, 0xa0, 0x75,
-0x00, 0x08, 0xda, 0x00, 0x00, 0x0c, 0xd0, 0x76,
-0x00, 0x08, 0x50, 0x00, 0x00, 0x08, 0x23, 0xff,
-0x00, 0x08, 0x24, 0x00, 0x00, 0x08, 0x0c, 0x0a,
-0x00, 0x08, 0xe6, 0x32, 0x00, 0x04, 0x8d, 0x06,
-0x00, 0x08, 0xe8, 0x00, 0x00, 0x08, 0x0c, 0x03,
-0x00, 0x04, 0x8d, 0x0d, 0x00, 0x08, 0xaa, 0x00,
-0x00, 0x08, 0x0c, 0x10, 0x00, 0x06, 0x2b, 0x01,
-0x00, 0x0c, 0xa8, 0x8c, 0x00, 0x06, 0x6d, 0x00,
-0x00, 0x0c, 0xa8, 0x8a, 0x00, 0x08, 0x80, 0x2c,
-0x00, 0x01, 0x01, 0x01, 0x00, 0x08, 0xd8, 0x00,
-0x00, 0x08, 0x6c, 0x01, 0x00, 0x0d, 0x00, 0xab,
-0x00, 0x08, 0x58, 0x00, 0x00, 0x0d, 0x00, 0xab,
-0x00, 0x06, 0x2b, 0x02, 0x00, 0x0c, 0xa8, 0x97,
-0x00, 0x06, 0x6d, 0x00, 0x00, 0x0c, 0xa0, 0x99,
-0x00, 0x08, 0x58, 0x00, 0x00, 0x0d, 0x00, 0x9a,
-0x00, 0x08, 0x02, 0x03, 0x00, 0x06, 0x5b, 0x01,
-0x00, 0x0c, 0xa8, 0xb0, 0x00, 0x08, 0x02, 0x01,
-0x00, 0x0d, 0x00, 0xb0, 0x00, 0x06, 0xd9, 0x01,
-0x00, 0x0c, 0xa0, 0x9a, 0x00, 0x08, 0x58, 0x03,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0xab,
-0x00, 0x08, 0xd4, 0x02, 0x00, 0x08, 0xae, 0x00,
-0x00, 0x08, 0xac, 0x03, 0x00, 0x01, 0xc1, 0x9e,
-0x00, 0x02, 0xc1, 0x9f, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x06, 0x2b, 0x03, 0x00, 0x0c, 0xa8, 0xab,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0xab,
-0x00, 0x08, 0xd6, 0x02, 0x00, 0x08, 0xb2, 0x00,
-0x00, 0x08, 0xb0, 0x03, 0x00, 0x01, 0xc1, 0xa0,
-0x00, 0x02, 0xc1, 0xa1, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x97, 0x00, 0x08, 0x82, 0x15,
-0x00, 0x06, 0xd9, 0x02, 0x00, 0x0c, 0xa8, 0x92,
-0x00, 0x09, 0x02, 0xe7, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x95, 0x00, 0x08, 0x88, 0x0d,
-0x00, 0x08, 0x90, 0x04, 0x00, 0x08, 0x92, 0x04,
-0x00, 0x08, 0x94, 0x04, 0x00, 0x08, 0x45, 0xfe,
-0x00, 0x08, 0x34, 0x00, 0x00, 0x08, 0x36, 0x00,
-0x00, 0x08, 0x38, 0x00, 0x00, 0x08, 0x3a, 0x00,
-0x00, 0x08, 0x0c, 0x05, 0x00, 0x04, 0x8d, 0x0b,
-0x00, 0x09, 0x00, 0xc0, 0x00, 0x08, 0x46, 0x01,
-0x00, 0x08, 0x0c, 0x01, 0x00, 0x08, 0x80, 0x28,
-0x00, 0x08, 0x0c, 0x1c, 0x00, 0x08, 0x0e, 0x01,
-0x00, 0x08, 0xce, 0x00, 0x00, 0x06, 0x0f, 0x22,
-0x00, 0x0c, 0xa0, 0xc2, 0x00, 0x0c, 0x82, 0x7c,
-0x00, 0x00, 0x80, 0xa2, 0x00, 0x06, 0x47, 0x00,
-0x00, 0x08, 0xd0, 0x00, 0x00, 0x0c, 0xaa, 0x77,
-0x00, 0x08, 0x4c, 0x01, 0x00, 0x0d, 0x02, 0x85,
-0x00, 0x06, 0x5b, 0x00, 0x00, 0x0c, 0xa2, 0xbe,
-0x00, 0x08, 0x52, 0x00, 0x00, 0x08, 0x4c, 0x00,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0xd5,
-0x00, 0x09, 0x52, 0xe0, 0x00, 0x06, 0x2b, 0x01,
-0x00, 0x0c, 0xa0, 0xf0, 0x00, 0x08, 0x0c, 0x1c,
-0x00, 0x06, 0x2b, 0x03, 0x00, 0x0c, 0xa1, 0x01,
-0x00, 0x0c, 0x91, 0xff, 0x00, 0x08, 0x0e, 0x02,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x06, 0x8f, 0x01,
-0x00, 0x0c, 0xa8, 0xf8, 0x00, 0x08, 0xa6, 0x07,
-0x00, 0x08, 0x52, 0x20, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x06, 0xa7, 0x08, 0x00, 0x0c, 0xa9, 0x0c,
-0x00, 0x08, 0x34, 0x00, 0x00, 0x08, 0x36, 0x00,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00,
-0x00, 0x08, 0x8a, 0x2a, 0x00, 0x08, 0x48, 0x03,
-0x00, 0x08, 0x46, 0x06, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x23, 0x00, 0x06, 0x4d, 0x00,
-0x00, 0x0c, 0xa9, 0x66, 0x00, 0x0d, 0x01, 0x0c,
-0x00, 0x08, 0x0c, 0x01, 0x00, 0x06, 0x0d, 0x00,
-0x00, 0x0c, 0x80, 0xf6, 0x00, 0x08, 0x0c, 0x01,
-0x00, 0x08, 0x26, 0x11, 0x00, 0x0d, 0x01, 0x0e,
-0x00, 0x08, 0x26, 0x01, 0x00, 0x0d, 0x01, 0x0e,
-0x00, 0x06, 0xd9, 0x02, 0x00, 0x0c, 0xa1, 0x0c,
-0x00, 0x08, 0xa6, 0x07, 0x00, 0x08, 0x52, 0x00,
-0x00, 0x08, 0x46, 0x06, 0x00, 0x08, 0x48, 0x03,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x23,
-0x00, 0x0d, 0x01, 0x0c, 0x00, 0x08, 0x0e, 0x03,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x8f, 0x01,
-0x00, 0x0c, 0xa8, 0xf8, 0x00, 0x06, 0x8f, 0x04,
-0x00, 0x0c, 0xa1, 0x08, 0x00, 0x03, 0x01, 0x04,
-0x00, 0x06, 0x8f, 0x08, 0x00, 0x0c, 0xa1, 0x0b,
-0x00, 0x03, 0x01, 0x20, 0x00, 0x08, 0xd2, 0x00,
-0x00, 0x08, 0xa6, 0x07, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x06, 0xa7, 0x10, 0x00, 0x0c, 0xa1, 0x13,
-0x00, 0x08, 0x0c, 0x05, 0x00, 0x04, 0x8d, 0x0b,
-0x00, 0x09, 0x00, 0xc0, 0x00, 0x06, 0xa7, 0x08,
-0x00, 0x0c, 0xa1, 0x2f, 0x00, 0x08, 0x88, 0x17,
-0x00, 0x08, 0x8a, 0x1e, 0x00, 0x08, 0x84, 0x1f,
-0x00, 0x08, 0x80, 0x16, 0x00, 0x08, 0x86, 0x1a,
-0x00, 0x08, 0xc8, 0x02, 0x00, 0x08, 0xc6, 0x03,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x00,
-0x00, 0x08, 0x84, 0x1b, 0x00, 0x08, 0x80, 0x16,
-0x00, 0x08, 0xb4, 0x01, 0x00, 0x08, 0xc6, 0x02,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x00,
-0x00, 0x08, 0xb6, 0x01, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x06, 0xa7, 0x08, 0x00, 0x0c, 0xa1, 0x2f,
-0x00, 0x08, 0x82, 0x1b, 0x00, 0x08, 0x80, 0x1a,
-0x00, 0x08, 0x8a, 0x2a, 0x00, 0x08, 0x46, 0x06,
-0x00, 0x08, 0x48, 0x03, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x23, 0x00, 0x06, 0xa7, 0x04,
-0x00, 0x0c, 0xa1, 0x4e, 0x00, 0x06, 0x4d, 0x00,
-0x00, 0x0c, 0xa9, 0x44, 0x00, 0x08, 0x80, 0x18,
-0x00, 0x08, 0x88, 0x19, 0x00, 0x08, 0x8a, 0x20,
-0x00, 0x08, 0x84, 0x21, 0x00, 0x08, 0x86, 0x1c,
-0x00, 0x08, 0xc8, 0x02, 0x00, 0x08, 0xc6, 0x03,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x00,
-0x00, 0x08, 0xb8, 0x01, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x84, 0x1d, 0x00, 0x08, 0x80, 0x18,
-0x00, 0x08, 0xc6, 0x02, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x00, 0x00, 0x08, 0xba, 0x01,
-0x00, 0x0c, 0xc9, 0x44, 0x00, 0x08, 0x82, 0x1d,
-0x00, 0x08, 0x80, 0x1c, 0x00, 0x08, 0x8a, 0x2b,
-0x00, 0x08, 0x46, 0x06, 0x00, 0x08, 0x48, 0x00,
-0x00, 0x08, 0xfc, 0x3f, 0x00, 0x0d, 0x02, 0x23,
-0x00, 0x06, 0x4d, 0x00, 0x00, 0x0c, 0xa9, 0x66,
-0x00, 0x06, 0x4d, 0x00, 0x00, 0x0c, 0xa9, 0x58,
-0x00, 0x06, 0xa7, 0x02, 0x00, 0x08, 0x28, 0x00,
-0x00, 0x0c, 0xa1, 0x58, 0x00, 0x08, 0x0c, 0x1c,
-0x00, 0x08, 0x0e, 0x04, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0xa8, 0x07, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x06, 0xd9, 0x02, 0x00, 0x0c, 0xa1, 0x5c,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x5e,
-0x00, 0x08, 0x80, 0x13, 0x00, 0x01, 0x01, 0x01,
-0x00, 0x09, 0x00, 0xc1, 0x00, 0x06, 0xa7, 0x01,
-0x00, 0x0c, 0xa1, 0x66, 0x00, 0x08, 0x28, 0x3f,
-0x00, 0x08, 0x34, 0x00, 0x00, 0x08, 0x36, 0x00,
-0x00, 0x08, 0x38, 0x00, 0x00, 0x08, 0x3a, 0x00,
-0x00, 0x08, 0x46, 0x06, 0x00, 0x0c, 0xd9, 0x69,
-0x00, 0x0d, 0x01, 0xff, 0x00, 0x0c, 0xd1, 0x67,
-0x00, 0x0c, 0xc9, 0x6b, 0x00, 0x08, 0x00, 0x01,
-0x00, 0x01, 0x80, 0x23, 0x00, 0x06, 0xa7, 0x01,
-0x00, 0x08, 0xc6, 0x00, 0x00, 0x0c, 0xa1, 0xa5,
-0x00, 0x08, 0x0c, 0x1c, 0x00, 0x06, 0x47, 0x02,
-0x00, 0x0c, 0x81, 0x75, 0x00, 0x08, 0x0e, 0x06,
-0x00, 0x0d, 0x01, 0x76, 0x00, 0x08, 0x0e, 0x07,
-0x00, 0x08, 0x08, 0x00, 0x00, 0x06, 0x0f, 0x00,
-0x00, 0x0c, 0xa1, 0x85, 0x00, 0x08, 0xfa, 0x07,
-0x00, 0x08, 0x8c, 0x3d, 0x00, 0x05, 0x4f, 0x10,
-0x00, 0x04, 0xe9, 0x84, 0x00, 0x01, 0x90, 0x07,
-0x00, 0x03, 0xa2, 0x81, 0x00, 0x06, 0x88, 0x02,
-0x00, 0x0c, 0xa9, 0x85, 0x00, 0x08, 0x05, 0xff,
-0x00, 0x03, 0xaf, 0x82, 0x00, 0x02, 0x10, 0x04,
-0x00, 0x03, 0x15, 0x84, 0x00, 0x03, 0xc9, 0x03,
-0x00, 0x06, 0x47, 0x04, 0x00, 0x0c, 0x91, 0x96,
-0x00, 0x06, 0x47, 0x02, 0x00, 0x0c, 0x81, 0x96,
-0x00, 0x00, 0xc8, 0x48, 0x00, 0x0d, 0x01, 0x9f,
-0x00, 0x06, 0x47, 0x04, 0x00, 0x0c, 0x91, 0x8a,
-0x00, 0x06, 0x47, 0x01, 0x00, 0x0c, 0xa1, 0x93,
-0x00, 0x00, 0xc8, 0x4a, 0x00, 0x08, 0x94, 0x04,
-0x00, 0x0d, 0x01, 0xa0, 0x00, 0x00, 0xc8, 0x49,
-0x00, 0x08, 0x92, 0x04, 0x00, 0x0d, 0x01, 0xa0,
-0x00, 0x08, 0x84, 0x28, 0x00, 0x05, 0x14, 0x22,
-0x00, 0x06, 0x03, 0x01, 0x00, 0x0c, 0xa1, 0x8c,
-0x00, 0x00, 0xc8, 0x4d, 0x00, 0x06, 0x47, 0x01,
-0x00, 0x0c, 0xa1, 0x94, 0x00, 0x06, 0x47, 0x00,
-0x00, 0x0c, 0xa1, 0x91, 0x00, 0x08, 0x90, 0x04,
-0x00, 0x08, 0x0a, 0x80, 0x00, 0x06, 0xd9, 0x02,
-0x00, 0x0c, 0xa9, 0xcc, 0x00, 0x08, 0x8b, 0x44,
-0x00, 0x0d, 0x01, 0xbc, 0x00, 0x06, 0x47, 0x00,
-0x00, 0x0c, 0xa1, 0xaf, 0x00, 0x06, 0xd3, 0x20,
-0x00, 0x0c, 0xa1, 0xaf, 0x00, 0x08, 0x80, 0x1a,
-0x00, 0x08, 0x82, 0x1b, 0x00, 0x08, 0x8a, 0x2a,
-0x00, 0x08, 0x48, 0x03, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x23, 0x00, 0x06, 0x4d, 0x00,
-0x00, 0x0c, 0xa9, 0xd5, 0x00, 0x08, 0x80, 0x23,
-0x00, 0x03, 0x80, 0x81, 0x00, 0x06, 0x80, 0x14,
-0x00, 0x0c, 0xa1, 0xd5, 0x00, 0x08, 0x0c, 0x1c,
-0x00, 0x08, 0x0e, 0x08, 0x00, 0x08, 0x0a, 0x80,
-0x00, 0x00, 0xda, 0x3c, 0x00, 0x06, 0xd9, 0x02,
-0x00, 0x0c, 0xa9, 0xd1, 0x00, 0x08, 0x8b, 0x47,
-0x00, 0x08, 0x7a, 0x1c, 0x00, 0x08, 0x8c, 0x3d,
-0x00, 0x08, 0x0e, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x0c, 0xb1, 0xd5, 0x00, 0x00, 0xda, 0x3c,
-0x00, 0x02, 0x50, 0x05, 0x00, 0x08, 0x8b, 0xc7,
-0x00, 0x0c, 0xc1, 0xc0, 0x00, 0x08, 0x52, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x09, 0x52, 0xe0,
-0x00, 0x0c, 0xb1, 0xd5, 0x00, 0x08, 0x8c, 0x3d,
-0x00, 0x0c, 0xc1, 0xc8, 0x00, 0x0d, 0x01, 0xc8,
-0x00, 0x06, 0x47, 0x00, 0x00, 0x0c, 0xa1, 0xd1,
-0x00, 0x08, 0x48, 0x03, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x23, 0x00, 0x08, 0x7a, 0x1c,
-0x00, 0x08, 0x8c, 0x3d, 0x00, 0x08, 0x0e, 0x00,
-0x00, 0x0d, 0x01, 0xc8, 0x00, 0x06, 0x47, 0x00,
-0x00, 0x0c, 0xa1, 0xdf, 0x00, 0x06, 0xd3, 0x04,
-0x00, 0x0c, 0xa1, 0xdf, 0x00, 0x08, 0x80, 0x1c,
-0x00, 0x08, 0x82, 0x1d, 0x00, 0x08, 0x8a, 0x2b,
-0x00, 0x08, 0x48, 0x00, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x23, 0x00, 0x08, 0x82, 0x29,
-0x00, 0x01, 0x13, 0x24, 0x00, 0x06, 0x47, 0x00,
-0x00, 0x08, 0xd2, 0x01, 0x00, 0x0c, 0xa9, 0x67,
-0x00, 0x06, 0x4d, 0x00, 0x00, 0x0c, 0xaa, 0x8d,
-0x00, 0x06, 0xa7, 0x01, 0x00, 0x0c, 0xa1, 0xea,
-0x00, 0x08, 0x80, 0x28, 0x00, 0x08, 0xc4, 0x00,
-0x00, 0x08, 0x0c, 0x1c, 0x00, 0x08, 0x0e, 0x01,
-0x00, 0x08, 0x80, 0x28, 0x00, 0x06, 0x0f, 0x24,
-0x00, 0x0c, 0xa1, 0xf1, 0x00, 0x08, 0xce, 0x00,
-0x00, 0x0d, 0x00, 0xc5, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0x97, 0x00, 0x06, 0x01, 0x01,
-0x00, 0x0c, 0x81, 0xf7, 0x00, 0x06, 0x01, 0xaf,
-0x00, 0x0c, 0x88, 0xb3, 0x00, 0x06, 0x01, 0x00,
-0x00, 0x0c, 0xa0, 0x69, 0x00, 0x06, 0x01, 0xb8,
-0x00, 0x0c, 0xa0, 0x54, 0x00, 0x06, 0x01, 0xb3,
-0x00, 0x0c, 0xa0, 0x12, 0x00, 0x06, 0x01, 0xb7,
-0x00, 0x0c, 0xa2, 0xbe, 0x00, 0x0d, 0x00, 0x09,
-0x00, 0x08, 0x0c, 0x1c, 0x00, 0x08, 0x0e, 0x05,
-0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x86, 0x07,
-0x00, 0x03, 0x88, 0x81, 0x00, 0x06, 0x01, 0x01,
-0x00, 0x0c, 0xa2, 0x0f, 0x00, 0x06, 0x07, 0x00,
-0x00, 0x0c, 0xa2, 0x0f, 0x00, 0x08, 0xfa, 0x04,
-0x00, 0x08, 0x8c, 0x3d, 0x00, 0x05, 0x29, 0x10,
-0x00, 0x04, 0xe5, 0x82, 0x00, 0x05, 0x10, 0x81,
-0x00, 0x05, 0x23, 0x81, 0x00, 0x08, 0x04, 0x00,
-0x00, 0x03, 0xb9, 0x83, 0x00, 0x06, 0x07, 0x00,
-0x00, 0x0c, 0xa2, 0x1b, 0x00, 0x03, 0xa1, 0x05,
-0x00, 0x06, 0x07, 0x00, 0x00, 0x0c, 0x92, 0x19,
-0x00, 0x00, 0x97, 0x83, 0x00, 0x00, 0xa7, 0x82,
-0x00, 0x0d, 0x02, 0x1b, 0x00, 0x05, 0x17, 0x83,
-0x00, 0x05, 0x27, 0x82, 0x00, 0x00, 0x96, 0x23,
-0x00, 0x06, 0x02, 0x05, 0x00, 0x0c, 0x92, 0x21,
-0x00, 0x06, 0x48, 0x01, 0x00, 0x0c, 0x92, 0x21,
-0x00, 0x08, 0xfe, 0x3e, 0x00, 0x00, 0x94, 0x23,
-0x00, 0x08, 0xfe, 0x3e, 0x00, 0x06, 0xd9, 0x02,
-0x00, 0x0c, 0xa2, 0x27, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x08, 0x02, 0x00, 0x00, 0x06, 0x0b, 0x01,
-0x00, 0x0c, 0xaa, 0x2b, 0x00, 0x03, 0x81, 0x01,
-0x00, 0x03, 0x93, 0x01, 0x00, 0x06, 0x47, 0x02,
-0x00, 0x0c, 0x92, 0x41, 0x00, 0x06, 0x01, 0x00,
-0x00, 0x0c, 0x9a, 0x30, 0x00, 0x00, 0x81, 0x01,
-0x00, 0x04, 0x21, 0x01, 0x00, 0x04, 0x05, 0x01,
-0x00, 0x03, 0xc1, 0x01, 0x00, 0x05, 0x45, 0x82,
-0x00, 0x06, 0x03, 0x00, 0x00, 0x0c, 0x9a, 0x37,
-0x00, 0x00, 0x93, 0x01, 0x00, 0x04, 0x33, 0x01,
-0x00, 0x04, 0x17, 0x01, 0x00, 0x03, 0xc3, 0x01,
-0x00, 0x05, 0x47, 0x83, 0x00, 0x08, 0x0a, 0x03,
-0x00, 0x03, 0xca, 0x11, 0x00, 0x00, 0xc1, 0x80,
-0x00, 0x03, 0xca, 0x12, 0x00, 0x00, 0xc3, 0x81,
-0x00, 0x0d, 0x02, 0x4a, 0x00, 0x01, 0x21, 0x01,
-0x00, 0x04, 0x01, 0x01, 0x00, 0x01, 0x33, 0x01,
-0x00, 0x04, 0x13, 0x01, 0x00, 0x08, 0x0a, 0x04,
-0x00, 0x03, 0xca, 0x11, 0x00, 0x00, 0xc1, 0x80,
-0x00, 0x03, 0xca, 0x12, 0x00, 0x00, 0xc3, 0x81,
-0x00, 0x08, 0x88, 0x29, 0x00, 0x03, 0xa4, 0x64,
-0x00, 0x03, 0x45, 0x84, 0x00, 0x02, 0x50, 0x24,
-0x00, 0x03, 0xbb, 0x83, 0x00, 0x03, 0x47, 0x84,
-0x00, 0x01, 0x28, 0xa4, 0x00, 0x06, 0x05, 0x24,
-0x00, 0x0c, 0xaa, 0x58, 0x00, 0x06, 0x49, 0x00,
-0x00, 0x0c, 0xaa, 0x58, 0x00, 0x0c, 0xda, 0x57,
-0x00, 0x0d, 0x01, 0xff, 0x00, 0x0c, 0xca, 0x55,
-0x00, 0x06, 0xd9, 0x02, 0x00, 0x0c, 0xa2, 0x5f,
-0x00, 0x06, 0x6d, 0x00, 0x00, 0x0c, 0xa2, 0x5e,
-0x00, 0x08, 0x08, 0x04, 0x00, 0x0d, 0x02, 0x5f,
-0x00, 0x08, 0x08, 0x20, 0x00, 0x08, 0xd2, 0x04,
-0x00, 0x09, 0x08, 0xe0, 0x00, 0x01, 0xc0, 0x23,
-0x00, 0x03, 0xc9, 0x01, 0x00, 0x08, 0x0a, 0x26,
-0x00, 0x03, 0xdb, 0x04, 0x00, 0x03, 0x5b, 0x08,
-0x00, 0x00, 0xd9, 0x84, 0x00, 0x08, 0xfe, 0x04,
-0x00, 0x0d, 0x02, 0x72, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x0d, 0x02, 0x72, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x00, 0x81, 0x08, 0x00, 0x0d, 0x02, 0x75,
-0x00, 0x00, 0x93, 0x08, 0x00, 0x0d, 0x02, 0x72,
-0x00, 0x00, 0x81, 0x08, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x09, 0x00, 0xe1, 0x00, 0x09, 0x02, 0xe2,
-0x00, 0x08, 0xfe, 0x3e, 0x00, 0x00, 0x93, 0x08,
-0x00, 0x0d, 0x02, 0x72, 0x00, 0x08, 0x0c, 0x1c,
-0x00, 0x08, 0x0e, 0x01, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x06, 0x0f, 0x23, 0x00, 0x0c, 0xa0, 0xc8,
-0x00, 0x08, 0x82, 0x28, 0x00, 0x08, 0xce, 0x01,
-0x00, 0x00, 0xf3, 0x80, 0x00, 0x08, 0xd0, 0x00,
-0x00, 0x06, 0x0f, 0x01, 0x00, 0x0c, 0xa0, 0xce,
-0x00, 0x06, 0x47, 0x00, 0x00, 0x0c, 0xa8, 0xce,
-0x00, 0x08, 0x4c, 0x02, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x09, 0x00, 0xc1, 0x00, 0x08, 0xfc, 0x3f,
-0x00, 0x0d, 0x02, 0xd5, 0x00, 0x06, 0x2b, 0x02,
-0x00, 0x0c, 0xa9, 0x26, 0x00, 0x08, 0x26, 0x00,
-0x00, 0x0d, 0x00, 0xe0, 0x00, 0x02, 0x00, 0x27,
-0x00, 0x02, 0x10, 0x00, 0x00, 0x06, 0x50, 0x01,
-0x00, 0x08, 0xce, 0x00, 0x00, 0x0c, 0x92, 0x85,
-0x00, 0x06, 0x4d, 0x01, 0x00, 0x0c, 0xa2, 0x77,
-0x00, 0x0d, 0x00, 0xce, 0x00, 0x06, 0x01, 0xb2,
-0x00, 0x0c, 0xaa, 0xa7, 0x00, 0x08, 0x0d, 0x08,
-0x00, 0x06, 0x0d, 0x00, 0x00, 0x0c, 0xaa, 0x97,
-0x00, 0x08, 0x0c, 0x08, 0x00, 0x04, 0x8d, 0x08,
-0x00, 0x0c, 0xaa, 0x97, 0x00, 0x08, 0x0c, 0x10,
-0x00, 0x06, 0x0d, 0x00, 0x00, 0x0c, 0xa2, 0x9d,
-0x00, 0x06, 0x0d, 0x01, 0x00, 0x0c, 0xa2, 0xa8,
-0x00, 0x04, 0x8d, 0x08, 0x00, 0x06, 0x01, 0x01,
-0x00, 0x0c, 0xaa, 0x97, 0x00, 0x03, 0x8d, 0x08,
-0x00, 0x04, 0x81, 0x08, 0x00, 0x08, 0xfe, 0x3e,
-0x00, 0x08, 0x0c, 0x08, 0x00, 0x04, 0x8d, 0x08,
-0x00, 0x08, 0xfe, 0x3e, 0x00, 0x08, 0x0c, 0x01,
-0x00, 0x04, 0xad, 0x0f, 0x00, 0x08, 0x0c, 0x03,
-0x00, 0x04, 0x8d, 0x0d, 0x00, 0x06, 0x67, 0xff,
-0x00, 0x0c, 0xa2, 0xba, 0x00, 0x08, 0x82, 0x33,
-0x00, 0x05, 0x92, 0x34, 0x00, 0x01, 0x13, 0x1f,
-0x00, 0x02, 0x10, 0x01, 0x00, 0x00, 0x83, 0x80,
-0x00, 0x06, 0x01, 0x07, 0x00, 0x0c, 0x8a, 0xba,
-0x00, 0x05, 0x00, 0x87, 0x00, 0x0d, 0x02, 0xb6,
-0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xb0, 0x81,
-0x00, 0x03, 0xc7, 0x04, 0x00, 0x08, 0xfe, 0x3e,
-0x00, 0x06, 0x5b, 0x01, 0x00, 0x0c, 0xa2, 0xc2,
-0x00, 0x09, 0x00, 0xe8, 0x00, 0x0d, 0x00, 0x01,
-0x00, 0x0c, 0xda, 0xc2, 0x00, 0x08, 0x5a, 0x00,
-0x00, 0x08, 0x23, 0xff, 0x00, 0x08, 0x24, 0x00,
-0x00, 0x08, 0x4e, 0x00, 0x00, 0x08, 0x2a, 0x02,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x2a, 0xe7,
-0x00, 0x08, 0x82, 0x10, 0x00, 0x00, 0x80, 0x71,
-0x00, 0x01, 0x90, 0x01, 0x00, 0x0c, 0xaa, 0xcb,
-0x00, 0x02, 0x01, 0xa8, 0x00, 0x08, 0x4c, 0x02,
-0x00, 0x0d, 0x02, 0x85, 0x00, 0x08, 0xe4, 0x33,
-0x00, 0x08, 0x60, 0x00, 0x00, 0x08, 0x6a, 0x01,
-0x00, 0x0d, 0x00, 0x2f, 0x00, 0x02, 0x00, 0x11,
-0x00, 0x06, 0x20, 0x00, 0x00, 0x08, 0xa2, 0x00,
-0x00, 0x0c, 0x92, 0xdd, 0x00, 0x02, 0x00, 0x12,
-0x00, 0x08, 0x22, 0x00, 0x00, 0x08, 0xa4, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0xfe, 0x3e,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x80, 0x00,
-0x0a, 0x0d,
-};
-static uchar
-zrmpeg2[] = {
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0xc1, 0x81,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x2e, 0x01,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x47, 0x17,
-0x00, 0x03, 0x2e, 0x02, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x03, 0x74, 0x17, 0x00, 0x02, 0x9c, 0x02,
-0x00, 0x03, 0x88, 0x0c, 0x00, 0x03, 0x46, 0x81,
-0x00, 0x03, 0x50, 0x07, 0x00, 0x02, 0x80, 0x80,
-0x00, 0x03, 0x88, 0x13, 0x00, 0x03, 0x43, 0x81,
-0x00, 0x02, 0x9c, 0x01, 0x00, 0x03, 0x88, 0x14,
-0x00, 0x03, 0x48, 0x80, 0x00, 0x03, 0x40, 0x80,
-0x00, 0x02, 0x9c, 0x80, 0x00, 0x03, 0x88, 0x17,
-0x00, 0x03, 0x44, 0x81, 0x00, 0x02, 0x9c, 0x04,
-0x00, 0x03, 0x88, 0x1a, 0x00, 0x03, 0x45, 0x81,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x50, 0x17,
-0x00, 0x00, 0x5c, 0x8f, 0x00, 0x02, 0x84, 0x01,
-0x00, 0x03, 0x88, 0x20, 0x00, 0x03, 0x49, 0x81,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x00, 0x5d, 0x0f,
-0x00, 0x00, 0xc9, 0x04, 0x00, 0x03, 0x4d, 0x12,
-0x00, 0x00, 0xa4, 0x2d, 0x00, 0x02, 0xe8, 0x00,
-0x00, 0x02, 0x80, 0x01, 0x00, 0x03, 0x8a, 0x29,
-0x00, 0x02, 0xe8, 0x01, 0x00, 0x03, 0x4d, 0x14,
-0x00, 0x00, 0x41, 0x10, 0x00, 0x01, 0x49, 0x02,
-0x00, 0x00, 0xab, 0x6d, 0x00, 0x00, 0x41, 0x20,
-0x00, 0x01, 0x49, 0x02, 0x00, 0x00, 0xaa, 0x0d,
-0x00, 0x02, 0x9c, 0x01, 0x00, 0x03, 0x8a, 0x33,
-0x00, 0x00, 0x92, 0x10, 0x00, 0x03, 0x4d, 0x14,
-0x00, 0x00, 0x5d, 0x10, 0x00, 0x00, 0xc9, 0x02,
-0x00, 0x00, 0xab, 0x6d, 0x00, 0x00, 0x5d, 0x20,
-0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0xaa, 0x0d,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x28, 0x5f,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x42, 0x17,
-0x00, 0x03, 0x2e, 0x20, 0x00, 0x01, 0xdc, 0x01,
-0x00, 0x03, 0xa6, 0x43, 0x00, 0x03, 0x4d, 0x17,
-0x00, 0x00, 0x20, 0x0d, 0x00, 0x03, 0x20, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x2e, 0x21,
-0x00, 0x00, 0x3c, 0x02, 0x00, 0x03, 0x20, 0x24,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x75, 0x17,
-0x00, 0x03, 0x2e, 0x68, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x03, 0x43, 0x17, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x03, 0x44, 0x17, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x03, 0x45, 0x17, 0x00, 0x00, 0x1c, 0x01,
-0x00, 0x03, 0x46, 0x10, 0x00, 0x00, 0x20, 0x02,
-0x00, 0x03, 0x47, 0x10, 0x00, 0x00, 0x22, 0x23,
-0x00, 0x00, 0x20, 0x02, 0x00, 0x03, 0x49, 0x10,
-0x00, 0x00, 0x23, 0xa3, 0x00, 0x03, 0x50, 0x35,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x04,
-0x00, 0x03, 0xa6, 0x5e, 0x00, 0x01, 0xe0, 0x02,
-0x00, 0x03, 0x4f, 0x10, 0x00, 0x00, 0x20, 0x02,
-0x00, 0x03, 0x58, 0x10, 0x00, 0x03, 0x50, 0x35,
-0x00, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x01,
-0x00, 0x00, 0x20, 0x83, 0x00, 0x03, 0x59, 0x11,
-0x00, 0x01, 0xe0, 0x84, 0x00, 0x03, 0x5a, 0x11,
-0x00, 0x02, 0xe2, 0x01, 0x00, 0x00, 0x26, 0x83,
-0x00, 0x00, 0x36, 0xa5, 0x00, 0x03, 0x14, 0x69,
-0x00, 0x03, 0x10, 0x6a, 0x00, 0x03, 0xa6, 0x6f,
-0x00, 0x03, 0x1c, 0x6a, 0x00, 0x03, 0x1e, 0x6b,
-0x00, 0x03, 0xa6, 0x72, 0x00, 0x03, 0x30, 0x6b,
-0x00, 0x03, 0x2a, 0x6c, 0x00, 0x03, 0xa8, 0x77,
-0x00, 0x03, 0x0e, 0x6c, 0x00, 0x03, 0xa6, 0x77,
-0x00, 0x03, 0x12, 0x6c, 0x00, 0x03, 0x32, 0x6d,
-0x00, 0x03, 0x34, 0x6e, 0x00, 0x03, 0xa8, 0x7c,
-0x00, 0x03, 0x0c, 0x6d, 0x00, 0x03, 0x2a, 0x6e,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x42, 0x17,
-0x00, 0x03, 0x2e, 0x22, 0x00, 0x00, 0x1c, 0x01,
-0x00, 0x01, 0x40, 0x01, 0x00, 0x00, 0xc0, 0x01,
-0x00, 0x03, 0x20, 0x18, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x03, 0x73, 0x17, 0x00, 0x03, 0x2e, 0x23,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x76, 0x17,
-0x00, 0x03, 0x2e, 0x60, 0x00, 0x01, 0x5f, 0x01,
-0x00, 0x02, 0x9c, 0x01, 0x00, 0x03, 0x88, 0x8d,
-0x00, 0x03, 0x41, 0x81, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x03, 0x43, 0x17, 0x00, 0x03, 0x2e, 0x61,
-0x00, 0x02, 0x9c, 0x01, 0x00, 0x03, 0x88, 0x94,
-0x00, 0x03, 0x42, 0x81, 0x00, 0x03, 0x47, 0x80,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x44, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x45, 0x17,
-0x00, 0x03, 0x4d, 0x33, 0x00, 0x01, 0xff, 0x2d,
-0x00, 0x03, 0x73, 0x0c, 0x00, 0x03, 0x5b, 0x1f,
-0x00, 0x03, 0x8f, 0x94, 0x00, 0x03, 0x4d, 0x36,
-0x00, 0x03, 0x50, 0x05, 0x00, 0x00, 0x20, 0x02,
-0x00, 0x03, 0x51, 0x03, 0x00, 0x00, 0x24, 0x84,
-0x00, 0x03, 0xa6, 0xa7, 0x00, 0x00, 0xc0, 0x01,
-0x00, 0x01, 0xa3, 0x6d, 0x00, 0x01, 0xa7, 0x6d,
-0x00, 0x03, 0x8e, 0xab, 0x00, 0x01, 0xa0, 0x0d,
-0x00, 0x00, 0xc0, 0x01, 0x00, 0x03, 0x4d, 0x11,
-0x00, 0x01, 0xe3, 0x6d, 0x00, 0x03, 0x72, 0x0d,
-0x00, 0x00, 0x1c, 0x81, 0x00, 0x03, 0x41, 0x11,
-0x00, 0x00, 0x3d, 0xa2, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x00, 0x1f, 0x81, 0x00, 0x03, 0x2e, 0x6f,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x4c, 0x17,
-0x00, 0x03, 0x51, 0x03, 0x00, 0x01, 0x45, 0x01,
-0x00, 0x00, 0x28, 0x86, 0x00, 0x03, 0x47, 0x11,
-0x00, 0x00, 0x06, 0x01, 0x00, 0x03, 0x51, 0x06,
-0x00, 0x00, 0xc4, 0x81, 0x00, 0x03, 0x48, 0x11,
-0x00, 0x00, 0x26, 0x63, 0x00, 0x00, 0x08, 0x81,
-0x00, 0x03, 0x4e, 0x11, 0x00, 0x00, 0x28, 0x05,
-0x00, 0x03, 0x4f, 0x10, 0x00, 0x00, 0x00, 0x01,
-0x00, 0x03, 0x71, 0x10, 0x00, 0x03, 0x50, 0x05,
-0x00, 0x00, 0xc1, 0x81, 0x00, 0x03, 0x4b, 0x13,
-0x00, 0x00, 0x2c, 0x03, 0x00, 0x03, 0x58, 0x10,
-0x00, 0x03, 0x50, 0x36, 0x00, 0x01, 0x41, 0x81,
-0x00, 0x03, 0x4d, 0x13, 0x00, 0x03, 0x52, 0x04,
-0x00, 0x01, 0x48, 0x81, 0x00, 0x01, 0xa5, 0x0d,
-0x00, 0x01, 0xca, 0x81, 0x00, 0x03, 0x53, 0x32,
-0x00, 0x00, 0x2d, 0x08, 0x00, 0x00, 0x29, 0x03,
-0x00, 0x01, 0xc9, 0x01, 0x00, 0x03, 0x56, 0x12,
-0x00, 0x03, 0x52, 0x31, 0x00, 0x00, 0x2b, 0x62,
-0x00, 0x01, 0x4d, 0x81, 0x00, 0x00, 0x2d, 0x8d,
-0x00, 0x03, 0x5a, 0x13, 0x00, 0x01, 0xcd, 0x81,
-0x00, 0x03, 0x59, 0x13, 0x00, 0x01, 0xc0, 0x01,
-0x00, 0x03, 0x4d, 0x11, 0x00, 0x01, 0xe2, 0xad,
-0x00, 0x03, 0x18, 0x62, 0x00, 0x03, 0x1c, 0x63,
-0x00, 0x03, 0x1e, 0x64, 0x00, 0x03, 0x0e, 0x65,
-0x00, 0x03, 0x32, 0x66, 0x00, 0x03, 0xa6, 0xed,
-0x00, 0x03, 0xa8, 0xf2, 0x00, 0x03, 0xa3, 0x03,
-0x00, 0x03, 0xab, 0x09, 0x00, 0x03, 0x0a, 0x62,
-0x00, 0x03, 0x50, 0x31, 0x00, 0x03, 0x20, 0x64,
-0x00, 0x03, 0x28, 0x65, 0x00, 0x03, 0x34, 0x66,
-0x00, 0x03, 0x8f, 0x0c, 0x00, 0x03, 0xa9, 0x0c,
-0x00, 0x03, 0xaa, 0xfb, 0x00, 0x03, 0xa2, 0xfe,
-0x00, 0x03, 0x02, 0x62, 0x00, 0x03, 0x8f, 0x0c,
-0x00, 0x03, 0xa2, 0xf6, 0x00, 0x03, 0xa5, 0x0c,
-0x00, 0x03, 0x2a, 0x66, 0x00, 0x03, 0x8f, 0x0c,
-0x00, 0x03, 0x30, 0x63, 0x00, 0x03, 0x12, 0x64,
-0x00, 0x03, 0x2c, 0x65, 0x00, 0x03, 0x2a, 0x66,
-0x00, 0x03, 0x8f, 0x0c, 0x00, 0x03, 0x02, 0x62,
-0x00, 0x03, 0x0c, 0x65, 0x00, 0x03, 0x8f, 0x0c,
-0x00, 0x03, 0x0a, 0x62, 0x00, 0x03, 0x30, 0x64,
-0x00, 0x03, 0x12, 0x65, 0x00, 0x03, 0x2c, 0x66,
-0x00, 0x03, 0x8f, 0x0c, 0x00, 0x03, 0x0a, 0x62,
-0x00, 0x03, 0x30, 0x63, 0x00, 0x03, 0x12, 0x64,
-0x00, 0x03, 0x2c, 0x65, 0x00, 0x03, 0x16, 0x66,
-0x00, 0x03, 0x8f, 0x0c, 0x00, 0x03, 0x02, 0x62,
-0x00, 0x03, 0x0c, 0x65, 0x00, 0x03, 0x34, 0x66,
-0x00, 0x03, 0x14, 0x67, 0x00, 0x03, 0xa9, 0x0f,
-0x00, 0x03, 0x10, 0x67, 0x00, 0x03, 0x4c, 0x1f,
-0x00, 0x03, 0x8f, 0x86, 0x00, 0x02, 0xda, 0x44,
-0x00, 0x02, 0xe2, 0x01, 0x00, 0x02, 0xe0, 0x04,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x4d, 0x57,
-0x00, 0x00, 0x27, 0x6d, 0x00, 0x01, 0xc0, 0x01,
-0x00, 0x03, 0x8b, 0x14, 0x00, 0x02, 0xe0, 0x04,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x01, 0x5d, 0x0a,
-0x00, 0x03, 0x4d, 0x52, 0x00, 0x00, 0x27, 0x6d,
-0x00, 0x03, 0x4d, 0x57, 0x00, 0x00, 0x27, 0x6d,
-0x00, 0x01, 0xc0, 0x01, 0x00, 0x03, 0x8b, 0x1a,
-0x00, 0x02, 0xe0, 0x06, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x03, 0x4d, 0x57, 0x00, 0x00, 0x27, 0x6d,
-0x00, 0x01, 0xc0, 0x01, 0x00, 0x03, 0x8b, 0x23,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x2e, 0x56,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x2e, 0x57,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x71, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x72, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x77, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x41, 0x17,
-0x00, 0x03, 0xa1, 0x36, 0x00, 0x01, 0x5f, 0x82,
-0x00, 0x02, 0xf1, 0x75, 0x00, 0x03, 0x59, 0x17,
-0x00, 0x03, 0x5b, 0x1f, 0x00, 0x03, 0x8f, 0xc5,
-0x00, 0x00, 0xc4, 0x89, 0x00, 0x01, 0x40, 0x07,
-0x00, 0x03, 0x4d, 0x10, 0x00, 0x00, 0xa4, 0x0d,
-0x00, 0x03, 0x73, 0x10, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x03, 0x50, 0x34, 0x00, 0x03, 0x20, 0x03,
-0x00, 0x02, 0xe4, 0x00, 0x00, 0x03, 0x53, 0x00,
-0x00, 0x03, 0xb3, 0x48, 0x00, 0x01, 0x4d, 0x84,
-0x00, 0x02, 0x8c, 0x01, 0x00, 0x03, 0x89, 0x50,
-0x00, 0x00, 0x4c, 0x0e, 0x00, 0x01, 0x40, 0x01,
-0x00, 0x02, 0x40, 0x05, 0x00, 0x03, 0x81, 0x50,
-0x00, 0x02, 0xe4, 0x01, 0x00, 0x02, 0x40, 0x03,
-0x00, 0x03, 0x81, 0x50, 0x00, 0x02, 0xe4, 0x02,
-0x00, 0x03, 0x75, 0x12, 0x00, 0x02, 0xe0, 0x00,
-0x00, 0x03, 0x76, 0x10, 0x00, 0x02, 0x48, 0x02,
-0x00, 0x03, 0x85, 0x70, 0x00, 0x03, 0x59, 0x37,
-0x00, 0x03, 0x50, 0x33, 0x00, 0x01, 0x40, 0x02,
-0x00, 0x03, 0x58, 0x10, 0x00, 0x03, 0x5b, 0x1f,
-0x00, 0x03, 0x8f, 0xc5, 0x00, 0x00, 0xc4, 0x81,
-0x00, 0x01, 0x40, 0x0f, 0x00, 0x03, 0x4d, 0x10,
-0x00, 0x00, 0xa4, 0x0d, 0x00, 0x00, 0x23, 0xaf,
-0x00, 0x03, 0x59, 0x31, 0x00, 0x03, 0xb3, 0x63,
-0x00, 0x03, 0x59, 0x32, 0x00, 0x03, 0x4c, 0x1f,
-0x00, 0x03, 0x8f, 0x7c, 0x00, 0x03, 0x72, 0x10,
-0x00, 0x03, 0x4b, 0x0e, 0x00, 0x02, 0x60, 0x0e,
-0x00, 0x03, 0x85, 0x6a, 0x00, 0x03, 0x4b, 0x10,
-0x00, 0x03, 0x50, 0x0e, 0x00, 0x01, 0xa0, 0x0b,
-0x00, 0x03, 0x76, 0x10, 0x00, 0x03, 0x51, 0x32,
-0x00, 0x01, 0xa4, 0x8b, 0x00, 0x03, 0x72, 0x11,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x4a, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x4b, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x4b, 0x17,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x45, 0x17,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x8f, 0x7a,
-0x00, 0x03, 0x50, 0x33, 0x00, 0x01, 0x40, 0x02,
-0x00, 0x03, 0x58, 0x10, 0x00, 0x03, 0x5b, 0x1f,
-0x00, 0x03, 0x8f, 0xc5, 0x00, 0x00, 0xc4, 0x81,
-0x00, 0x01, 0x40, 0x0f, 0x00, 0x03, 0x4d, 0x10,
-0x00, 0x03, 0x5f, 0x0c, 0x00, 0x00, 0xa4, 0x0d,
-0x00, 0x03, 0x58, 0x35, 0x00, 0x03, 0x59, 0x36,
-0x00, 0x03, 0x5b, 0x1f, 0x00, 0x03, 0x8f, 0xc5,
-0x00, 0x00, 0xc4, 0x89, 0x00, 0x01, 0x40, 0x07,
-0x00, 0x03, 0x4d, 0x10, 0x00, 0x00, 0xa4, 0x0d,
-0x00, 0x03, 0xa1, 0x90, 0x00, 0x01, 0x40, 0x02,
-0x00, 0x03, 0xb1, 0x92, 0x00, 0x00, 0xc0, 0x02,
-0x00, 0x03, 0x5f, 0x0c, 0x00, 0x03, 0x4f, 0x10,
-0x00, 0x03, 0xa7, 0x96, 0x00, 0x02, 0xec, 0x0f,
-0x00, 0x03, 0x4c, 0x33, 0x00, 0x00, 0x3b, 0x0c,
-0x00, 0x03, 0x87, 0x9a, 0x00, 0x02, 0xec, 0x00,
-0x00, 0x03, 0x4d, 0x16, 0x00, 0x00, 0xd8, 0x01,
-0x00, 0x00, 0x22, 0x03, 0x00, 0x03, 0x52, 0x03,
-0x00, 0x01, 0x49, 0x01, 0x00, 0x00, 0x2a, 0x8d,
-0x00, 0x03, 0x50, 0x15, 0x00, 0x03, 0xa9, 0xbf,
-0x00, 0x03, 0xa7, 0xb5, 0x00, 0x03, 0xab, 0xb0,
-0x00, 0x03, 0xad, 0xab, 0x00, 0x03, 0xa3, 0xa8,
-0x00, 0x03, 0xa5, 0xc2, 0x00, 0x03, 0x8f, 0xc3,
-0x00, 0x03, 0x50, 0x14, 0x00, 0x03, 0xa5, 0xc3,
-0x00, 0x03, 0x8f, 0xc2, 0x00, 0x03, 0xa3, 0xae,
-0x00, 0x03, 0xaf, 0xc3, 0x00, 0x03, 0x8f, 0xc2,
-0x00, 0x03, 0x50, 0x14, 0x00, 0x03, 0x8f, 0xc2,
-0x00, 0x03, 0x50, 0x16, 0x00, 0x03, 0xa3, 0xb3,
-0x00, 0x03, 0x8f, 0xc3, 0x00, 0x00, 0xc0, 0x01,
-0x00, 0x03, 0x8f, 0xc2, 0x00, 0x03, 0xab, 0xbc,
-0x00, 0x03, 0xa3, 0xb9, 0x00, 0x03, 0xaf, 0xc3,
-0x00, 0x03, 0x8f, 0xc2, 0x00, 0x03, 0x50, 0x14,
-0x00, 0x03, 0xaf, 0xc3, 0x00, 0x03, 0x8f, 0xc2,
-0x00, 0x03, 0x50, 0x16, 0x00, 0x01, 0xc0, 0x01,
-0x00, 0x03, 0x8f, 0xc3, 0x00, 0x03, 0xa7, 0xc1,
-0x00, 0x03, 0x8f, 0xa4, 0x00, 0x03, 0xaf, 0xc3,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x5f, 0x1b,
-0x00, 0x03, 0x20, 0x70, 0x00, 0x02, 0xe4, 0x01,
-0x00, 0x02, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x0f,
-0x00, 0x03, 0x5a, 0x10, 0x00, 0x02, 0xe0, 0x00,
-0x00, 0x02, 0xe2, 0x00, 0x00, 0x02, 0xa8, 0x19,
-0x00, 0x03, 0x89, 0xce, 0x00, 0x00, 0x24, 0x98,
-0x00, 0x01, 0x40, 0x01, 0x00, 0x02, 0x84, 0x01,
-0x00, 0x03, 0x89, 0xd2, 0x00, 0x00, 0xa0, 0x1a,
-0x00, 0x01, 0x44, 0x81, 0x00, 0x00, 0xc9, 0x01,
-0x00, 0x03, 0x8b, 0xcb, 0x00, 0x03, 0x5f, 0x1b,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x0a, 0x0d,
-};
-static uchar
-zrmpeg3s[] = {
-0x00, 0x03, 0x8e, 0x00, 0x00, 0x03, 0xc0, 0x0a,
-0x00, 0x03, 0x50, 0x0b, 0x00, 0x01, 0x40, 0x08,
-0x00, 0x02, 0x80, 0x02, 0x00, 0x03, 0x8a, 0x07,
-0x00, 0x02, 0xca, 0x00, 0x00, 0x02, 0x80, 0x01,
-0x00, 0x03, 0x8a, 0x0a, 0x00, 0x02, 0xd6, 0xe0,
-0x00, 0x02, 0xce, 0x00, 0x00, 0x03, 0x4c, 0x80,
-0x00, 0x02, 0xde, 0x04, 0x00, 0x02, 0xc2, 0x00,
-0x00, 0x02, 0xd2, 0x00, 0x00, 0x02, 0xf8, 0x00,
-0x00, 0x03, 0x5d, 0x10, 0x00, 0x03, 0x5b, 0x1f,
-0x00, 0x03, 0x8f, 0x8c, 0x00, 0x03, 0x88, 0x1d,
-0x00, 0x02, 0x5c, 0xfa, 0x00, 0x03, 0x8a, 0x11,
-0x00, 0x02, 0xe8, 0x46, 0x00, 0x02, 0xf8, 0x00,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x5d, 0x17,
-0x00, 0x01, 0xd2, 0x01, 0x00, 0x03, 0x8a, 0x18,
-0x00, 0x03, 0x8e, 0x11, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x03, 0x5b, 0x1f, 0x00, 0x03, 0x8f, 0xd2,
-0x00, 0x03, 0xa0, 0x22, 0x00, 0x03, 0x46, 0x17,
-0x00, 0x03, 0x5b, 0x1f, 0x00, 0x03, 0x8f, 0x8c,
-0x00, 0x02, 0x5c, 0xbb, 0x00, 0x03, 0x8a, 0x29,
-0x00, 0x03, 0x5b, 0x1f, 0x00, 0x03, 0x8f, 0x8c,
-0x00, 0x03, 0x88, 0x1d, 0x00, 0x02, 0x5c, 0xb9,
-0x00, 0x03, 0x89, 0x00, 0x00, 0x02, 0x5c, 0xbc,
-0x00, 0x03, 0x84, 0x26, 0x00, 0x03, 0x50, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x54, 0x17,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x01, 0xd2, 0x01,
-0x00, 0x02, 0x5c, 0xff, 0x00, 0x03, 0x88, 0x30,
-0x00, 0x01, 0x5d, 0x06, 0x00, 0x02, 0x48, 0x01,
-0x00, 0x03, 0x8a, 0x3a, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x01, 0xd2, 0x02, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x01, 0x5d, 0x04, 0x00, 0x03, 0x88, 0x46,
-0x00, 0x03, 0x5b, 0x1f, 0x00, 0x03, 0x8f, 0xd2,
-0x00, 0x03, 0x44, 0x17, 0x00, 0x01, 0xd2, 0x04,
-0x00, 0x02, 0x48, 0x03, 0x00, 0x03, 0x8a, 0x46,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x03, 0x5b, 0x1f,
-0x00, 0x03, 0x8f, 0xd2, 0x00, 0x01, 0xd2, 0x05,
-0x00, 0x02, 0x50, 0x05, 0x00, 0x03, 0x86, 0x26,
-0x00, 0x02, 0xe2, 0xff, 0x00, 0x00, 0x67, 0x6b,
-0x00, 0x02, 0x60, 0x0d, 0x00, 0x03, 0x85, 0xfa,
-0x00, 0x03, 0xb2, 0xab, 0x00, 0x02, 0x88, 0x02,
-0x00, 0x03, 0x89, 0x16, 0x00, 0x03, 0x42, 0x17,
-0x00, 0x03, 0x8e, 0xa0, 0x00, 0x02, 0x88, 0x02,
-0x00, 0x03, 0x89, 0x16, 0x00, 0x03, 0x55, 0x00,
-0x00, 0x02, 0x94, 0x01, 0x00, 0x03, 0x88, 0x5a,
-0x00, 0x01, 0x57, 0x01, 0x00, 0x00, 0x5b, 0x07,
-0x00, 0x03, 0xb5, 0x16, 0x00, 0x03, 0x8e, 0x5f,
-0x00, 0x02, 0x94, 0x10, 0x00, 0x03, 0x89, 0x16,
-0x00, 0x01, 0x57, 0x05, 0x00, 0x00, 0x5b, 0x07,
-0x00, 0x03, 0xb7, 0x16, 0x00, 0x01, 0x41, 0x05,
-0x00, 0x02, 0x48, 0x06, 0x00, 0x03, 0x8b, 0x16,
-0x00, 0x02, 0x58, 0x00, 0x00, 0x03, 0x8b, 0x16,
-0x00, 0x03, 0x55, 0x00, 0x00, 0x02, 0x94, 0x01,
-0x00, 0x03, 0x8a, 0x69, 0x00, 0x03, 0x4b, 0x81,
-0x00, 0x03, 0x8e, 0x6a, 0x00, 0x03, 0x4a, 0x81,
-0x00, 0x03, 0x45, 0x10, 0x00, 0x03, 0xa0, 0x6e,
-0x00, 0x03, 0x40, 0x81, 0x00, 0x03, 0x22, 0x16,
-0x00, 0x03, 0x50, 0x35, 0x00, 0x02, 0x40, 0x01,
-0x00, 0x03, 0x80, 0x75, 0x00, 0x03, 0x84, 0x7d,
-0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0xe2, 0x00,
-0x00, 0x03, 0x8e, 0x79, 0x00, 0x03, 0x4d, 0x32,
-0x00, 0x03, 0x50, 0x04, 0x00, 0x03, 0x4c, 0x1f,
-0x00, 0x03, 0x8f, 0x83, 0x00, 0x03, 0x20, 0x10,
-0x00, 0x03, 0x22, 0x11, 0x00, 0x03, 0x20, 0x12,
-0x00, 0x03, 0x22, 0x13, 0x00, 0x03, 0xb4, 0x80,
-0x00, 0x03, 0xb6, 0x80, 0x00, 0x03, 0x8e, 0x51,
-0x00, 0x03, 0x55, 0x1c, 0x00, 0x02, 0xf8, 0x01,
-0x00, 0x03, 0xb4, 0x84, 0x00, 0x02, 0xf8, 0x02,
-0x00, 0x03, 0x51, 0x07, 0x00, 0x03, 0x5d, 0x11,
-0x00, 0x01, 0xd2, 0x02, 0x00, 0x03, 0xa6, 0x90,
-0x00, 0x03, 0x43, 0x81, 0x00, 0x02, 0xe2, 0xff,
-0x00, 0x00, 0xc4, 0x88, 0x00, 0x00, 0x67, 0x65,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x00, 0xbc, 0x8d,
-0x00, 0x03, 0x5d, 0x11, 0x00, 0x01, 0xd2, 0x01,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x5d, 0x17,
-0x00, 0x01, 0xd2, 0x02, 0x00, 0x02, 0x50, 0x01,
-0x00, 0x03, 0x80, 0x90, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x03, 0x47, 0x17, 0x00, 0x02, 0x90, 0x01,
-0x00, 0x03, 0x88, 0x26, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x00, 0xdd, 0x08, 0x00, 0x02, 0xe0, 0xff,
-0x00, 0x00, 0x61, 0x65, 0x00, 0x00, 0xa9, 0x65,
-0x00, 0x03, 0x43, 0x80, 0x00, 0x03, 0x8e, 0x26,
-0x00, 0x03, 0x48, 0x81, 0x00, 0x03, 0x49, 0x81,
-0x00, 0x03, 0xa0, 0xa5, 0x00, 0x03, 0x40, 0x81,
-0x00, 0x03, 0x22, 0x16, 0x00, 0x03, 0x4d, 0x36,
-0x00, 0x03, 0x50, 0x02, 0x00, 0x03, 0x4c, 0x1f,
-0x00, 0x03, 0x8f, 0x83, 0x00, 0x03, 0x20, 0x14,
-0x00, 0x03, 0x22, 0x15, 0x00, 0x03, 0x50, 0x0e,
-0x00, 0x02, 0xf8, 0x00, 0x00, 0x03, 0x51, 0x07,
-0x00, 0x03, 0x5d, 0x11, 0x00, 0x03, 0x45, 0x80,
-0x00, 0x03, 0xa5, 0x1d, 0x00, 0x01, 0xd2, 0x02,
-0x00, 0x03, 0xa2, 0xbc, 0x00, 0x03, 0x41, 0x81,
-0x00, 0x02, 0xe2, 0xff, 0x00, 0x00, 0xc4, 0x88,
-0x00, 0x00, 0x67, 0x60, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x00, 0xbf, 0x8d, 0x00, 0x00, 0x12, 0x01,
-0x00, 0x03, 0x8e, 0xbd, 0x00, 0x03, 0x50, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0xa8, 0xc7,
-0x00, 0x02, 0x5d, 0xe0, 0x00, 0x03, 0x89, 0x98,
-0x00, 0x02, 0x5c, 0x00, 0x00, 0x03, 0x8a, 0xc7,
-0x00, 0x02, 0xec, 0x01, 0x00, 0x01, 0xbb, 0xef,
-0x00, 0x03, 0x8a, 0xcd, 0x00, 0x02, 0xde, 0x01,
-0x00, 0x03, 0x8e, 0xcf, 0x00, 0x02, 0xde, 0x04,
-0x00, 0x02, 0x5c, 0x01, 0x00, 0x03, 0x89, 0x1d,
-0x00, 0x01, 0x5f, 0x08, 0x00, 0x02, 0x58, 0x01,
-0x00, 0x03, 0x89, 0x70, 0x00, 0x03, 0xa8, 0xcf,
-0x00, 0x03, 0x5d, 0x17, 0x00, 0x01, 0xd2, 0x02,
-0x00, 0x02, 0x50, 0x01, 0x00, 0x03, 0x80, 0xbb,
-0x00, 0x03, 0x51, 0x17, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x03, 0x45, 0x81, 0x00, 0x03, 0x42, 0x80,
-0x00, 0x02, 0xce, 0x00, 0x00, 0x03, 0x4e, 0x17,
-0x00, 0x03, 0xa8, 0xda, 0x00, 0x03, 0x47, 0x17,
-0x00, 0x02, 0xd8, 0x26, 0x00, 0x02, 0x90, 0x01,
-0x00, 0x03, 0x88, 0xde, 0x00, 0x02, 0xd8, 0xf9,
-0x00, 0x03, 0x4f, 0x81, 0x00, 0x02, 0x5c, 0x01,
-0x00, 0x03, 0x88, 0xea, 0x00, 0x01, 0x5e, 0x88,
-0x00, 0x02, 0x54, 0x01, 0x00, 0x03, 0x88, 0xe5,
-0x00, 0x03, 0x5f, 0x0c, 0x00, 0x02, 0xda, 0xff,
-0x00, 0x00, 0x7f, 0x0d, 0x00, 0x02, 0x44, 0x00,
-0x00, 0x03, 0x89, 0x2d, 0x00, 0x03, 0x5f, 0x0c,
-0x00, 0x02, 0x84, 0xff, 0x00, 0x03, 0x8a, 0xf1,
-0x00, 0x02, 0x90, 0x01, 0x00, 0x03, 0x8a, 0xf4,
-0x00, 0x03, 0x42, 0x81, 0x00, 0x02, 0xce, 0x00,
-0x00, 0x02, 0xdc, 0x00, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x5f, 0x0c, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x02, 0xee, 0x00, 0x00, 0x00, 0xdd, 0x08,
-0x00, 0x03, 0x56, 0x17, 0x00, 0x02, 0xd8, 0xfb,
-0x00, 0x03, 0x8f, 0x2d, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x00, 0xdd, 0x08, 0x00, 0x02, 0xe0, 0xff,
-0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0xa8, 0x20,
-0x00, 0x03, 0x41, 0x80, 0x00, 0x03, 0x8e, 0x26,
-0x00, 0x03, 0xb9, 0x0a, 0x00, 0x03, 0x50, 0x1e,
-0x00, 0x02, 0x40, 0x00, 0x00, 0x03, 0x89, 0x06,
-0x00, 0x02, 0x40, 0x90, 0x00, 0x03, 0x8b, 0x08,
-0x00, 0x02, 0xe0, 0x10, 0x00, 0x03, 0x20, 0xc0,
-0x00, 0x02, 0xe0, 0x80, 0x00, 0x03, 0x20, 0xc0,
-0x00, 0x03, 0x50, 0x07, 0x00, 0x03, 0xa7, 0x0e,
-0x00, 0x03, 0x50, 0x05, 0x00, 0x03, 0x8f, 0x0f,
-0x00, 0x03, 0x50, 0x05, 0x00, 0x02, 0xf8, 0x00,
-0x00, 0x03, 0x5d, 0x10, 0x00, 0x03, 0x4c, 0x1f,
-0x00, 0x03, 0x8f, 0x7c, 0x00, 0x02, 0xe0, 0xf0,
-0x00, 0x03, 0x20, 0xc0, 0x00, 0x03, 0x8e, 0x00,
-0x00, 0x02, 0x50, 0x00, 0x00, 0x03, 0x88, 0x26,
-0x00, 0x01, 0xd2, 0x02, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x01, 0xd2, 0x02, 0x00, 0x03, 0x85, 0x19,
-0x00, 0x03, 0x8e, 0x26, 0x00, 0x03, 0x4f, 0x80,
-0x00, 0x03, 0x56, 0x10, 0x00, 0x03, 0xbf, 0x21,
-0x00, 0x00, 0xdb, 0x08, 0x00, 0x02, 0x58, 0x00,
-0x00, 0x03, 0x8a, 0xcd, 0x00, 0x02, 0xd8, 0xcd,
-0x00, 0x03, 0xbf, 0x2b, 0x00, 0x01, 0xd2, 0x02,
-0x00, 0x02, 0x50, 0x01, 0x00, 0x03, 0x87, 0x72,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x01, 0x5f, 0x08,
-0x00, 0x03, 0x8f, 0x2d, 0x00, 0x00, 0xdf, 0x08,
-0x00, 0x01, 0x5b, 0x08, 0x00, 0x02, 0x58, 0xb7,
-0x00, 0x03, 0x89, 0x6b, 0x00, 0x02, 0x58, 0xb8,
-0x00, 0x03, 0x89, 0x5e, 0x00, 0x02, 0xea, 0x00,
-0x00, 0x02, 0x74, 0x0a, 0x00, 0x03, 0x89, 0x63,
-0x00, 0x02, 0x58, 0xb3, 0x00, 0x03, 0x89, 0x5f,
-0x00, 0x02, 0x58, 0xb8, 0x00, 0x03, 0x89, 0x5f,
-0x00, 0x02, 0x58, 0x00, 0x00, 0x03, 0x8b, 0x63,
-0x00, 0x02, 0xec, 0x01, 0x00, 0x00, 0x3a, 0x69,
-0x00, 0x03, 0xa9, 0x5f, 0x00, 0x02, 0x50, 0x01,
-0x00, 0x03, 0x87, 0x63, 0x00, 0x03, 0x56, 0x0a,
-0x00, 0x02, 0x78, 0x09, 0x00, 0x03, 0x83, 0x63,
-0x00, 0x03, 0xbf, 0x49, 0x00, 0x00, 0xdf, 0x88,
-0x00, 0x03, 0x4d, 0x17, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x00, 0xbf, 0x8d, 0x00, 0x01, 0xd2, 0x01,
-0x00, 0x03, 0x8f, 0x4b, 0x00, 0x02, 0xef, 0x00,
-0x00, 0x01, 0xd2, 0x02, 0x00, 0x00, 0x5f, 0x38,
-0x00, 0x02, 0x58, 0x18, 0x00, 0x03, 0x8b, 0x59,
-0x00, 0x03, 0x44, 0x81, 0x00, 0x03, 0x56, 0x0a,
-0x00, 0x01, 0xba, 0x69, 0x00, 0x00, 0x38, 0x61,
-0x00, 0x03, 0x56, 0x01, 0x00, 0x01, 0xbb, 0x0b,
-0x00, 0x02, 0x78, 0x0a, 0x00, 0x03, 0x81, 0x58,
-0x00, 0x02, 0xc2, 0x00, 0x00, 0x01, 0xba, 0x69,
-0x00, 0x03, 0x8f, 0x68, 0x00, 0x02, 0xec, 0x00,
-0x00, 0x03, 0x5d, 0x16, 0x00, 0x02, 0xed, 0x00,
-0x00, 0x03, 0x5d, 0x16, 0x00, 0x03, 0x8f, 0x68,
-0x00, 0x03, 0xaf, 0x75, 0x00, 0x03, 0x44, 0x80,
-0x00, 0x02, 0xec, 0x00, 0x00, 0x03, 0x5d, 0x16,
-0x00, 0x03, 0x47, 0x0e, 0x00, 0x03, 0xbf, 0x68,
-0x00, 0x03, 0xa9, 0x68, 0x00, 0x03, 0xab, 0x68,
-0x00, 0x02, 0xec, 0x01, 0x00, 0x03, 0x5d, 0x16,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x5f, 0x0c,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x02, 0xec, 0xcd,
-0x00, 0x02, 0x78, 0x0c, 0x00, 0x03, 0x8b, 0x76,
-0x00, 0x02, 0xd8, 0xcf, 0x00, 0x03, 0x8f, 0x76,
-0x00, 0x03, 0x4f, 0x81, 0x00, 0x03, 0x8f, 0x1e,
-0x00, 0x02, 0xe2, 0x01, 0x00, 0x02, 0xd8, 0xd4,
-0x00, 0x03, 0x8f, 0x28, 0x00, 0x02, 0xd9, 0x00,
-0x00, 0x03, 0x4c, 0x81, 0x00, 0x02, 0xce, 0x00,
-0x00, 0x02, 0xe6, 0x00, 0x00, 0x03, 0x5d, 0x13,
-0x00, 0x02, 0xe7, 0xb7, 0x00, 0x03, 0x5d, 0x13,
-0x00, 0x02, 0xec, 0x0a, 0x00, 0x02, 0xe6, 0x00,
-0x00, 0x03, 0x5d, 0x13, 0x00, 0x01, 0xdb, 0x01,
-0x00, 0x03, 0x8b, 0x7e, 0x00, 0x03, 0x5f, 0x0c,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x01, 0xe0, 0x06,
-0x00, 0x01, 0x40, 0x01, 0x00, 0x03, 0x58, 0x10,
-0x00, 0x03, 0x59, 0x33, 0x00, 0x03, 0x5b, 0x1f,
-0x00, 0x03, 0x8f, 0xda, 0x00, 0x00, 0x24, 0x0d,
-0x00, 0x03, 0x5f, 0x0c, 0x00, 0x01, 0x40, 0x88,
-0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x02, 0x5c, 0x01, 0x00, 0x03, 0x89, 0x93,
-0x00, 0x03, 0x81, 0x8c, 0x00, 0x00, 0x00, 0x01,
-0x00, 0x03, 0x8f, 0x8d, 0x00, 0x02, 0x40, 0x02,
-0x00, 0x03, 0x85, 0x8c, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x03, 0x5f, 0x1b, 0x00, 0x02, 0x5c, 0xba,
-0x00, 0x02, 0x50, 0x0d, 0x00, 0x03, 0x84, 0xc0,
-0x00, 0x02, 0xea, 0x02, 0x00, 0x02, 0xe2, 0x3c,
-0x00, 0x02, 0x50, 0x0d, 0x00, 0x03, 0x83, 0xa0,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x03, 0x8e, 0xc0,
-0x00, 0x00, 0x16, 0x81, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x02, 0xc4, 0xff, 0x00, 0x00, 0x64, 0xa2,
-0x00, 0x02, 0x7c, 0x02, 0x00, 0x03, 0x8b, 0xb0,
-0x00, 0x00, 0x45, 0x07, 0x00, 0x01, 0x44, 0x83,
-0x00, 0x00, 0xc9, 0x08, 0x00, 0x03, 0x42, 0x12,
-0x00, 0x00, 0xa4, 0x82, 0x00, 0x02, 0x54, 0x0b,
-0x00, 0x03, 0x85, 0xa0, 0x00, 0x02, 0xea, 0x00,
-0x00, 0x01, 0xd2, 0x0b, 0x00, 0x03, 0x8f, 0x9c,
-0x00, 0x03, 0x43, 0x15, 0x00, 0x01, 0xf2, 0x03,
-0x00, 0x02, 0xe2, 0x07, 0x00, 0x00, 0xc4, 0x88,
-0x00, 0x00, 0x04, 0x81, 0x00, 0x00, 0xc5, 0x08,
-0x00, 0x02, 0x54, 0x02, 0x00, 0x03, 0x81, 0xc3,
-0x00, 0x03, 0x85, 0xbd, 0x00, 0x03, 0x42, 0x12,
-0x00, 0x00, 0xbf, 0x82, 0x00, 0x00, 0x12, 0x02,
-0x00, 0x03, 0x8e, 0xc0, 0x00, 0x00, 0xdd, 0x08,
-0x00, 0x03, 0x43, 0x12, 0x00, 0x02, 0xee, 0x00,
-0x00, 0x00, 0xbf, 0x83, 0x00, 0x00, 0x12, 0x01,
-0x00, 0x03, 0x8e, 0xc0, 0x00, 0x03, 0x43, 0x12,
-0x00, 0x03, 0x4f, 0x80, 0x00, 0x00, 0x45, 0x07,
-0x00, 0x01, 0x44, 0x83, 0x00, 0x00, 0xc9, 0x08,
-0x00, 0x03, 0x42, 0x12, 0x00, 0x00, 0xa4, 0x82,
-0x00, 0x03, 0xbf, 0xb5, 0x00, 0x00, 0xc5, 0x08,
-0x00, 0x01, 0x49, 0x08, 0x00, 0x00, 0xa9, 0x03,
-0x00, 0x03, 0x5d, 0x12, 0x00, 0x01, 0xd6, 0x82,
-0x00, 0x03, 0x4f, 0x81, 0x00, 0x03, 0x8f, 0xc5,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x00, 0x5f, 0x82,
-0x00, 0x00, 0xdf, 0x8e, 0x00, 0x03, 0x5a, 0x17,
-0x00, 0x02, 0xef, 0x00, 0x00, 0x01, 0x5f, 0x81,
-0x00, 0x03, 0x5f, 0x1b, 0x00, 0x00, 0xbf, 0x9a,
-0x00, 0x02, 0xe4, 0x01, 0x00, 0x02, 0xe0, 0x01,
-0x00, 0x00, 0xc0, 0x0f, 0x00, 0x03, 0x5a, 0x10,
-0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0xe2, 0x00,
-0x00, 0x02, 0xa8, 0x19, 0x00, 0x03, 0x89, 0xe3,
-0x00, 0x00, 0x24, 0x98, 0x00, 0x01, 0x40, 0x01,
-0x00, 0x02, 0x84, 0x01, 0x00, 0x03, 0x89, 0xe7,
-0x00, 0x00, 0xa0, 0x1a, 0x00, 0x01, 0x44, 0x81,
-0x00, 0x00, 0xc9, 0x01, 0x00, 0x03, 0x8b, 0xe0,
-0x00, 0x03, 0x5f, 0x1b, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x50, 0x10, 0x00, 0x03, 0x50, 0x10,
-0x00, 0x03, 0x3c, 0xc0, 0x00, 0x03, 0x70, 0x10,
-0x00, 0x03, 0x50, 0x1e, 0x00, 0x02, 0x40, 0xe0,
-0x00, 0x03, 0x8b, 0xf6, 0x00, 0x03, 0x47, 0x81,
-0x00, 0x01, 0x40, 0x04, 0x00, 0x03, 0x88, 0x01,
-0x00, 0x03, 0x60, 0x80, 0x00, 0x03, 0x50, 0x30,
-0x00, 0x02, 0xea, 0xff, 0x00, 0x00, 0x77, 0x65,
-0x00, 0x03, 0x88, 0x51, 0x00, 0x02, 0x60, 0x0d,
-0x00, 0x03, 0x88, 0x7d, 0x00, 0x03, 0x8f, 0x16,
-0x0a, 0x0d,
-};