3 /* ******************************************
6 * Derived from Lance Berc's SRM console
7 * for the SRC XXM Machine
8 * ******************************************/
11 typedef unsigned long long uint64_t;
12 typedef unsigned long long uint64
;
13 typedef unsigned int uint32_t;
14 typedef unsigned int uint32
;
17 #include "alpha_access.h"
18 #include "machine_defs.h"
21 #include "new_aouthdr.h"
31 #define CONS_INT_TX 0x01 /* interrupt enable / state bits */
32 #define CONS_INT_RX 0x02
34 #define KSEG 0xfffffc0000000000
35 #define K1BASE 0xfffffc8000000000
36 #define KSEG_TO_PHYS(x)(((ul)x) & ~KSEG)
38 #define CDR ((volatile DevConsoleRegisters *) \
39 (__MAGIC_ZONE(0, 0, MAGIC_ZONE_BDOOR_DEV) + __MAGIC_BDOOR_CNSLE_OFFS))
42 #define PHYS_TO_K1(_x) (K1BASE|(_x))
44 #define AOUT_LOAD_ADDR (KSEG|0xf000)
46 #define ROUNDUP8(x) ((ul)(((ul)x)+7) & ~7)
47 #define ROUNDUP128(x) ((ul)(((ul)x)+127) & ~127)
48 #define ROUNDUP8K(x) ((ul)(((ul)(x))+8191) & ~8191)
50 #define FIRST(x) ((((ul)(x)) >> 33) & 0x3ff)
51 #define SECOND(x) ((((ul)(x)) >> 23) & 0x3ff)
52 #define THIRD(x) ((((ul)(x)) >> 13) & 0x3ff)
53 #define THIRD_XXX(x) ((((ul)(x)) >> 13) & 0xfff)
54 #define PFN(x) ((((ul)(x) & ~KSEG) >> 13))
56 /* Kernel write | kernel read | valid */
57 #define KPTE(x) ((ul)((((ul)(x)) << 32) | 0x1101))
60 #define MDT_BITMAP_PAGES 4
62 #define CSERVE_K_JTOKERN 0x18
64 #define NUM_KERNEL_THIRD (4)
67 static unixBoot(int go
, int argc
, char **argv
);
68 void jToPal(ul bootadr
);
69 void SlaveLoop(int cpu
);
72 struct AlphaAccess simosConf
;
74 /* **************************************************************
75 * Console callbacks use VMS calling conventions
76 * read AXP manual, 2-64.
77 * ***************************************************************/
78 typedef struct OpenVMSFunc
{
83 OpenVMSFunc callbackFunc
, fixupFunc
;
91 extern void SpinLock(ul
*lock
);
92 #define SpinUnlock(_x) *(_x) = 0;
94 struct _kernel_params
{
104 extern consoleCallback
[];
105 extern consoleFixup
[];
106 long CallBackDispatcher();
107 long CallBackFixup();
110 * simos console output
113 void InitConsole(void)
116 CDR
->intr_status
=(DevRegister
)(DEV_CNSLE_RX_INTR
|DEV_CNSLE_TX_INTR
);
122 struct AlphaAccess
*k1Conf
= (struct AlphaAccess
*)(__MAGIC_ZONE(0, 0, MAGIC_ZONE_EV5_ALIAS
));
123 return k1Conf
->inputChar
;
132 *(int*) PHYS_TO_K1(SLOT_D_COM1
<<5) = c
;
134 struct AlphaAccess
*k1Conf
= (struct AlphaAccess
*)(__MAGIC_ZONE(0, 0, MAGIC_ZONE_EV5_ALIAS
));
135 k1Conf
->outputChar
= c
;
145 main(int argc
, char **argv
)
148 struct AlphaAccess
*k1Conf
= (struct AlphaAccess
*)(__MAGIC_ZONE(0, 0, MAGIC_ZONE_EV5_ALIAS
));
153 printf("SimOS console \n");
155 * get configuration from backdoor
157 simosConf
.last_offset
= k1Conf
->last_offset
;
158 printf(" Got simosConfiguration %d \n",simosConf
.last_offset
);
160 for (i
=1;i
<=simosConf
.last_offset
/4;i
++) {
161 ui
*k1ptr
= (ui
*)k1Conf
+ i
;
162 ui
*ksegptr
= (ui
*)(&simosConf
.last_offset
)+i
;
167 if (simosConf
.version
!= ALPHA_ACCESS_VERSION
) {
168 panic("Console version mismatch. Console expects %d. SimOS has %d \n",
169 ALPHA_ACCESS_VERSION
,simosConf
.version
);
174 * setup arguments to kernel
176 unixBoot(1,argc
,argv
);
178 x
= *(volatile int *)(K1BASE
-4);
186 struct rpb xxm_rpb
= {
187 NULL
, /* 000: physical self-reference */
188 ((long)'H') | (((long)'W') << 8) | (((long)'R') << 16) |
189 ((long)'P' << 24) | (((long)'B') << 32), /* 008: contains string "HWRPB" */
190 6, /* 010: HWRPB version number */
191 /* the byte count is wrong, but who needs it? - lance */
192 0, /* 018: bytes in RPB perCPU CTB CRB MEDSC */
193 0, /* 020: primary cpu id */
194 8192, /* 028: page size in bytes */
195 43, /* 030: number of phys addr bits */
196 127, /* 038: max valid ASN */
197 {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1'}, /* 040: system serial num: 10 ascii chars */
199 /* To be legitimate, the following system type and variation are correct for the XXM.
200 But there are too many #ifdefs etc to deal with in Unix, so we tell the kernel
201 that we're an Avanti, which is similar enough.
203 31, /* 050: system type - XXM is now in the Alpha SRM */
204 (1 << 10) | (2<<1),/* 058: system variation - XXM w/EV5 & embeded console */
207 0x12, /* 050: system type - masquarade as some random 21064 */
209 12, /* masquerade a DEC_3000_500 (bugnion) */
210 (2<<1), /* 058: system variation */
211 'c'|('o'<<8)|('o'<<16)|('l'<< 24), /* 060: system revision */
212 1024*4096, /* 068: scaled interval clock intr freq OVERRIDEN*/
213 0, /* 070: cycle counter frequency */
214 0x200000000, /* 078: virtual page table base */
215 0, /* 080: reserved */
216 0, /* 088: offset to translation buffer hint */
217 1, /* 090: number of processor slots OVERRIDDEN*/
218 sizeof(struct rpb_percpu
), /* 098: per-cpu slot size. OVERRIDDEN */
219 0, /* 0A0: offset to per_cpu slots */
220 1, /* 0A8: number of CTBs */
222 sizeof(struct rpb_ctb
), /* 0B0: bytes in largest CTB */
224 sizeof(struct ctb_tt
),
226 0, /* 0B8: offset to CTB (cons term block) */
227 0, /* 0C0: offset to CRB (cons routine block) */
228 0, /* 0C8: offset to memory descriptor table */
229 0, /* 0D0: offset to config data block */
230 0, /* 0D8: offset to FRU table */
231 0, /* 0E0: virt addr of save term routine */
232 0, /* 0E8: proc value for save term routine */
233 0, /* 0F0: virt addr of restore term routine */
234 0, /* 0F8: proc value for restore term routine */
235 0, /* 100: virt addr of CPU restart routine */
236 0, /* 108: proc value for CPU restart routine */
237 0, /* 110: used to determine presence of kdebug */
238 0, /* 118: reserved for hardware */
239 /* the checksum is wrong, but who needs it? - lance */
240 0, /* 120: checksum of prior entries in rpb */
241 0, /* 128: receive ready bitmask */
242 0, /* 130: transmit ready bitmask */
243 0, /* 138: Dynamic System Recog. offset */
246 ul xxm_tbb
[] = { 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e,
247 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e};
249 struct rpb_percpu xxm_rpb_percpu
= {
250 {0,0,0,0,0,0,0,{0,0},{0,0,0,0,0,0,0,0}}, /* 000: boot/restart HWPCB */
251 (STATE_PA
| STATE_PP
| STATE_CV
| STATE_PV
| STATE_PMV
| STATE_PL
), /* 080: per-cpu state bits */
252 0xc000, /* 088: palcode memory length */
253 0x2000, /* 090: palcode scratch length */
254 0x4000, /* 098: phys addr of palcode mem space */
255 0x2000, /* 0A0: phys addr of palcode scratch space */
256 (2 << 16) | (5 << 8) | 1, /* 0A8: PALcode rev required */
257 5 | (2L << 32), /* 0B0: processor type */
258 7, /* 0B8: processor variation */
259 'D'|('a'<<8)|('v'<<16)|('e'<<24), /* 0C0: processor revision */
260 {'D','a','v','e','C','o','n','r','o','y',0,0,0,0,0,0}, /* 0C8: proc serial num: 10 ascii chars */
261 0, /* 0D8: phys addr of logout area */
262 0, /* 0E0: length in bytes of logout area */
263 0, /* 0E8: halt pcb base */
264 0, /* 0F0: halt pc */
265 0, /* 0F8: halt ps */
266 0, /* 100: halt arg list (R25) */
267 0, /* 108: halt return address (R26) */
268 0, /* 110: halt procedure value (R27) */
269 0, /* 118: reason for halt */
270 0, /* 120: for software */
271 {0}, /* 128: inter-console communications buffer */
272 {1,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0}, /* 1D0: PALcode revs available */
273 0 /* 250: reserved for arch use */
274 /* the dump stack grows from the end of the rpb page not to reach here */
277 struct _xxm_rpb_mdt
{
278 long rpb_checksum
; /* 000: checksum of entire mem desc table */
279 long rpb_impaddr
; /* 008: PA of implementation dep info */
280 long rpb_numcl
; /* 010: number of clusters */
281 struct rpb_cluster rpb_cluster
[3]; /* first instance of a cluster */
284 struct _xxm_rpb_mdt xxm_rpb_mdt
= {
285 0, /* 000: checksum of entire mem desc table */
286 0, /* 008: PA of implementation dep info */
287 0, /* 010: number of clusters */
288 {{ 0, /* 000: starting PFN of this cluster */
289 0, /* 008: count of PFNs in this cluster */
290 0, /* 010: count of tested PFNs in cluster */
291 0, /* 018: va of bitmap */
292 0, /* 020: pa of bitmap */
293 0, /* 028: checksum of bitmap */
294 1 /* 030: usage of cluster */
296 { 0, /* 000: starting PFN of this cluster */
297 0, /* 008: count of PFNs in this cluster */
298 0, /* 010: count of tested PFNs in cluster */
299 0, /* 018: va of bitmap */
300 0, /* 020: pa of bitmap */
301 0, /* 028: checksum of bitmap */
302 0 /* 030: usage of cluster */
304 { 0, /* 000: starting PFN of this cluster */
305 0, /* 008: count of PFNs in this cluster */
306 0, /* 010: count of tested PFNs in cluster */
307 0, /* 018: va of bitmap */
308 0, /* 020: pa of bitmap */
309 0, /* 028: checksum of bitmap */
310 0 /* 030: usage of cluster */
314 /* constants for slotinfo bus_type subfield */
315 #define SLOTINFO_TC 0
316 #define SLOTINFO_ISA 1
317 #define SLOTINFO_EISA 2
318 #define SLOTINFO_PCI 3
320 struct rpb_ctb xxm_rpb_ctb
= {
321 CONS_DZ
, /* 000: console type */
322 0, /* 008: console unit */
323 0, /* 010: reserved */
324 0 /* 018: byte length of device dep portion */
327 /* we don't do any fixup (aka relocate the console) - we hope */
328 struct rpb_crb xxm_rpb_crb
= {
329 0, /* va of call-back dispatch rtn */
330 0, /* pa of call-back dispatch rtn */
331 0, /* va of call-back fixup rtn */
332 0, /* pa of call-back fixup rtn */
333 0, /* number of entries in phys/virt map */
334 0 /* Number of pages to be mapped */
338 unsigned long length
;
342 extern struct _rpb_name xxm_name
;
344 struct rpb_dsr xxm_rpb_dsr
= {
350 struct _rpb_name xxm_name
= {
352 {'D','E','C',' ','S','R','C',' ','X','X','M',' ','D','G','C',0},
355 /* XXM has one LURT entry - 1050 is for workstations, 1100 is servers (and is needed for CXX) */
356 long xxm_lurt
[10] = { 9, 12, -1, -1, -1, -1, -1, -1, 1100, 1100 };
359 unsigned long bootadr
;
361 unsigned long aout_bss_addr
, aout_bss_size
, aout_entry
, aout_text_start
, aout_data_addr
;
366 struct rpb_percpu
*rpb_percpu
;
371 ul bootStrapImpure
[MAX_CPUS
];
374 char *unix_boot_alloc(int pages
)
376 char *ret
= (char *) unix_boot_mem
;
377 unix_boot_mem
+= (pages
* 8192);
383 ul
*reservedFixup
= 0;
385 int strcpy(char *dst
, char *src
);
389 unixBoot(int go
, int argc
, char **argv
)
391 ul
*second
, *third_kernel
, ptr
, *tbb
, size
, *percpu_logout
;
392 unsigned char *mdt_bitmap
;
393 long *lp1
, *lp2
, sum
;
396 int mem_size
= simosConf
.mem_size
;
398 int mem_pages
= mem_size
/ 8192, cons_pages
;
399 ul kernel_bytes
, ksp
, kernel_end
, *unix_kernel_stack
, bss
, ksp_bottom
, ksp_top
;
400 struct rpb_ctb
*rpb_ctb
;
401 struct ctb_tt
*ctb_tt
;
402 struct rpb_dsr
*rpb_dsr
;
403 struct rpb_crb
*rpb_crb
;
404 struct _xxm_rpb_mdt
*rpb_mdt
;
409 printf( "memsize %x pages %x \n",mem_size
,mem_pages
);
414 if (unixArgs()) return;
418 * two pages for the HWRPB
419 * five page table pages:
420 * 1: First level page table
421 * 1: Second level page table
422 * 1: Third level page table for HWRPB
423 * 2: Third level page table for kernel (for up to 16MB)
424 * set up the page tables
425 * load the kernel at the physical address 0x230000
427 * set up memory descriptor table to give up the
428 * physical memory between the end of the page
429 * tables and the start of the kernel
430 * enable kseg addressing
434 unix_boot_mem
= ROUNDUP8K(&_end
);
436 printf("First free page after ROM 0x%x\n", unix_boot_mem
);
438 rpb
= (struct rpb
*) unix_boot_alloc( HWRPB_PAGES
);
440 mdt_bitmap
= (unsigned char *) unix_boot_alloc(MDT_BITMAP_PAGES
);
441 first
= (ul
*)unix_boot_alloc(1);
442 second
= (ul
*)unix_boot_alloc(1);
443 third_rpb
= (ul
*)unix_boot_alloc(1);
444 reservedFixup
= (ul
*) unix_boot_alloc(1);
445 third_kernel
= (ul
*)unix_boot_alloc(NUM_KERNEL_THIRD
);
446 percpu_logout
= (ul
*)unix_boot_alloc(1);
449 cons_pages
= KSEG_TO_PHYS(unix_boot_mem
) / 8192;
451 /* Set up the page tables */
452 bzero((char *)first
, 8192);
453 bzero((char *)second
, 8192);
454 bzero((char *)reservedFixup
,8192);
455 bzero((char *)third_rpb
, HWRPB_PAGES
* 8192);
456 bzero((char *)third_kernel
, 8192 * NUM_KERNEL_THIRD
);
458 first
[0] = KPTE(PFN(second
));
459 first
[1] = KPTE(PFN(first
)); /* Region 3 */
461 second
[SECOND(0x10000000)] = KPTE(PFN(third_rpb
)); /* Region 0 */
462 for (i
=0;i
<NUM_KERNEL_THIRD
;i
++) {
463 second
[SECOND(0x20000000)+i
] = KPTE(PFN(third_kernel
)+i
); /* Region 1 */
465 second
[SECOND(0x40000000)] = KPTE(PFN(second
)); /* Region 2 */
470 /* For some obscure reason, Dec Unix's database read
471 * from /etc/sysconfigtab is written to this fixed
472 * mapped memory location. Go figure, since it is
473 * not initialized by the console. Maybe it is
474 * to look at the database from the console
475 * after a boot/crash.
477 * Black magic to estimate the max size. SEGVs on overflow
481 #define DATABASE_BASE 0x20000000
483 #define DATABASE_END 0x20230000 /* don't need all that */
486 #define DATABASE_END 0x20020000
489 ul
*dbPage
= (ul
*)unix_boot_alloc(1);
490 second
[SECOND(DATABASE_BASE
)] = KPTE(PFN(dbPage
));
491 for (i
=DATABASE_BASE
; i
<DATABASE_END
; i
+= 8096) {
492 ul
*db
= (ul
*)unix_boot_alloc(1);
493 dbPage
[THIRD(i
)] = KPTE(PFN(db
));
499 for (i
= 0; i
< HWRPB_PAGES
; i
++) third_rpb
[i
] = KPTE(PFN(rpb
) + i
);
501 /* Map the MDT bitmap table */
502 for (i
=0;i
<MDT_BITMAP_PAGES
;i
++) {
503 third_rpb
[HWRPB_PAGES
+i
] = KPTE(PFN(mdt_bitmap
)+i
);
506 /* Protect the PAL pages */
507 for (i
= 1; i
< PFN(first
); i
++) third_rpb
[HWRPB_PAGES
+ MDT_BITMAP_PAGES
+ i
] = KPTE(i
);
509 /* Set up third_kernel after it's loaded, when we know where it is */
512 if (unixLoadKernel(AOUT_LOAD_ADDR
, argv
[1]) == -1) return;
513 aoutfixup(AOUT_LOAD_ADDR
);
515 /* aoutfixup(simosConf.kernelFileHdr); */
520 kern_first_page
= (KSEG_TO_PHYS(aout_text_start
) / 8192);
521 kernel_end
= ksp_top
= ROUNDUP8K(aout_bss_addr
+ aout_bss_size
);
522 bootadr
= aout_entry
;
525 kern_first_page
= (KSEG_TO_PHYS(simosConf
.kernStart
)/8192);
526 kernel_end
= ksp_top
= ROUNDUP8K(simosConf
.kernEnd
);
527 bootadr
= simosConf
.entryPoint
;
530 printf("HWRPB 0x%x l1pt 0x%x l2pt 0x%x l3pt_rpb 0x%x l3pt_kernel 0x%x l2reserv 0x%x\n",
531 rpb
, first
, second
, third_rpb
, third_kernel
,reservedFixup
);
532 if (kernel_end
- simosConf
.kernStart
> (0x800000*NUM_KERNEL_THIRD
)) {
533 printf("Kernel is more than 8MB 0x%x - 0x%x = 0x%x\n",
534 kernel_end
, simosConf
.kernStart
,
535 kernel_end
-simosConf
.kernStart
);
536 panic("kernel too big\n");
539 /* Map the kernel's pages into the third level of region 2 */
541 for (ptr
= simosConf
.kernStart
; ptr
< kernel_end
; ptr
+= 8192) {
543 third_kernel
[THIRD_XXX(ptr
)] = KPTE(PFN(ptr
));
545 /* blow 2 pages of phys mem for guards since it maintains 1-to-1 mapping */
546 ksp
= ksp_top
+ (3 * 8192);
547 if (ksp
- simosConf
.kernStart
> (0x800000*NUM_KERNEL_THIRD
)) {
548 printf("Kernel stack pushd us over 8MB\n");
549 panic("ksp too big\n");
551 if (THIRD_XXX((ul
)ksp_top
) > NUM_KERNEL_THIRD
* 1024) {
552 panic("increase NUM_KERNEL_THIRD, and change THIRD_XXX\n");
555 bzero((char *)ptr
, 8192 * 2);
556 third_kernel
[THIRD_XXX(ptr
)] = 0; /* Stack Guard Page */
558 third_kernel
[THIRD_XXX(ptr
)] = KPTE(PFN(ptr
)); /* Kernel Stack Pages */
560 third_kernel
[THIRD_XXX(ptr
)] = KPTE(PFN(ptr
));
562 third_kernel
[THIRD_XXX(ptr
)] = 0; /* Stack Guard Page */
564 /* put argv into the bottom of the stack - argv starts at 1 because
565 * the command thatr got us here (i.e. "unixboot) is in argv[0].
567 ksp
-= 8; /* Back up one longword */
568 ksp
-= argc
* sizeof(char *); /* Make room for argv */
569 kargv
= (char **) ksp
;
570 for (i
= 1; i
< argc
; i
++) { /* Copy arguments to stack */
571 ksp
-= ((strlen(argv
[i
]) + 1) + 7) & ~0x7;
572 kargv
[i
-1] = (char *) ksp
;
573 strcpy(kargv
[i
-1], argv
[i
]);
576 kargv
[kargc
] = NULL
; /* just to be sure; doesn't seem to be used */
577 ksp
-= sizeof(char *); /* point above last arg for no real reason */
581 bcopy((char *)&xxm_rpb
, (char *)rpb
, sizeof(struct rpb
));
583 rpb
->rpb_selfref
= (struct rpb
*) KSEG_TO_PHYS(rpb
);
584 rpb
->rpb_string
= 0x0000004250525748;
586 tbb
= (ul
*) (((char *) rpb
) + ROUNDUP8(sizeof(struct rpb
)));
587 rpb
->rpb_trans_off
= (ul
)tbb
- (ul
)rpb
;
588 bcopy((char *)xxm_tbb
, (char *)tbb
, sizeof(xxm_tbb
));
592 * rpb_counter. Use to determine timeouts in OS.
593 * XXX must be patched after a checkpoint restore (I guess)
596 printf("CPU Clock at %d MHz IntrClockFrequency=%d \n", simosConf
.cpuClock
,simosConf
.intrClockFrequency
);
597 rpb
->rpb_counter
= simosConf
.cpuClock
* 1000 * 1000;
600 * By definition, the rpb_clock is scaled by 4096 (in hz)
602 rpb
->rpb_clock
= simosConf
.intrClockFrequency
* 4096;
607 * Per CPU Slots. Multiprocessor support.
611 int size
= ROUNDUP128(sizeof(struct rpb_percpu
));
613 printf("Booting with %d processor(s) \n",simosConf
.numCPUs
);
615 rpb
->rpb_numprocs
= simosConf
.numCPUs
;
616 rpb
->rpb_slotsize
= size
;
617 rpb_percpu
= (struct rpb_percpu
*)
618 ROUNDUP128(((ul
) tbb
) +(sizeof(xxm_tbb
)));
620 rpb
->rpb_percpu_off
= (ul
)rpb_percpu
- (ul
)rpb
;
622 for (i
=0;i
<simosConf
.numCPUs
;i
++) {
623 struct rpb_percpu
*thisCPU
= (struct rpb_percpu
*)
624 ((ul
)rpb_percpu
+ size
*i
);
626 bzero((char *)thisCPU
, size
);
627 bcopy((char *)&xxm_rpb_percpu
,
629 sizeof(struct rpb_percpu
));
631 thisCPU
->rpb_pcb
.rpb_ksp
= ksp
;
632 thisCPU
->rpb_pcb
.rpb_ptbr
= PFN(first
);
634 thisCPU
->rpb_logout
= KSEG_TO_PHYS(percpu_logout
);
635 thisCPU
->rpb_logout_len
= 8192;
637 /* thisCPU->rpb_pcb.rpb_ptbr = PFN(second);*/
639 printf("KSP: 0x%x PTBR 0x%x\n", thisCPU
->rpb_pcb
.rpb_ksp
, thisCPU
->rpb_pcb
.rpb_ptbr
);
642 bootStrapImpure
[i
] = (ul
)unix_boot_alloc(1);
647 nextPtr
= (ul
)rpb_percpu
+ size
*simosConf
.numCPUs
;
651 * Console Terminal Block
655 rpb_ctb
= (struct rpb_ctb
*) nextPtr
;
656 ctb_tt
= (struct ctb_tt
*) rpb_ctb
;
658 rpb
->rpb_ctb_off
= ((ul
)rpb_ctb
) - (ul
)rpb
;
659 rpb
->rpb_ctb_size
= sizeof(struct rpb_ctb
);
661 bzero((char *)rpb_ctb
, sizeof(struct ctb_tt
));
665 rpb_ctb
->rpb_type
= CONS_DZ
;
667 rpb_ctb
->rpb_type
= CONS_GRPH
;
668 rpb_ctb
->rpb_unit
= (SLOTINFO_PCI
<< 16) | (0 << 8) | tga_slot
;
671 rpb_ctb
->rpb_type
= CONS_DZ
;
674 rpb_ctb
->rpb_length
= sizeof(ctb_tt
)-sizeof(rpb_ctb
);
680 ctb_tt
->ctb_tivec
= 0x6c0; /* matches tlaser pal code */
681 ctb_tt
->ctb_rivec
= 0x680; /* matches tlaser pal code */
682 ctb_tt
->ctb_baud
= 9600;
683 ctb_tt
->ctb_put_sts
= 0;
684 ctb_tt
->ctb_get_sts
= 0;
687 rpb_crb
= (struct rpb_crb
*) (((ul
)rpb_ctb
) + sizeof(struct ctb_tt
));
688 rpb
->rpb_crb_off
= ((ul
)rpb_crb
) - (ul
)rpb
;
690 bzero((char *)rpb_crb
, sizeof(struct rpb_crb
));
692 * console callback stuff (simos)
695 rpb_crb
->rpb_num
= 1;
696 rpb_crb
->rpb_mapped_pages
= HWRPB_PAGES
;
697 rpb_crb
->rpb_map
[0].rpb_virt
= 0x10000000;
698 rpb_crb
->rpb_map
[0].rpb_phys
= ((ul
)rpb
) & ~0x1fff;
699 rpb_crb
->rpb_map
[0].rpb_pgcount
= HWRPB_PAGES
;
702 printf("Console Callback at 0x%x, fixup at 0x%x \n",
703 rpb_crb
->rpb_va_disp
,
704 rpb_crb
->rpb_va_fixup
);
706 rpb_mdt
= (struct _xxm_rpb_mdt
*) (((ul
)rpb_crb
) + sizeof(struct rpb_crb
));
707 rpb
->rpb_mdt_off
= (ul
)rpb_mdt
- (ul
)rpb
;
708 bcopy((char *)&xxm_rpb_mdt
, (char *)rpb_mdt
, sizeof(struct _xxm_rpb_mdt
));
713 /* Until Digital Unix can handle it, account all pages below the kernel
714 * as "console" memory. */
715 rpb_mdt
->rpb_cluster
[cl
].rpb_pfncount
= cons_pages
;
717 rpb_mdt
->rpb_cluster
[cl
].rpb_pfncount
= kern_first_page
;
720 rpb_mdt
->rpb_cluster
[cl
].rpb_pfn
= kern_first_page
;
721 rpb_mdt
->rpb_cluster
[cl
].rpb_pfncount
= mem_pages
- kern_first_page
;
722 rpb_mdt
->rpb_cluster
[cl
].rpb_pfntested
=rpb_mdt
->rpb_cluster
[cl
].rpb_pfncount
;
723 rpb_mdt
->rpb_cluster
[cl
].rpb_pa
= KSEG_TO_PHYS(mdt_bitmap
);
724 rpb_mdt
->rpb_cluster
[cl
].rpb_va
= 0x10000000 + HWRPB_PAGES
* 8192;
728 /* The stupid Unix kernel needs to have all mdt clusters in ascending
729 * order, and the last cluster is used to compute the top of memory.
730 * It can't make use of memory between the console and the kernel.
732 rpb_mdt
->rpb_cluster
[cl
].rpb_pfn
= cons_pages
;
733 rpb_mdt
->rpb_cluster
[cl
].rpb_pfncount
= kern_first_page
- cons_pages
;
734 rpb_mdt
->rpb_cluster
[cl
].rpb_pfntested
=rpb_mdt
->rpb_cluster
[cl
].rpb_pfncount
;
735 rpb_mdt
->rpb_cluster
[cl
].rpb_pa
= KSEG_TO_PHYS(mdt_bitmap
);
736 rpb_mdt
->rpb_cluster
[cl
].rpb_va
= 0x10000000 + HWRPB_PAGES
* 8192;
740 rpb_mdt
->rpb_numcl
= cl
;
742 for (i
= 0; i
< cl
; i
++)
743 printf("Memory cluster %d [%d - %d]\n", i
, rpb_mdt
->rpb_cluster
[i
].rpb_pfn
, rpb_mdt
->rpb_cluster
[i
].rpb_pfncount
);
747 /* Checksum the rpb for good luck */
749 lp1
= (long *)&rpb_mdt
->rpb_impaddr
;
750 lp2
= (long *)&rpb_mdt
->rpb_cluster
[cl
];
751 while (lp1
< lp2
) sum
+= *lp1
++;
752 rpb_mdt
->rpb_checksum
= sum
;
754 /* XXX should checksum the cluster descriptors */
756 bzero((char *)mdt_bitmap
, MDT_BITMAP_PAGES
* 8192);
757 for (i
= 0; i
< mem_pages
/8; i
++) ((unsigned char *)mdt_bitmap
)[i
] = 0xff;
759 printf("Initalizing mdt_bitmap addr 0x%x mem_pages %x \n",
760 (long)mdt_bitmap
,(long)mem_pages
);
762 xxm_rpb
.rpb_config_off
= 0;
763 xxm_rpb
.rpb_fru_off
= 0;
765 rpb_dsr
= (struct rpb_dsr
*) (((ul
)rpb_mdt
) + sizeof(struct _xxm_rpb_mdt
));
766 rpb
->rpb_dsr_off
= ((ul
)rpb_dsr
) - (ul
)rpb
;
767 bzero((char *)rpb_dsr
, sizeof(struct rpb_dsr
));
768 rpb_dsr
->rpb_smm
= 1578; /* Official XXM SMM number as per SRM */
769 rpb_dsr
->rpb_smm
= 1089; /* Official Alcor SMM number as per SRM */
771 rpb_lurt
= (int *) ROUNDUP8(((ul
)rpb_dsr
) + sizeof(struct rpb_dsr
));
772 rpb_dsr
->rpb_lurt_off
= ((ul
) rpb_lurt
) - (ul
) rpb_dsr
;
773 bcopy((char *)xxm_lurt
, (char *)rpb_lurt
, sizeof(xxm_lurt
));
775 rpb_name
= (char *) ROUNDUP8(((ul
)rpb_lurt
) + sizeof(xxm_lurt
));
776 rpb_dsr
->rpb_sysname_off
= ((ul
) rpb_name
) - (ul
) rpb_dsr
;
777 #define THENAME " SimOS ALPHA/EV5"
778 sum
= sizeof(THENAME
);
779 bcopy(THENAME
, rpb_name
, sum
);
780 *(ul
*)rpb_name
= sizeof(THENAME
); /* put in length field */
782 /* calculate size of rpb */
783 rpb
->rpb_size
= ((ul
) &rpb_name
[sum
]) - (ul
)rpb
;
785 if (rpb
->rpb_size
> 8192*HWRPB_PAGES
) {
786 panic("HWRPB_PAGES=%d too small for HWRPB !!! \n");
791 ul
*ptr
= (ul
*)((char*)rpb_dsr
+ sizeof(struct rpb_dsr
));
792 rpb_crb
->rpb_pa_disp
= KSEG_TO_PHYS(ptr
);
794 rpb_crb
->rpb_va_disp
= 0x10000000 + ((ul
)ptr
&(0x2000*HWRPB_PAGES
-1));
796 rpb_crb
->rpb_va_disp
= 0x10000000 + ((ul
)ptr
& 0x1fff);
798 printf("ConsoleDispatch at virt %x phys %x val %x\n",
799 rpb_crb
->rpb_va_disp
,
800 rpb_crb
->rpb_pa_disp
,
803 *ptr
++ = (ul
) consoleCallback
;
804 rpb_crb
->rpb_pa_fixup
= KSEG_TO_PHYS(ptr
);
806 rpb_crb
->rpb_va_fixup
= 0x10000000 + ((ul
)ptr
& (0x2000*HWRPB_PAGES
-1));
808 rpb_crb
->rpb_va_fixup
= 0x10000000 + ((ul
)ptr
& 0x1fff);
811 *ptr
++ = (ul
) consoleFixup
;
815 /* Checksum the rpb for good luck */
818 lp2
= &rpb
->rpb_checksum
;
830 for (i
=1;i
<simosConf
.numCPUs
;i
++) {
831 volatile struct AlphaAccess
*k1Conf
= (volatile struct AlphaAccess
*)
832 (__MAGIC_ZONE(0, 0, MAGIC_ZONE_EV5_ALIAS
));
834 printf("Bootstraping CPU %d with sp=0x%x \n",
835 i
,bootStrapImpure
[i
]);
836 SpinUnlock(&theLock
);
837 k1Conf
->bootStrapImpure
= bootStrapImpure
[i
];
838 k1Conf
->bootStrapCPU
= i
;
843 * Make sure that we are not stepping on the kernel
845 if ((ul
)unix_boot_mem
>= (ul
)simosConf
.kernStart
) {
846 panic("CONSOLE: too much memory. Smashing kernel \n");
849 printf("unix_boot_mem ends at %x \n",unix_boot_mem
);
850 SpinUnlock(&theLock
);
855 #define CSERVE_K_JTOKERN 0x18
856 cServe(bootadr
, (ul
) rpb_percpu
, CSERVE_K_JTOKERN
, free_pfn
);
859 if (go
) JToKern(bootadr
, rpb_percpu
, free_pfn
, kargc
, kargv
, NULL
);
867 unsigned long rem
, len
, off
, dst
;
870 struct new_aouthdr
*ao
= (struct new_aouthdr
*) &p
[NEW_FILHSZ
];
872 struct scnhdr
*s
= (struct scnhdr
*) &p
[FILHSZ
+ AOUTHSZ
];
873 struct scnhdr
*t
, *d
, *b
;
874 printf("aoutfixup: %d sections \n",fh
->f_nscns
);
878 aout_text_start
= ((ul
)ao
->text_start_hi
<<32) + ao
->text_start
;
879 aout_data_addr
= ((ul
)ao
->data_start_hi
<<32) + ao
->data_start
;
880 aout_bss_addr
= ((ul
)ao
->bss_start_hi
<<32) + ao
->bss_start
;
881 aout_bss_size
= ((ul
)ao
->bsize_hi
<<32) + ao
->bsize
;
882 aout_entry
= ((ul
)ao
->entry_hi
<<32) + ao
->entry
;
884 printf("_text 0x%16x %8d @ %08d\n", aout_text_start
, ao
->tsize
,0 /* t->s_scnptr*/);
885 printf("_data 0x%16x %8d @ %08d\n", aout_data_addr
, ao
->dsize
,0/* d->s_scnptr*/);
886 printf("_bss 0x%16x %8d\n", aout_bss_addr
, ao
->bsize
);
887 printf("entry 0x%16x\n", aout_entry
);
889 for (i
= 0; i
< fh
->f_nscns
; i
++) {
890 printf("section %d %s \n",i
,s
[i
].s_name
);
891 if (!strcmp(s
[i
].s_name
, ".text")) t
= &s
[i
];
892 else if (!strcmp(s
[i
].s_name
, ".data")) d
= &s
[i
];
893 else if (!strcmp(s
[i
].s_name
, ".bss")) b
= &s
[i
];
895 bcopy(&p
[t
->s_scnptr
], (char *)ao
->text_start
, ao
->tsize
);
896 bcopy(&p
[d
->s_scnptr
], (char *)ao
->data_start
, ao
->dsize
);
901 extern ui palJToKern
[];
903 JToKern(bootadr
, rpb_percpu
, free_pfn
, k_argc
, k_argv
, envp
)
911 struct _kernel_params
*kernel_params
= (struct _kernel_params
*) KSEG
;
914 printf("k_argc = %d ", k_argc
);
915 for (i
= 0; i
< k_argc
; i
++) {
916 printf("'%s' ", k_argv
[i
]);
920 /* rpb_percpu |= 0xfffffc0000000000;*/
921 kernel_params
->bootadr
= bootadr
;
922 kernel_params
->rpb_percpu
= KSEG_TO_PHYS(rpb_percpu
);
923 kernel_params
->free_pfn
= free_pfn
;
924 kernel_params
->argc
= k_argc
;
925 kernel_params
->argv
= (ul
)k_argv
;
926 kernel_params
->envp
= (ul
)envp
;
927 printf("jumping to kernel at 0x%x, (PCBB 0x%x pfn %d)\n", bootadr
, rpb_percpu
, free_pfn
);
928 jToPal(KSEG_TO_PHYS((ul
)palJToKern
));
929 printf("returned from jToPal. Looping\n");
934 void jToPal(ul bootadr
)
936 cServe(bootadr
, 0, CSERVE_K_JTOPAL
);
939 * Make sure that floating point is enabled incase
940 * it was disabled by the user program.
946 int strcpy(char *dst
, char *src
)
959 /* *****************************************
961 * ******************************************/
963 int numOpenDevices
= 11;
968 #define BOOTDEVICE_NAME "SCSI 1 0 0 1 100 0"
971 DeviceOperation(long op
, long channel
, long count
, long address
, long block
)
973 struct AlphaAccess
*k1Conf
= (struct AlphaAccess
*)
974 (__MAGIC_ZONE(0, 0, MAGIC_ZONE_EV5_ALIAS
));
979 printf("Console::DeviceRead count=0x%x address=0x%x block=0x%x\n",
980 count
,address
,block
);
983 if (strcmp(deviceState
[channel
].name
, BOOTDEVICE_NAME
)) {
984 panic("DeviceRead: only implemented for root disk \n");
986 pAddr
= KSEG_TO_PHYS(address
);
987 if (pAddr
+ count
> simosConf
.mem_size
) {
988 panic("DeviceRead: request out of range \n");
991 k1Conf
->diskCount
= count
;
992 k1Conf
->diskPAddr
= pAddr
;
993 k1Conf
->diskBlock
= block
;
994 k1Conf
->diskOperation
= op
; /* launch */
999 /* *************************************************************************
1000 * SimoS Console callbacks
1001 * **************************************************/
1003 /* AXP manual 2-31 */
1004 #define CONSCB_GETC 0x1
1005 #define CONSCB_PUTS 0x2
1006 #define CONSCB_RESET_TERM 0x3
1007 #define CONSCB_SET_TERM_INT 0x4
1008 #define CONSCB_SET_TERM_CTL 0x5
1009 #define CONSCB_PROCESS_KEY 0x6
1011 #define CONSCB_OPEN 0x10
1012 #define CONSCB_CLOSE 0x11
1013 #define CONSCB_READ 0x13
1015 #define CONSCB_GETENV 0x22
1017 /* AXP manual 2-26 */
1018 #define ENV_AUTO_ACTION 0X01
1019 #define ENV_BOOT_DEV 0X02
1020 #define ENV_BOOTDEF_DEV 0X03
1021 #define ENV_BOOTED_DEV 0X04
1022 #define ENV_BOOT_FILE 0X05
1023 #define ENV_BOOTED_FILE 0X06
1024 #define ENV_BOOT_OSFLAGS 0X07
1025 #define ENV_BOOTED_OSFLAGS 0X08
1026 #define ENV_BOOT_RESET 0X09
1027 #define ENV_DUMP_DEV 0X0A
1028 #define ENV_ENABLE_AUDIT 0X0B
1029 #define ENV_LICENSE 0X0C
1030 #define ENV_CHAR_SET 0X0D
1031 #define ENV_LANGUAGE 0X0E
1032 #define ENV_TTY_DEV 0X0F
1033 #define ENV_SCSIID 0X42
1034 #define ENV_SCSIFAST 0X43
1035 #define ENV_COM1_BAUD 0X44
1036 #define ENV_COM1_MODEM 0X45
1037 #define ENV_COM1_FLOW 0X46
1038 #define ENV_COM1_MISC 0X47
1039 #define ENV_COM2_BAUD 0X48
1040 #define ENV_COM2_MODEM 0X49
1041 #define ENV_COM2_FLOW 0X4A
1042 #define ENV_COM2_MISC 0X4B
1043 #define ENV_PASSWORD 0X4C
1044 #define ENV_SECURE 0X4D
1045 #define ENV_LOGFAIL 0X4E
1046 #define ENV_SRM2DEV_ID 0X4F
1048 #define MAX_ENVLEN 32
1050 char env_auto_action
[MAX_ENVLEN
] = "BOOT";
1051 char env_boot_dev
[MAX_ENVLEN
] = "";
1052 char env_bootdef_dev
[MAX_ENVLEN
] = "";
1053 char env_booted_dev
[MAX_ENVLEN
] = BOOTDEVICE_NAME
;
1054 char env_boot_file
[MAX_ENVLEN
] = "";
1055 char env_booted_file
[MAX_ENVLEN
] = "";
1056 char env_boot_osflags
[MAX_ENVLEN
] = "";
1057 char env_booted_osflags
[MAX_ENVLEN
] = "";
1058 char env_boot_reset
[MAX_ENVLEN
] = "";
1059 char env_dump_dev
[MAX_ENVLEN
] = "";
1060 char env_enable_audit
[MAX_ENVLEN
] = "";
1061 char env_license
[MAX_ENVLEN
] = "";
1062 char env_char_set
[MAX_ENVLEN
] = "";
1063 char env_language
[MAX_ENVLEN
] = "";
1064 char env_tty_dev
[MAX_ENVLEN
] = "0";
1065 char env_scsiid
[MAX_ENVLEN
] = "";
1066 char env_scsifast
[MAX_ENVLEN
] = "";
1067 char env_com1_baud
[MAX_ENVLEN
] = "";
1068 char env_com1_modem
[MAX_ENVLEN
] = "";
1069 char env_com1_flow
[MAX_ENVLEN
] = "";
1070 char env_com1_misc
[MAX_ENVLEN
] = "";
1071 char env_com2_baud
[MAX_ENVLEN
] = "";
1072 char env_com2_modem
[MAX_ENVLEN
] = "";
1073 char env_com2_flow
[MAX_ENVLEN
] = "";
1074 char env_com2_misc
[MAX_ENVLEN
] = "";
1075 char env_password
[MAX_ENVLEN
] = "";
1076 char env_secure
[MAX_ENVLEN
] = "";
1077 char env_logfail
[MAX_ENVLEN
] = "";
1078 char env_srm2dev_id
[MAX_ENVLEN
] = "";
1080 #define MAX_ENV_INDEX 100
1081 char *env_ptr
[MAX_ENV_INDEX
] =
1084 env_auto_action
, /* 0x01 */
1085 env_boot_dev
, /* 0x02 */
1086 env_bootdef_dev
, /* 0x03 */
1087 env_booted_dev
, /* 0x04 */
1088 env_boot_file
, /* 0x05 */
1089 env_booted_file
, /* 0x06 */
1090 env_boot_osflags
, /* 0x07 */
1091 env_booted_osflags
, /* 0x08 */
1092 env_boot_reset
, /* 0x09 */
1093 env_dump_dev
, /* 0x0A */
1094 env_enable_audit
, /* 0x0B */
1095 env_license
, /* 0x0C */
1096 env_char_set
, /* 0x0D */
1097 (char *)&env_language
, /* 0x0E */
1098 env_tty_dev
, /* 0x0F */
1099 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x10 - 0x1F */
1100 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x20 - 0x2F */
1101 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x30 - 0x3F */
1104 env_scsiid
, /* 0x42 */
1105 env_scsifast
, /* 0x43 */
1106 env_com1_baud
, /* 0x44 */
1107 env_com1_modem
, /* 0x45 */
1108 env_com1_flow
, /* 0x46 */
1109 env_com1_misc
, /* 0x47 */
1110 env_com2_baud
, /* 0x48 */
1111 env_com2_modem
, /* 0x49 */
1112 env_com2_flow
, /* 0x4A */
1113 env_com2_misc
, /* 0x4B */
1114 env_password
, /* 0x4C */
1115 env_secure
, /* 0x4D */
1116 env_logfail
, /* 0x4E */
1117 env_srm2dev_id
, /* 0x4F */
1118 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x50 - 0x5F */
1126 CallBackDispatcher(long a0
, long a1
, long a2
, long a3
, long a4
)
1134 for(i
= 0; i
< a3
; i
++)
1135 PutChar(*(char *)a2
+i
);
1139 if (a1
>= 0 && a1
< MAX_ENV_INDEX
&& env_ptr
[a1
] != 0 && *env_ptr
[a1
]) {
1140 i
= strcpy((char*)a2
, env_ptr
[a1
]);
1142 strcpy((char*)a2
, "");
1143 i
= (long)0xc000000000000000;
1144 if (a1
>= 0 && a1
< MAX_ENV_INDEX
)
1145 printf ("GETENV unsupported option %d (0x%x)\n", a1
, a1
);
1147 printf ("GETENV unsupported option %s\n", a1
);
1151 panic("CONSCB_GETENV overwrote buffer\n");
1155 bcopy((char*)a1
,deviceState
[numOpenDevices
].name
,a2
);
1156 deviceState
[numOpenDevices
].name
[a2
] = '\0';
1157 printf("CONSOLE OPEN : %s --> success \n",
1158 deviceState
[numOpenDevices
].name
);
1159 return numOpenDevices
++;
1162 DeviceOperation(a0
,a1
,a2
,a3
,a4
);
1169 panic("cher (%x,%x,%x,%x)\n", a0
, a1
, a2
, a3
);
1175 long CallBackFixup(int a0
, int a1
, int a2
)
1177 printf("CallbackFixup %x %x \n",a0
,a1
);
1180 if (first
[FIRST(a1
)]==0) {
1181 first
[FIRST(a1
)] = KPTE(PFN(reservedFixup
));
1183 panic("CallBakcfixup\n");
1185 second
[SECOND(a1
)] = KPTE(PFN(third_rpb
)); /* Region 0 */
1186 printf("Fixup: FISRT(a1)=0x%x SECOND(a1)=0x%x THIRD(a1)=0x%x\n",
1187 FIRST(a1
),SECOND(a1
),THIRD(a1
));
1197 void SlaveCmd(int cpu
, struct rpb_percpu
*my_rpb
)
1199 /* extern void palJToSlave[]; */
1200 extern unsigned int palJToSlave
[];
1203 my_rpb
->rpb_state
|= STATE_BIP
;
1204 my_rpb
->rpb_state
&= ~STATE_RC
;
1207 printf("SlaveCmd: restart %x %x vptb %x my_rpb %x my_rpb_phys %x\n",
1209 rpb
->rpb_restart_pv
,
1210 rpb
->rpb_vptb
, my_rpb
,
1211 KSEG_TO_PHYS(my_rpb
));
1212 SpinUnlock(&theLock
);
1214 cServe(KSEG_TO_PHYS((ul
)palJToSlave
),
1215 (ul
)rpb
->rpb_restart
,
1217 rpb
->rpb_restart_pv
,
1219 KSEG_TO_PHYS(my_rpb
));
1222 void SlaveLoop( int cpu
)
1224 int size
= ROUNDUP128(sizeof(struct rpb_percpu
));
1225 struct rpb_percpu
*my_rpb
= (struct rpb_percpu
*)
1226 ((ul
)rpb_percpu
+ size
*cpu
);
1231 panic("CPU 0 entering slaveLoop. Reenetering the console. HOSED \n");
1233 printf("Entering slaveloop for cpu %d my_rpb=%x \n",cpu
,my_rpb
);
1235 SpinUnlock(&theLock
);
1238 for (i
=0; i
< 1000000 ; i
++) {
1239 if (my_rpb
->rpb_iccb
.iccb_rxlen
) {
1241 printf("Slave CPU %d console command %s",
1242 cpu
,my_rpb
->rpb_iccb
.iccb_rxbuf
);
1243 SpinUnlock(&theLock
);
1244 SlaveCmd(cpu
,my_rpb
);
1245 panic("SlaveCmd returned \n");