~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/core/pcmcia.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if 0
 
2
 
 
3
/*
 
4
 *      pcmcia.c
 
5
 *
 
6
 *      PCMCIA support routines for etherboot - generic stuff
 
7
 *
 
8
 *      This code has partly be taken from the linux kernel sources, .../drivers/pcmcia/
 
9
 *      Started & put together by
 
10
 *              Anselm Martin Hoffmeister
 
11
 *              Stockholm Projekt Computer-Service
 
12
 *              Sankt Augustin / Bonn, Germany
 
13
 *
 
14
 *      Distributed under GPL2
 
15
 */
 
16
 
 
17
/*
 
18
 *
 
19
 *
 
20
 *                      ******************************
 
21
 *                      PLEASE DO NOT YET WORK ON THIS
 
22
 *                      ******************************
 
23
 *
 
24
 *      I'm still fixing it up on every end, so we most probably would interfere
 
25
 *      at some point. If there's anything obvious or better, not-so-obvious,
 
26
 *      please contact me by e-mail: anselm (AT) hoffmeister (DOT) be   *THANKS*
 
27
 */
 
28
 
 
29
FILE_LICENCE ( GPL2_ONLY );
 
30
 
 
31
#include <stdio.h>
 
32
#include <pcmcia.h>
 
33
#include <i82365.h>
 
34
#define CODE_STATUS "alpha"
 
35
#define CODE_VERSION "0.1.3"
 
36
#include <pcmcia-opts.h>
 
37
#include <ipxe/init.h>
 
38
 
 
39
int     sockets; /* AHTODO: Phase this out! */
 
40
u_int   pccsocks;
 
41
struct  pccsock_t pccsock[MAXPCCSOCKS];
 
42
int     inited = -1;
 
43
struct  pcc_config_t pccconfig[MAXPCCCONFIGS];
 
44
 
 
45
struct  driver_interact_t driver[] = {
 
46
#ifdef  SUPPORT_I82365
 
47
        { I82365, i82365_interfacer, "Intel_82365" },
 
48
#endif
 
49
};
 
50
 
 
51
#define NUM_DRIVERS (sizeof(driver)/(sizeof(struct driver_interact_t)))
 
52
 
 
53
void    sleepticks(int numticks ) {
 
54
        u_int   tmo;
 
55
        for (tmo = currticks()+numticks; currticks() < tmo; ) {
 
56
        }
 
57
        return;
 
58
}
 
