1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_FHC_H
#define _SYS_FHC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types32.h>
#include <sys/dditypes.h>
/* useful debugging stuff */
#define FHC_ATTACH_DEBUG 0x1
#define FHC_INTERRUPT_DEBUG 0x2
#define FHC_REGISTERS_DEBUG 0x4
#define FHC_CTLOPS_DEBUG 0x8
#define FHC_BOARDS 0
#define FHC_CLOCKS 1
/*
* OBP supplies us with 6 register sets for the FHC. The code for the fhc
* driver relies on these register sets being presented by the PROM in the
* order specified below. If this changes, the following comments must be
* revised and the code in fhc_init() must be changed to reflect these
* revisions.
*
* They are:
* 0 FHC internal registers
* 1 IGR Interrupt Group Number
* 2 FanFail IMR, ISMR
* 3 System IMR, ISMR
* 4 UART IMR, ISMR
* 5 TOD IMR, ISMR
*/
/*
* The offsets are defined as offsets from the base of the OBP register
* set which the register belongs to.
*/
/* Register set 0 */
#define FHC_OFF_ID 0x0 /* FHC ID register */
#define FHC_OFF_RCTRL 0x10 /* FHC Reset Control and Status */
#define FHC_OFF_CTRL 0x20 /* FHC Control and Status */
#define FHC_OFF_BSR 0x30 /* FHC Board Status Register */
#define FHC_OFF_JTAG_CTRL 0xF0 /* JTAG Control Register */
#define FHC_OFF_JTAG_CMD 0x100 /* JTAG Comamnd Register */
/* Register sets 2-5, the ISMR offset is the same */
#define FHC_OFF_ISMR 0x10 /* FHC Interrupt State Machine */
/* Bit field defines for FHC Control and Status Register */
#define FHC_CENTERDIS 0x00100000
/* NOTE: this bit is only used by firmware and must always be cleared by OS */
#define FHC_CSR_SYNC 0x00010000
#define FHC_MOD_OFF 0x00008000
#define FHC_ACDC_OFF 0x00004000
#define FHC_FHC_OFF 0x00002000
#define FHC_EPDA_OFF 0x00001000
#define FHC_EPDB_OFF 0x00000800
#define FHC_PS_OFF 0x00000400
#define FHC_NOT_BRD_PRES 0x00000200
#define FHC_LED_LEFT 0x00000040
#define FHC_LED_MID 0x00000020
#define FHC_LED_RIGHT 0x00000010
/* Bit field defines for FHC Reset Control and Status Register */
#define FHC_POR 0x80000000
#define FHC_SOFT_POR 0x40000000
#define FHC_SOFT_XIR 0x20000000
/* Bit field defines for the JTAG control register. */
#define JTAG_MASTER_EN 0x80000000
#define JTAG_MASTER_NPRES 0x40000000
/* Macros for decoding UPA speed pins from the Board Status Register */
#define CPU_0_PINS(bsr) (((bsr) >> 10) & 0x7)
#define CPU_1_PINS(bsr) (((bsr) >> 7) & 0x7)
#define CID_REV_MASK 0x0fffffff
#define ULTRAI_COMPID 0x0002502f
#define ULTRAII_COMPID 0x0003602f
/* Macro for extracting the "plus" bit from the Board Status Register */
#define ISPLUSBRD(bsr) (((bsr) & 1) == 0)
/* Macros for physical access */
#define FHC_OFFSET 0xf8000000ull
#define FHC_REGOFF 0x800000ull
#define FHC_OFF_IGN 0x2000ull
#define FHC_OFF_SIM 0x6000ull
#define FHC_OFF_SSM 0x6010ull
#define FHC_OFF_UIM 0x8000ull
#define FHC_OFF_USM 0x8010ull
#define FHC_CTRL(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \
FHC_REGOFF + FHC_OFF_CTRL)
#define FHC_JTAG_CTRL(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \
FHC_REGOFF + FHC_OFF_JTAG_CTRL)
#define FHC_IGN(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \
FHC_REGOFF + FHC_OFF_IGN)
#define FHC_SIM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \
FHC_REGOFF + FHC_OFF_SIM)
#define FHC_SSM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \
FHC_REGOFF + FHC_OFF_SSM)
#define FHC_UIM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \
FHC_REGOFF + FHC_OFF_UIM)
#define FHC_USM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \
FHC_REGOFF + FHC_OFF_USM)
/*
* the foolowing defines are used for trans phy-addr to board number
*/
#define BOARD_PHYADDR_SHIFT 24
#define CLOCKBOARD_PHYADDR_BITS 0x1fff8
#define IO_BOARD_NUMBER_SHIFT 10
#define IO_BOARD_NUMBER_MASK 0xf
/*
* The following defines are used by the fhc driver to determine the
* difference between IO and CPU type boards. This will be replaced
* later by JTAG scan to determine board type.
*/
/* XXX */
#define FHC_UPADATA64A 0x40000
#define FHC_UPADATA64B 0x20000
/* XXX */
/* Bit field defines for Board Status Register */
#define FHC_DIAG_MODE 0x40
/* Bit field defines for the FHC Board Status Register when on a disk board */
#define FHC_FANFAIL 0x00000040
#define FHC_SCSI_VDD_OK 0x00000001
/* Size of temperature recording array */
#define MAX_TEMP_HISTORY 16
/* Maximum number of boards in system */
#define MAX_BOARDS 16
/* Maximum number of Board Power Supplies. */
#define MAX_PS_COUNT 8
/* Use predefined strings to name the kstats from this driver. */
#define FHC_KSTAT_NAME "fhc"
#define CSR_KSTAT_NAMED "csr"
#define BSR_KSTAT_NAMED "bsr"
/*
* The following defines are for the AC chip, but are needed to be global,
* so have been put in the fhc header file.
*/
/*
* Most Sunfire ASICs have the chip rev encoded into bits 31-28 of the
* component ID register.
*/
#define CHIP_REV(c) ((c) >> 28)
#ifndef _ASM
/* Use predefined strings to name the kstats from this driver. */
/* Bit field defines for Interrupt Mapping registers */
#define IMR_VALID ((uint_t)1 << INR_EN_SHIFT) /* Mondo valid bit */
/* Bit defines for Interrupt State Machine Register */
#define INT_PENDING 3 /* state of the interrupt dispatch */
struct intr_regs {
volatile uint_t *mapping_reg;
volatile uint_t *clear_reg;
uint_t mapping_reg_cache; /* cache current value for CPR */
};
#define BD_IVINTR_SHFT 0x7
/*
* Convert the Board Number field in the FHC Board Status Register to
* a board number. The field in the register is bits 0,3-1 of the board
* number. Therefore a macro is necessary to extract the board number.
*/
#define FHC_BSR_TO_BD(bsr) ((((bsr) >> 16) & 0x1) | \
(((bsr) >> 12) & 0xE))
#define FHC_INO(ino) ((ino) & 0x7)
#define FHC_CPU2BOARD(cpuid) ((cpuid) >> 1)
#define FHC_CPU_IS_A(cpuid) (!((cpuid) & 1))
#define FHC_CPU_IS_B(cpuid) ((cpuid) & 1)
#define FHC_BOARD2CPU_A(board) ((board) << 1)
#define FHC_BOARD2CPU_B(board) (((board) << 1) + 1)
#define FHC_PS2BOARD(ps) ((((ps) & 0x6) << 1) | ((ps) & 0x1))
#define FHC_BOARD2PS(board) ((((board) & 0xc) >> 1) | ((board) & 0x1))
#define FHC_OTHER_CPU_ID(cpuid) ((cpuid) ^ 1)
/* this base address is assumed to never map to real memory */
#define FHC_BASE_NOMEM (1ull << 40)
#define FHC_MAX_ECACHE_SIZE (16 * 1024 * 1024)
#define FHC_BOARD_0 0x1c000000000ull
#define FHC_BOARD_SPAN 0x200000000ull
#define FHC_DTAG_OFFSET 0xfa000000ull
#define FHC_BOARD_BASE(cpuid) (FHC_BOARD_0 + (cpuid) * FHC_BOARD_SPAN)
#define FHC_DTAG_BASE(cpuid) (FHC_BOARD_BASE(cpuid) + FHC_DTAG_OFFSET)
#define FHC_DTAG_LOW 0x300000000ull
#define FHC_DTAG_HIGH 0x3ull
#define FHC_DTAG_SIZE (16 * 1024 * 1024)
#define FHC_DTAG_SKIP 64
/*
* Each Sunfire CPU Board has 32Kbytes of SRAM on the FireHose Bus.
*
* The SRAM is allocated as follows:
*
* 0x1ff.f020.0000 - 0x1ff.f020.5fff scratch/stacks
* 0x1ff.f020.6000 - 0x1ff.f020.67ff reset info (2K bytes)
* 0x1ff.f020.6800 - 0x1ff.f020.6fff POST private (2K bytes)
* 0x1ff.f020.7000 - 0x1ff.f020.77ff OS private (2K bytes)
* 0x1ff.f020.7800 - 0x1ff.f020.7fff OBP private (2K bytes)
*/
#define FHC_LOCAL_SRAM_BASE 0x1fff0200000ull
#define FHC_GLOBAL_SRAM_BASE 0x1c0f8200000ull
#define FHC_CPU2GLOBAL_SRAM(mid) \
(FHC_GLOBAL_SRAM_BASE + (mid) * 0x200000000ull)
#define FHC_SRAM_OS_BASE 0x7000
#define FHC_LOCAL_OS_PAGEBASE ((FHC_LOCAL_SRAM_BASE + FHC_SRAM_OS_BASE) & \
MMU_PAGEMASK)
#define FHC_SRAM_OS_OFFSET ((FHC_LOCAL_SRAM_BASE + FHC_SRAM_OS_BASE) & \
MMU_PAGEOFFSET)
#define FHC_SHUTDOWN_WAIT_MSEC 1000
#define FHC_MAX_INO 4
#define FHC_SYS_INO 0x0
#define FHC_UART_INO 0x1
#define FHC_TOD_INO 0x2
#define FHC_FANFAIL_INO 0x3
/*
* Defines for the kstats created for passing temperature values and
* history out to user level programs. All temperatures passed out
* will be in degrees Centigrade, corrected for the board type the
* temperature was read from. Since each Board type has a different
* response curve for the A/D convertor, the temperatures are all
* calibrated inside the kernel.
*/
#define OVERTEMP_KSTAT_NAME "temperature"
/*
* This kstat is used for manually overriding temperatures.
*/
#define TEMP_OVERRIDE_KSTAT_NAME "temperature override"
/*
* Time averaging based method of recording temperature history.
* Higher level temperature arrays are composed of temperature averages
* of the array one level below. When the lower array completes a
* set of data, the data is averaged and placed into the higher
* level array. Then the lower level array is overwritten until
* it is once again complete, where the process repeats.
*
* This method gives a user a fine grained view of the last minute,
* and larger grained views of the temperature as one goes back in
* time.
*
* The time units for the longer samples are based on the value
* of the OVERTEMP_TIMEOUT_SEC and the number of elements in each
* of the arrays between level 1 and the higher level.
*/
#define OVERTEMP_TIMEOUT_SEC 2
/* definition of the clock board index */
#define CLOCK_BOARD_INDEX 16
#define L1_SZ 30 /* # of OVERTEMP_TIMEOUT_SEC samples */
#define L2_SZ 15 /* size of array for level 2 samples */
#define L3_SZ 12 /* size of array for level 3 samples */
#define L4_SZ 4 /* size of array for level 4 samples */
#define L5_SZ 2 /* size of array for level 5 samples */
/*
* Macros for determining when to do the temperature averaging of arrays.
*/
#define L2_INDEX(i) ((i) / L1_SZ)
#define L2_REM(i) ((i) % L1_SZ)
#define L3_INDEX(i) ((i) / (L1_SZ * L2_SZ))
#define L3_REM(i) ((i) % (L1_SZ * L2_SZ))
#define L4_INDEX(i) ((i) / (L1_SZ * L2_SZ * L3_SZ))
#define L4_REM(i) ((i) % (L1_SZ * L2_SZ * L3_SZ))
#define L5_INDEX(i) ((i) / (L1_SZ * L2_SZ * L3_SZ * L4_SZ))
#define L5_REM(i) ((i) % (L1_SZ * L2_SZ * L3_SZ * L4_SZ))
/*
* define for an illegal temperature. This temperature will never be seen
* in a real system, so it is used as an illegal value in the various
* functions processing the temperature data structure.
*/
#define NA_TEMP 0x7FFF
/*
* State variable for board temperature. Each board has its own
* temperature state. State transitions from OK -> bad direction
* happen instantaneously, but use a counter in the opposite
* direction, so that noise in the A/D counters does not cause
* a large number of messages to appear.
*/
enum temp_state { TEMP_OK = 0, /* normal board temperature */
TEMP_WARN = 1, /* start warning operator */
TEMP_DANGER = 2 }; /* get ready to shutdown */
/*
* Number of temperature poll counts to wait before printing that the
* system has cooled down.
*/
#define TEMP_STATE_TIMEOUT_SEC 20
#define TEMP_STATE_COUNT ((TEMP_STATE_TIMEOUT_SEC) / \
(OVERTEMP_TIMEOUT_SEC))
/*
* Number of poll counts that a system temperature must be at or above danger
* temperature before system is halted and powers down.
*/
#define SHUTDOWN_TIMEOUT_SEC 20
#define SHUTDOWN_COUNT ((SHUTDOWN_TIMEOUT_SEC) / \
(OVERTEMP_TIMEOUT_SEC))
/*
* State variable for temperature trend. Each state represents the
* current temperature trend for a given device.
*/
enum temp_trend { TREND_UNKNOWN = 0, /* Unknown temperature trend */
TREND_RAPID_FALL = 1, /* Rapidly falling temp. */
TREND_FALL = 2, /* Falling temperature */
TREND_STABLE = 3, /* Stable temperature */
TREND_RISE = 4, /* Rising temperature */
TREND_RAPID_RISE = 5, /* Rapidly rising temperature */
TREND_NOISY = 6 }; /* Unknown trend (noisy) */
/* Thresholds for temperature trend */
#define NOISE_THRESH 2
#define RAPID_RISE_THRESH 4
#define RAPID_FALL_THRESH 4
/*
* Main structure for passing the calibrated and time averaged temperature
* values to user processes. This structure is copied out via the kstat
* mechanism.
*/
#define TEMP_KSTAT_VERSION 3 /* version of temp_stats structure */
struct temp_stats {
uint_t index; /* index of current temperature */
short l1[L1_SZ]; /* OVERTEMP_TIMEOUT_SEC samples */
short l2[L2_SZ]; /* level 2 samples */
short l3[L3_SZ]; /* level 3 samples */
short l4[L4_SZ]; /* level 4 samples */
short l5[L5_SZ]; /* level 5 samples */
short max; /* maximum temperature recorded */
short min; /* minimum temperature recorded */
enum temp_state state; /* state of board temperature */
int temp_cnt; /* counter for state changes */
int shutdown_cnt; /* counter for overtemp shutdown */
int version; /* version of this structure */
enum temp_trend trend; /* temperature trend for board */
short override; /* override temperature for testing */
};
/* The variable fhc_cpu_warning_temp_threshold is initialized to this value. */
#define FHC_CPU_WARNING_TEMP_THRESHOLD 45
/*
* Fault list management.
*
* The following defines and enum definitions have been created to support
* the fault list (struct ft_list). These defines must match with the
* fault string table in fhc.c. If any faults are added, they must be
* added at the end of this list, and the table must be modified
* accordingly.
*/
enum ft_type {
FT_CORE_PS = 0, /* Core power supply */
FT_OVERTEMP, /* Temperature */
FT_AC_PWR, /* AC power Supply */
FT_PPS, /* Peripheral Power Supply */
FT_CLK_33, /* System 3.3 Volt Power */
FT_CLK_50, /* System 5.0 Volt Power */
FT_V5_P, /* Peripheral 5V Power */
FT_V12_P, /* Peripheral 12V Power */
FT_V5_AUX, /* Auxiliary 5V Power */
FT_V5_P_PCH, /* Peripheral 5V Precharge */
FT_V12_P_PCH, /* Peripheral 12V Precharge */
FT_V3_PCH, /* System 3V Precharge */
FT_V5_PCH, /* System 5V Precharge */
FT_PPS_FAN, /* Peripheral Power Supply Fan */
FT_RACK_EXH, /* Rack Exhaust Fan */
FT_DSK_FAN, /* 4 (or 5) Slot Disk Fan */
FT_AC_FAN, /* AC Box Fan */
FT_KEYSW_FAN, /* Key Switch Fan */
FT_INSUFFICIENT_POWER, /* System has insufficient power */
FT_PROM, /* fault inherited from PROM */
FT_HOT_PLUG, /* hot plug unavailable */
FT_TODFAULT /* tod error detection */
};
enum ft_class {
FT_BOARD,
FT_SYSTEM
};
/*
* This extern allows other drivers to use the ft_str_table if they
* have fhc specified as a depends_on driver.
*/
extern char *ft_str_table[];
/* Maximum length of string table entries */
#define MAX_FT_DESC 64
#define FT_LIST_KSTAT_NAME "fault_list"
/*
* The fault list structure is a structure for holding information on
* kernel detected faults. The fault list structures are linked into
* a list and the list is protected by the ftlist_mutex. There are
* also several routines for manipulating the fault list.
*/
struct ft_list {
int32_t unit; /* unit number of faulting device */
enum ft_type type; /* type of faulting device */
int32_t pad; /* padding to replace old next pointer */
enum ft_class fclass; /* System or board class fault */
time32_t create_time; /* Time stamp at fault detection */
char msg[MAX_FT_DESC]; /* fault string */
};
/*
* Allow binary compatibility between ILP32 and LP64 by
* eliminating the next pointer and making ft_list a fixed size.
* The structure name "ft_list" remains unchanged for
* source compatibility of kstat applications.
*/
struct ft_link_list {
struct ft_list f;
struct ft_link_list *next;
};
/*
* Board list management.
*
* Enumerated types for defining type of system and clock
* boards. It is used by both the kernel and user programs.
*/
enum board_type {
EMPTY_BOARD = -1,
UNINIT_BOARD = 0, /* Uninitialized board type */
UNKNOWN_BOARD, /* Unknown board type */
CPU_BOARD, /* System board CPU(s) */
MEM_BOARD, /* System board no CPUs */
IO_2SBUS_BOARD, /* 2 SBus & SOC IO Board */
IO_SBUS_FFB_BOARD, /* SBus & FFB SOC IO Board */
IO_PCI_BOARD, /* PCI IO Board */
DISK_BOARD, /* Disk Drive Board */
CLOCK_BOARD, /* System Clock board */
IO_2SBUS_SOCPLUS_BOARD, /* 2 SBus & SOC+ IO board */
IO_SBUS_FFB_SOCPLUS_BOARD /* SBus&FFB&SOC+ board */
};
/*
* Defined strings for comparing with OBP board-type property. If OBP ever
* changes the board-type properties, these string defines must be changed
* as well.
*/
#define CPU_BD_NAME "cpu"
#define MEM_BD_NAME "mem"
#define IO_2SBUS_BD_NAME "dual-sbus"
#define IO_SBUS_FFB_BD_NAME "upa-sbus"
#define IO_PCI_BD_NAME "dual-pci"
#define DISK_BD_NAME "disk"
#define IO_2SBUS_SOCPLUS_BD_NAME "dual-sbus-soc+"
#define IO_SBUS_FFB_SOCPLUS_BD_NAME "upa-sbus-soc+"
/*
* The following structures and union are needed because the bd_info
* structure describes all types of system boards.
* XXX - We cannot determine Spitfire rev from JTAG scan, so it is
* left blank for now. Future implementations might fill in this info.
*/
struct cpu_info {
int cpu_rev; /* CPU revision */
int cpu_speed; /* rated speed of CPU in MHz */
int cpu_compid; /* CPU component ID */
int sdb0_compid; /* SDB component ID */
int sdb1_compid; /* SDB component ID */
int ec_compid; /* Ecache RAM ID, needed for cache size */
int cache_size; /* Cache size in bytes */
int cpu_sram_mode; /* module's sram mode */
int cpu_detected; /* Something on the CPU JTAG ring. */
};
struct io1_info {
int sio0_compid; /* Sysio component ID */
int sio1_compid; /* Sysio component ID */
int hme_compid; /* several revs in existence */
int soc_compid; /* SOC */
};
struct io1plus_info {
int sio0_compid; /* Sysio component ID */
int sio1_compid; /* Sysio component ID */
int hme_compid; /* several revs in existence */
int socplus_compid; /* SOC+ */
};
/* Defines for the FFB size field */
#define FFB_FAILED -1
#define FFB_NOT_FOUND 0
#define FFB_SINGLE 1
#define FFB_DOUBLE 2
struct io2_info {
int fbc_compid; /* FBC component ID */
int ffb_size; /* not present, single or dbl buffered */
int sio1_compid; /* Sysio component ID */
int hme_compid; /* several revs in existence */
int soc_compid; /* SOC component ID */
};
struct io2plus_info {
int fbc_compid; /* FBC component ID */
int ffb_size; /* not present, single or dbl buffered */
int sio1_compid; /* Sysio component ID */
int hme_compid; /* several revs in existence */
int socplus_compid; /* or SOC+ component ID */
};
struct io3_info {
int psyo0_compid; /* Psycho+ component ID */
int psyo1_compid; /* Psycho+ component ID */
int cheo_compid; /* Cheerio component ID */
};
struct dsk_info {
int disk_pres[2];
int disk_id[2];
};
union bd_un {
struct cpu_info cpu[2];
struct io1_info io1;
struct io2_info io2;
struct io3_info io3;
struct dsk_info dsk;
struct io1plus_info io1plus;
struct io2plus_info io2plus;
};
/*
* board_state and bd_info are maintained for backward
* compatibility with prtdiag and others user programs that may rely
* on them.
*/
enum board_state {
UNKNOWN_STATE = 0, /* Unknown board */
ACTIVE_STATE, /* active and working */
HOTPLUG_STATE, /* Hot plugged board */
LOWPOWER_STATE, /* Powered down board */
DISABLED_STATE, /* Board disabled by PROM */
FAILED_STATE /* Board failed by POST */
};
struct bd_info {
enum board_type type; /* Type of board */
enum board_state state; /* current state of this board */
int board; /* board number */
int fhc_compid; /* fhc component id */
int ac_compid; /* ac component id */
char prom_rev[64]; /* best guess as to what is needed */
union bd_un bd;
};
/*
* Config admin interface.
*
* Receptacle states.
*/
typedef enum {
SYSC_CFGA_RSTATE_EMPTY = 0, /* Empty state */
SYSC_CFGA_RSTATE_DISCONNECTED, /* DISCONNECTED state */
SYSC_CFGA_RSTATE_CONNECTED /* CONNECTED state */
} sysc_cfga_rstate_t;
/*
* Occupant states.
*/
typedef enum {
SYSC_CFGA_OSTATE_UNCONFIGURED = 0, /* UNCONFIGURED state */
SYSC_CFGA_OSTATE_CONFIGURED /* CONFIGURED state */
} sysc_cfga_ostate_t;
/*
* Receptacle/Occupant condition.
*/
typedef enum {
SYSC_CFGA_COND_UNKNOWN = 0, /* Unknown condition */
SYSC_CFGA_COND_OK, /* Condition OK */
SYSC_CFGA_COND_FAILING, /* Failing */
SYSC_CFGA_COND_FAILED, /* Failed */
SYSC_CFGA_COND_UNUSABLE /* Unusable */
} sysc_cfga_cond_t;
/*
* Error definitions for CFGADM platform library
*/
typedef enum {
SYSC_ERR_DEFAULT = 0, /* generic errors */
SYSC_ERR_INTRANS, /* hardware in transition */
SYSC_ERR_UTHREAD, /* can't stop user thread */
SYSC_ERR_KTHREAD, /* can't stop kernel thread */
SYSC_ERR_SUSPEND, /* can't suspend a device */
SYSC_ERR_RESUME, /* can't resume a device */
SYSC_ERR_POWER, /* not enough power for slot */
SYSC_ERR_COOLING, /* not enough cooling for slot */
SYSC_ERR_PRECHARGE, /* not enough precharge for slot */
SYSC_ERR_HOTPLUG, /* Hot Plug Unavailable */
SYSC_ERR_HW_COMPAT, /* incompatible hardware found during dr */
SYSC_ERR_NON_DR_PROM, /* prom not support Dynamic Reconfiguration */
SYSC_ERR_CORE_RESOURCE, /* core resource cannot be removed */
SYSC_ERR_PROM, /* error encountered in OBP/POST */
SYSC_ERR_DR_INIT, /* error encountered in sysc_dr_init op */
SYSC_ERR_NDI_ATTACH, /* error encountered in NDI attach operations */
SYSC_ERR_NDI_DETACH, /* error encountered in NDI detach operations */
SYSC_ERR_RSTATE, /* wrong receptacle state */
SYSC_ERR_OSTATE, /* wrong occupant state */
SYSC_ERR_COND /* invalid condition */
} sysc_err_t;
/*
* Config admin structure.
*/
typedef struct sysc_cfga_stat {
/* generic representation of the attachment point below */
sysc_cfga_rstate_t rstate; /* current receptacle state */
sysc_cfga_ostate_t ostate; /* current occupant state */
sysc_cfga_cond_t condition; /* current board condition */
time32_t last_change; /* last state/condition change */
uint_t in_transition:1; /* board is in_transition */
/* platform specific below */
enum board_type type; /* Type of board */
int board; /* board number */
int fhc_compid; /* fhc component id */
int ac_compid; /* ac component id */
char prom_rev[64]; /* best guess as to what is needed */
union bd_un bd;
uint_t no_detach:1; /* board is non_detachable */
uint_t plus_board:1; /* board is 98 MHz capable */
} sysc_cfga_stat_t;
/*
* Config admin command structure for SYSC_CFGA ioctls.
*/
typedef struct sysc_cfga_cmd {
uint_t force:1; /* force this state transition */
uint_t test:1; /* Need to test hardware */
int arg; /* generic data for test */
sysc_err_t errtype; /* error code returned */
char *outputstr; /* output returned from ioctl */
} sysc_cfga_cmd_t;
typedef struct sysc_cfga_cmd32 {
uint_t force:1; /* force this state transition */
uint_t test:1; /* Need to test hardware */
int arg; /* generic data for test */
sysc_err_t errtype; /* error code returned */
caddr32_t outputstr; /* output returned from ioctl */
} sysc_cfga_cmd32_t;
typedef struct sysc_cfga_pkt {
sysc_cfga_cmd_t cmd_cfga;
char *errbuf; /* internal error buffer */
} sysc_cfga_pkt_t;
/*
* Sysctrl DR sequencer interface.
*/
typedef struct sysc_dr_handle {
dev_info_t **dip_list; /* list of top dips for board */
int dip_list_len; /* length devinfo list */
int flags; /* dr specific flags */
int error; /* dr operation error */
char *errstr; /* dr config/unfig error message */
} sysc_dr_handle_t;
#define SYSC_DR_MAX_NODE 32
#define SYSC_DR_FHC 0x1 /* connect phase init (fhc) */
#define SYSC_DR_DEVS 0x2 /* config phase init (devices) */
#define SYSC_DR_FORCE 0x4 /* force detach */
#define SYSC_DR_REMOVE 0x8 /* remove dev_info */
#define SYSC_DR_HANDLE_FHC 0x0
#define SYSC_DR_HANDLE_DEVS 0x1
/*
* Sysctrl event interface.
*/
typedef enum sysc_evt {
SYSC_EVT_BD_EMPTY = 0,
SYSC_EVT_BD_PRESENT,
SYSC_EVT_BD_DISABLED,
SYSC_EVT_BD_FAILED,
SYSC_EVT_BD_OVERTEMP,
SYSC_EVT_BD_TEMP_OK,
SYSC_EVT_BD_PS_CHANGE,
SYSC_EVT_BD_INS_FAILED,
SYSC_EVT_BD_INSERTED,
SYSC_EVT_BD_REMOVED,
SYSC_EVT_BD_HP_DISABLED,
SYSC_EVT_BD_CORE_RESOURCE_DISCONNECT
} sysc_evt_t;
/*
* sysctrl audit message events
*/
typedef enum sysc_audit_evt {
SYSC_AUDIT_RSTATE_EMPTY = 0,
SYSC_AUDIT_RSTATE_CONNECT,
SYSC_AUDIT_RSTATE_DISCONNECT,
SYSC_AUDIT_RSTATE_SUCCEEDED,
SYSC_AUDIT_RSTATE_EMPTY_FAILED,
SYSC_AUDIT_RSTATE_CONNECT_FAILED,
SYSC_AUDIT_RSTATE_DISCONNECT_FAILED,
SYSC_AUDIT_OSTATE_CONFIGURE,
SYSC_AUDIT_OSTATE_UNCONFIGURE,
SYSC_AUDIT_OSTATE_SUCCEEDED,
SYSC_AUDIT_OSTATE_CONFIGURE_FAILED,
SYSC_AUDIT_OSTATE_UNCONFIGURE_FAILED
} sysc_audit_evt_t;
typedef struct {
void (*update)(void *, sysc_cfga_stat_t *, sysc_evt_t);
void *soft;
} sysc_evt_handle_t;
void fhc_bd_sc_register(void f(void *, sysc_cfga_stat_t *, sysc_evt_t), void *);
/*
* The board list structure is the central storage for the kernel's
* knowledge of normally booted and hotplugged boards.
*/
typedef struct bd_list {
struct fhc_soft_state *softsp; /* handle for DDI soft state */
sysc_cfga_stat_t sc; /* board info */
sysc_dr_handle_t sh[2]; /* sysctrl dr interface */
void *dev_softsp; /* opaque pointer to device state */
void *ac_softsp; /* opaque pointer to our AC */
struct kstat *ksp; /* pointer used in kstat destroy */
int fault; /* failure on this board? */
int flags; /* board state flags */
} fhc_bd_t;
/*
* Fhc_bd.c holds 2 resizable arrays of boards. First for clock
* boards under central and second for normally booted and
* hotplugged boards.
*/
typedef struct resizable_bd_list {
fhc_bd_t **boards;
int size;
int last;
int sorted;
} fhc_bd_resizable_t;
#define BDF_VALID 0x1 /* board entry valid */
#define BDF_DETACH 0x2 /* board detachable */
#define BDF_DISABLED 0x4 /* board disabled */
#define SYSC_OUTPUT_LEN MAXPATHLEN /* output str len */
/*
* Board list management interface.
*/
int fhc_max_boards(void);
void fhc_bdlist_init(void);
void fhc_bdlist_fini(void);
void fhc_bdlist_prime(int, int, int);
fhc_bd_t *fhc_bdlist_lock(int);
void fhc_bdlist_unlock(void);
void fhc_bd_init(struct fhc_soft_state *, int, enum board_type);
fhc_bd_t *fhc_bd(int);
fhc_bd_t *fhc_bd_clock(void);
fhc_bd_t *fhc_bd_first(void);
fhc_bd_t *fhc_bd_next(fhc_bd_t *);
enum board_type fhc_bd_type(int);
char *fhc_bd_typestr(enum board_type);
int fhc_bd_valid(int);
int fhc_bd_detachable(int);
int fhc_bd_insert_scan(void);
int fhc_bd_remove_scan(void);
int fhc_bd_test(int, sysc_cfga_pkt_t *);
int fhc_bd_test_set_cond(int, sysc_cfga_pkt_t *);
void fhc_bd_update(int, sysc_evt_t);
void fhc_bd_env_set(int, void *);
int fhc_bdlist_locked(void);
int fhc_bd_busy(int);
int fhc_bd_is_jtag_master(int);
int fhc_bd_is_plus(int);
#if defined(_KERNEL)
/*
* In order to indicate that we are in an environmental chamber, or
* oven, the test people will set the 'mfg-mode' property in the
* options node to 'chamber'. Therefore we have the following define.
*/
#define CHAMBER_VALUE "chamber"
/*
* zs design for fhc has two zs' interrupting on same interrupt mondo
* This requires us to poll for zs and zs alone. The poll list has been
* defined as a fixed size for simplicity.
*/
#define MAX_ZS_CNT 2
/* FHC Interrupt routine wrapper structure */
struct fhc_wrapper_arg {
struct fhc_soft_state *softsp;
volatile uint_t *clear_reg;
volatile uint_t *mapping_reg;
dev_info_t *child;
uint32_t inum;
uint_t (*funcp)(caddr_t, caddr_t);
caddr_t arg1;
caddr_t arg2;
};
/*
* The JTAG master command structure. It contains the address of the
* the JTAG controller on this system board. The controller can only
* be used if this FHC holds the JTAG master signal. This is checked
* by reading the JTAG control register on this FHC.
*/
struct jt_mstr {
volatile uint_t *jtag_cmd;
int is_master;
kmutex_t lock;
};
/* Functions exported to manage the fault list */
void reg_fault(int, enum ft_type, enum ft_class);
void clear_fault(int, enum ft_type, enum ft_class);
int process_fault_list(void);
void create_ft_kstats(int);
/* memloc's are protected under the bdlist lock */
struct fhc_memloc {
struct fhc_memloc *next;
int board; /* reference our board element */
uint_t pa; /* base PA of this segment (in MB) */
uint_t size; /* size of this segment (in MB) */
};
/* Functions used to manage memory 'segments' */
#define FHC_MEMLOC_SHIFT 20
#define FHC_MEMLOC_MAX (0x10000000000ull >> FHC_MEMLOC_SHIFT)
void fhc_add_memloc(int board, uint64_t pa, uint_t size);
void fhc_del_memloc(int board);
uint64_t fhc_find_memloc_gap(uint_t size);
void fhc_program_memory(int board, uint64_t base);
/* Structures used in the driver to manage the hardware */
struct fhc_soft_state {
dev_info_t *dip; /* dev info of myself */
struct bd_list *list; /* pointer to board list entry */
int is_central; /* A central space instance of FHC */
volatile uint_t *id; /* FHC ID register */
volatile uint_t *rctrl; /* FHC Reset Control and Status */
volatile uint_t *bsr; /* FHC Board Status register */
volatile uint_t *jtag_ctrl; /* JTAG Control register */
volatile uint_t *igr; /* Interrupt Group Number */
struct intr_regs intr_regs[FHC_MAX_INO];
struct fhc_wrapper_arg poll_list[MAX_ZS_CNT];
struct fhc_wrapper_arg *intr_list[FHC_MAX_INO];
kmutex_t poll_list_lock;
uchar_t spurious_zs_cntr; /* Spurious counter for zs devices */
kmutex_t pokefault_mutex;
int pokefault;
/* this lock protects the following data */
/* ! non interrupt use only ! */
kmutex_t ctrl_lock; /* lock for access to FHC CSR */
volatile uint_t *ctrl; /* FHC Control and Status */
/* The JTAG master structure has internal locking */
struct jt_mstr jt_master;
/* the pointer to the kstat is stored for deletion upon detach */
kstat_t *fhc_ksp;
};
/*
* Function shared with child drivers which require fhc
* support. They gain access to this function through the use of the
* _depends_on variable.
*/
enum board_type get_board_type(int board);
void update_temp(dev_info_t *pdip, struct temp_stats *envstat, uchar_t value);
enum temp_trend temp_trend(struct temp_stats *);
void fhc_reboot(void);
int overtemp_kstat_update(kstat_t *ksp, int rw);
int temp_override_kstat_update(kstat_t *ksp, int rw);
void init_temp_arrays(struct temp_stats *envstat);
void update_board_leds(fhc_bd_t *, uint_t, uint_t);
struct jt_mstr *jtag_master_lock(void);
void jtag_master_unlock(struct jt_mstr *);
extern int fhc_board_poweroffcpus(int board, char *errbuf, int cpu_flags);
/* FHC interrupt specification */
struct fhcintrspec {
uint_t mondo;
uint_t pil;
dev_info_t *child;
struct fhc_wrapper_arg *handler_arg;
};
/* kstat structure used by fhc to pass data to user programs. */
struct fhc_kstat {
struct kstat_named csr; /* FHC Control and Status Register */
struct kstat_named bsr; /* FHC Board Status Register */
};
#endif /* _KERNEL */
#endif /* _ASM */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_FHC_H */
|