59
 
 
60
static void pcmcia_init_all(void) {
 
61
        u_int i, j, k, l, m, n, ui, configs = 0;
 
62
        u_int multicard[8];
 
63
        u_char  *uc, upc;
 
64
        if ( PDEBUG > 0 ) printf("Initializing PCMCIA subsystem (code-status: " CODE_STATUS ", Version " CODE_VERSION ")\n");
 
65
        if ( PDEBUG > 2 ) {
 
66
                printf ( "Supporting %d driver(s): ", NUM_DRIVERS );
 
67
                for ( i = 0; i < NUM_DRIVERS; ++i ) {
 
68
                        printf ( "[%s] ", driver[i].name );
 
69
                }
 
70
                printf ( "\n" );
 
71
        }
 
72
        pccsocks = 0;
 
73
        sockets = 0;
 
74
        // Init all drivers in the driver[] array:
 
75
        for ( i = 0; i < NUM_DRIVERS; ++i ) {
 
76
                driver[i].f(INIT,0,i,0,0);      // init needs no params. It uses pccsocks and pccsock[].
 
77
                                                // Only i tells it which driver_id itself is.
 
78
        }
 
79
        for ( i = 0; i < pccsocks; ++i ) {
 
80
                printf ( "Socket %d: ", i );
 
81
                if ( pccsock[i].status != HASCARD ) {
 
82
                        printf ( "is %s: skipping\n", pccsock[i].status == EMPTY? "empty":"[status unknown]" );
 
83
                        continue;
 
84
                }
 
85
                if ( 0 != driver[pccsock[i].drivernum].f(MAPATTRMEM,pccsock[i].internalid,MAP_ATTRMEM_TO, MAP_ATTRMEM_LEN,0 ) ) {
 
86
                        printf ("PCMCIA controller failed to map attribute memory.\n**** SEVERE ERROR CONDITION. Skipping controller.\n" );
 
87
                        if ( PDEBUG > 2 ) {
 
88
                                printf ( "<press key. THIS CONDITION SHOULD BE REPORTED!>\n" ); getchar();
 
89
                        }
 
90
                        continue;
 
91
                }
 
92
                // parse configuration information
 
93
                uc = ioremap ( MAP_ATTRMEM_TO, MAP_ATTRMEM_LEN );
 
94
                pccsock[i].stringoffset = pccsock[i].configoffset = pccsock[i].stringlength = 0;
 
95
                pccsock[i].type = 0xff;
 
96
                for ( l = 0; l < 8; ++l ) multicard[l] = 0;
 
97
                sleepticks(2);
 
98
                for ( l = ui = 0; ui < 0x800; ui += uc[(2*ui)+2] + 2 ) {
 
99
                        if ( uc[(2*ui)] == 0xff ) {
 
100
                                break;
 
101
                        }
 
102
                        // This loop is complete rubbish AFAICS.
 
103
                        // But without it, my test system won't come up.
 
104
                        // It's too bad to develop on broken hardware
 
105
                        //                              - Anselm
 
106
                }
 
107
                sleepticks(2);
 
108
                configs = 0;
 
109
                inited = -1;
 
110
                for ( l = ui = 0; ui < 0x800; ui += uc[(2*ui)+2] + 2 ) {
 
111
                        if ( uc[(2*ui)] == 0xff ) break;
 
112
                        else if ( uc[2*ui] == 0x15 ) {
 
113
                                for ( k = 2 * ( ui + 2 ); ( uc[k] <= ' ' ) && ( k < ( 2 * ( uc[2*(ui+1)] + ui + 2 ) ) ) ; k += 2 ) { ; }
 
114
                                pccsock[i].stringoffset = k;
 
115
                                pccsock[i].stringlength = ( 2 * ( ui + 2 + uc[(2*ui)+2] ) - k ) / 2;
 
116
                        } else if ( uc[2*ui] == 0x21 ) {
 
117
                                pccsock[i].type = uc[(2*ui)+4];
 
118
                        } else if ( uc[2*ui] == 0x1a ) { // Configuration map
 
119
                                printf ( "\nConfig map 0x1a found [" );
 
120
                                for ( k = 0; k < uc[2*(ui+1)]; ++k ) {
 
121
                                        printf ( "%02x ", uc[2*(ui+k+2)] );
 
122
                                }
 
123
                                printf ( "]\nHighest config available is %d\n", uc[2*(ui+3)] );
 
124
                                m = uc[2*(ui+2)];
 
125
                                pccsock[i].configoffset = 0;
 
126
                                for ( j = 0; j <= (m & 3); ++j ) {
 
127
                                        pccsock[i].configoffset += uc[2*(ui+4+j)] << (8*j);
 
128
                                }
 
129
                                pccsock[i].rmask0 = 0;
 
130
                                for ( j = 0; j <= ( ( ( m & 0x3c ) >> 2 ) & 3 ); ++j ) {
 
131
                                        pccsock[i].rmask0 += uc[2*(ui+5+(m&3)+j)] << (8*j);
 
132
                                }
 
133
                                j = pccsock[i].rmask0;
 
134
                                printf ( "Config offset is %x, card has regs: < %s%s%s%s%s>\n", pccsock[i].configoffset,
 
135
                                        j & 1 ? "COR ":"", j & 2 ? "CCSR ":"", j & 4 ? "PRR ":"", j & 8 ? "SCR ":"", j & 16? "ESR ":"" );
 
136
                                printf ( "COR + CCSR contents (si/du) %x %x/%x %x\n", uc[pccsock[i].configoffset+0],
 
137
                                        uc[pccsock[i].configoffset+2],uc[pccsock[i].configoffset*2],uc[(pccsock[i].configoffset*2)+2] );
 
138
                                printf ( "          " );
 
139
                        } else if ( uc[2*ui] == 0x1b ) { // Configuration data entry
 
140
                                //printf ( "Config data 0x1b found [\n" );getchar();
 
141
                                for ( k = 0; k < uc[2*(ui+1)]; ++k ) {
 
142
                                //      printf ( "%02x ", uc[2*(ui+k+2)] );
 
143
                                }
 
144
                                // Parse this tuple into pccconfig[configs]
 
145
                                // printf ( "]\n" );
 
146
                                if ( configs == MAXPCCCONFIGS ) continue;
 
147
                                k = 2*ui+4;
 
148
                                pccconfig[configs].index = uc[k] & 0x3f;
 
149
                                if ( uc[k] & 0x80 ) {
 
150
                                //      printf ( "Special config, unsupp. for now\n" );
 
151
                                        continue;
 
152
                                }
 
153
                                k+=2;
 
154
                                // printf ( "Features: %2x\n", uc[k] );
 
155
                                if ( uc[k] & 0x7 ) {
 
156
                                        // printf ( "Cannot work with Vcc/Timing configs right now\n" );
 
157
                                        continue;
 
158
                                }
 
159
                                pccconfig[configs].iowin = pccconfig[configs].iolen = 0;
 
160
                                if ( 0 != ( uc[k] & 0x8 ) ) {
 
161
                                        k+=2;
 
162
                                        // printf ( "Reading IO config: " );
 
163
                                        if ( 0 == ( uc[k] & 0x80 ) ) {
 
164
                                        //      printf ( "Cannot work with auto/io config\n" );
 
165
                                                continue;
 
166
                                        }
 
167
                                        k+=2;
 
168
                                        if ( 0 != ( uc[k] & 0x0f ) ) {
 
169
                                        //      printf ( "Don't support more than 1 iowin right now\n" );
 
170
                                                continue;
 
171
                                        }
 
172
                                        j = (uc[k] & 0x30) >> 4;
 
173
                                        m = (uc[k] & 0xc0) >> 6;
 
174
                                        if ( 3 == j ) ++j;
 
175
                                        if ( 3 == m ) ++m;
 
176
                                        k += 2;
 
177
                                        pccconfig[configs].iowin = 0;
 
178
                                        pccconfig[configs].iolen = 1;
 
179
                                        for ( n = 0; n < j; ++n, k+=2 ) {
 
180
                                                pccconfig[configs].iowin += uc[k] << (n*8);
 
181
                                        }
 
182
                                        for ( n = 0; n < m; ++n, k+=2 ) {
 
183
                                                pccconfig[configs].iolen += uc[k] << (n*8);
 
184
                                        }
 
185
                                        // printf ( "io %x len %d (%d)\n", pccconfig[configs].iowin, pccconfig[configs].iolen,configs );
 
186
                                }
 
187
                                for ( j = 0; j < (uc[k] & 3); ++j ) {
 
188
                                //      pccconfig[configs].iowin += (uc[k+(2*j)+2]) << (8*j);
 
189
                                }
 
190
                                ++configs;
 
191
                        }
 
192
                }
 
193
                if ( pccsock[i].stringoffset > 0 ) {    // If no identifier, it's not a valid CIS (as of documentation...)
 
194
                        printf ( "[" );
 
195
                        for ( k = 0; ( k <  pccsock[i].stringlength ) && ( k < 64 ); ++k ) {
 
196
                                j = uc[pccsock[i].stringoffset + 2 * k];
 
197
                                printf ( "%c", (j>=' '? j:' ' ) );
 
198
                        }
 
199
                        printf ("]\n          is type %d (", pccsock[i].type );
 
200
                        switch ( pccsock[i].type ) {
 
201
                          case  0x00:
 
202
                                printf ( "MULTI" ); break;
 
203
                          case  0x01:
 
204
                                printf ( "Memory" ); break;
 
205
                          case  0x02:
 
206
                                printf ( "Serial" ); break;
 
207
                          case  0x03:
 
208
                                printf ( "Parallel" ); break;
 
209
                          case  0x04:
 
210
                                printf ( "Fixed" ); break;
 
211
                          case  0x05:
 
212
                                printf ( "Video" ); break;
 
213
                          case  0x06:
 
214
                                printf ( "Network" ); break;
 
215
                          case  0x07:
 
216
                                printf ( "AIMS" ); break;
 
217
                          case  0x08:
 
218
                                printf ( "SCSI" ); break;
 
219
                          case  0x106: // Special / homebrew to say "Multi/network"
 
220
                                printf ( "MULTI, with Network" ); break; // AHTODO find a card for this
 
221
                          default:
 
222
                                printf ( "UNSUPPORTED/UNKNOWN" );
 
223
                        }
 
224
                        printf ( ") with %d possible configuration(s)\n", configs );
 
225
                        // Now set dependency: If it's Network or multi->network, accept
 
226
                        if ( (inited <= 0 ) && (6 == (0xff & pccsock[i].type) ) && (0 < configs ) ) {
 
227
                                printf ( "activating this device with ioport %x-%x (config #%d)\n", 
 
228
                                pccconfig[0].iowin, pccconfig[0].iowin+pccconfig[0].iolen-1, pccconfig[0].index );
 
229
                                inited = i;
 
230
                                // And unmap attrmem ourselves!
 
231
                                printf ( "Activating config..." );
 
232
                                if ( m=driver[pccsock[i].drivernum].f(SELECTCONFIG,pccsock[i].internalid,pccconfig[0].index,0,&pccconfig[0]) ) {
 
233
                                        printf ("Failure(%d)!",m); inited = -1;
 
234
                                        driver[pccsock[i].drivernum].f(UNMAPATTRMEM,pccsock[i].internalid,0,0,0);
 
235
                                }
 
236
                                printf ( "done!\n" );
 
237
                                continue;
 
238
                        }
 
239
                } else {
 
240
                        printf ( "unsupported - no identifier string found in CIS\n" );
 
241
                }
 
242
                // unmap the PCMCIA device
 
243
                if ( i != inited ) {
 
244
                    if ( 0 != driver[pccsock[i].drivernum].f(UNMAPATTRMEM,pccsock[i].internalid,0,0,0) ) {
 
245
                        printf ("PCMCIA controller failed to unmap attribute memory.\n**** SEVERE ERROR CONDITION ****\n" );
 
246
                        if ( PDEBUG > 2 ) {
 
247
                                printf ( "<press key. THIS CONDITION SHOULD BE REPORTED!>\n" ); getchar();
 
248
                        }
 
249
                        continue;
 
250
                    }
 
251
                }
 
252
        }
 
253
        if ( PDEBUG > 2 ) {
 
254
                printf ( "<press key to exit the pcmcia_init_all routine>\n" );
 
255
                getchar();
 
256
        }
 
257
 
 
258
}
 
259
 
 
260
static void     pcmcia_shutdown_all(void) {
 
261
        int i;
 
262
        //if ( PDEBUG > 2 ) {printf("<press key to continue>\n" ); getchar(); }
 
263
        for ( i = 0; i < pccsocks; ++i ) {
 
264
                driver[pccsock[i].drivernum].f(SHUTDOWN,pccsock[i].internalid,0,0,0);
 
265
        }
 
266
        printf("Shutdown of PCMCIA subsystem completed");
 
267
}
 
268
 
 
269
#endif