File indexing completed on 2025-05-11 08:23:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <sys/param.h>
0017 #include <sys/types.h>
0018 #include <string.h>
0019 #include "bootldr.h"
0020 #include <libcpu/spr.h>
0021 #include "zlib.h"
0022 #include <libcpu/byteorder.h>
0023 #include <rtems/bspIo.h>
0024 #include <bsp.h>
0025
0026 #include <rtems.h>
0027
0028
0029 #define PAGE_ALIGN(addr) (((addr) + PAGE_MASK) & ~PAGE_MASK)
0030
0031 SPR_RO(PPC_PVR)
0032
0033 struct inode;
0034 struct wait_queue;
0035 struct buffer_head;
0036 typedef struct { int counter; } atomic_t;
0037
0038 typedef struct page {
0039
0040 struct page *next;
0041 struct page *prev;
0042 struct inode *inode;
0043 unsigned long offset;
0044 struct page *next_hash;
0045 atomic_t count;
0046 unsigned long flags;
0047 struct wait_queue *wait;
0048 struct page **pprev_hash;
0049 struct buffer_head * buffers;
0050 } mem_map_t;
0051
0052 extern opaque mm_private, pci_private, v86_private, console_private;
0053
0054 #define CONSOLE_ON_SERIAL "console=ttyS0"
0055
0056 extern struct console_io vacuum_console_functions;
0057 extern opaque log_console_setup, serial_console_setup, vga_console_setup;
0058
0059 boot_data __bd = {0, 0, 0, 0, 0, 0, 0, 0,
0060 32, 0, 0, 0, 0, 0, 0,
0061 &mm_private,
0062 NULL,
0063 &pci_private,
0064 NULL,
0065 &v86_private,
0066 "root=/dev/hdc1"
0067 };
0068
0069 static void exit(void) __attribute__((noreturn));
0070
0071 static void exit(void) {
0072 printk("\nOnly way out is to press the reset button!\n");
0073 asm volatile("": : :"memory");
0074 while(1);
0075 }
0076
0077 void hang(const char *s, u_long x, ctxt *p) {
0078 u_long *r1;
0079 #ifdef DEBUG
0080 print_all_maps("\nMemory mappings at exception time:\n");
0081 #endif
0082 printk("%s %lx NIP: %p LR: %p\n"
0083 "Callback trace (stack:return address)\n",
0084 s, x, (void *) p->nip, (void *) p->lr);
0085 asm volatile("lwz %0,0(1); lwz %0,0(%0); lwz %0,0(%0)": "=b" (r1));
0086 while(r1) {
0087 printk(" %p:%p\n", r1, (void *) r1[1]);
0088 r1 = (u_long *) *r1;
0089 }
0090 exit();
0091 };
0092
0093 static void *zalloc(void *x, unsigned items, unsigned size)
0094 {
0095 void *p = salloc(items*size);
0096
0097 if (!p) {
0098 printk("oops... not enough memory for gunzip\n");
0099 }
0100 return p;
0101 }
0102
0103 static void zfree(void *x, void *addr, unsigned nb)
0104 {
0105 sfree(addr);
0106 }
0107
0108 #define HEAD_CRC 2
0109 #define EXTRA_FIELD 4
0110 #define ORIG_NAME 8
0111 #define COMMENT 0x10
0112 #define RESERVED 0xe0
0113
0114 #define DEFLATED 8
0115
0116 void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
0117 {
0118 z_stream s;
0119 int r, i, flags;
0120
0121
0122 i = 10;
0123 flags = src[3];
0124 if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
0125 printk("bad gzipped data\n");
0126 exit();
0127 }
0128 if ((flags & EXTRA_FIELD) != 0)
0129 i = 12 + src[10] + (src[11] << 8);
0130 if ((flags & ORIG_NAME) != 0)
0131 while (src[i++] != 0)
0132 ;
0133 if ((flags & COMMENT) != 0)
0134 while (src[i++] != 0)
0135 ;
0136 if ((flags & HEAD_CRC) != 0)
0137 i += 2;
0138 if (i >= *lenp) {
0139 printk("gunzip: ran out of data in header\n");
0140 exit();
0141 }
0142
0143 s.zalloc = zalloc;
0144 s.zfree = zfree;
0145 r = inflateInit2(&s, -MAX_WBITS);
0146 if (r != Z_OK) {
0147 printk("inflateInit2 returned %d\n", r);
0148 exit();
0149 }
0150 s.next_in = src + i;
0151 s.avail_in = *lenp - i;
0152 s.next_out = dst;
0153 s.avail_out = dstlen;
0154 r = inflate(&s, Z_FINISH);
0155 if (r != Z_OK && r != Z_STREAM_END) {
0156 printk("inflate returned %d\n", r);
0157 exit();
0158 }
0159 *lenp = s.next_out - (unsigned char *) dst;
0160 inflateEnd(&s);
0161 }
0162
0163 void decompress_kernel(int kernel_size, void * zimage_start, int len,
0164 void * initrd_start, int initrd_len ) {
0165 u_char *parea;
0166 RESIDUAL* rescopy;
0167 int zimage_size= len;
0168
0169
0170
0171
0172
0173
0174
0175 parea=__palloc(kernel_size, PA_LOW);
0176 if(!parea) {
0177 printk("Not enough memory to uncompress the kernel.");
0178 exit();
0179 }
0180
0181 rescopy=salloc(sizeof(RESIDUAL));
0182
0183 *rescopy = *bd->residual;
0184 bd->residual = (void *)PAGE_ALIGN(kernel_size);
0185
0186
0187
0188
0189 memset(parea, 0, kernel_size);
0190 printk("\nUncompressing the kernel...\n");
0191
0192 gunzip(parea, kernel_size, zimage_start, &zimage_size);
0193
0194 bd->of_entry = 0;
0195 bd->load_address = 0;
0196 bd->r6 = (char *)bd->residual+PAGE_ALIGN(sizeof(RESIDUAL));
0197 bd->r7 = bd->r6+strlen(bd->cmd_line);
0198 if ( initrd_len ) {
0199
0200
0201
0202
0203
0204
0205
0206
0207 unsigned tmp = rescopy->TotalMemory;
0208
0209
0210
0211 if ((tmp & (~tmp+1)) != tmp) tmp <<= 1;
0212 tmp /= 256;
0213 if (tmp> (2<<20)) tmp=2<<20;
0214 tmp = tmp*2 + 0x40000;
0215 tmp += (rescopy->TotalMemory / PAGE_SIZE)
0216 * sizeof(struct page);
0217 bd->load_address = (void *)PAGE_ALIGN((int)bd->r7 + tmp);
0218 bd->of_entry = (char *)bd->load_address+initrd_len;
0219 }
0220 #ifdef DEBUG
0221 printk("Kernel at 0x%p, size=0x%x\n", NULL, kernel_size);
0222 printk("Initrd at 0x%p, size=0x%x\n",bd->load_address, initrd_len);
0223 printk("Residual data at 0x%p\n", bd->residual);
0224 printk("Command line at 0x%p\n",bd->r6);
0225 #endif
0226 printk("done\nNow booting...\n");
0227 MMUoff();
0228 codemove(0, parea, kernel_size, bd->cache_lsize);
0229 codemove(bd->residual, rescopy, sizeof(RESIDUAL), bd->cache_lsize);
0230 codemove(bd->r6, bd->cmd_line, sizeof(bd->cmd_line), bd->cache_lsize);
0231
0232 codemove(bd->load_address, initrd_start, initrd_len, bd->cache_lsize);
0233 }
0234
0235 static int ticks_per_ms=0;
0236
0237
0238
0239
0240 void
0241 boot_udelay(uint32_t _microseconds)
0242 {
0243 uint32_t start, ticks, now;
0244
0245 ticks = _microseconds * ticks_per_ms / 1000;
0246 CPU_Get_timebase_low( start );
0247 do {
0248 CPU_Get_timebase_low( now );
0249 } while (now - start < ticks);
0250 }
0251
0252 void
0253 setup_hw(void)
0254 {
0255 char *cp, ch;
0256 register RESIDUAL * res;
0257
0258 struct pci_dev *default_vga;
0259 int timer, err;
0260 u_short default_vga_cmd;
0261
0262 res=bd->residual;
0263 default_vga=NULL;
0264 default_vga_cmd = 0;
0265
0266 #define vpd res->VitalProductData
0267 if (_read_PPC_PVR()>>16 != 1) {
0268 if ( res && vpd.ProcessorBusHz ) {
0269 ticks_per_ms = vpd.ProcessorBusHz/
0270 (vpd.TimeBaseDivisor ? vpd.TimeBaseDivisor : 4000);
0271 } else {
0272 ticks_per_ms = 16500;
0273 }
0274 }
0275
0276 select_console(CONSOLE_LOG);
0277
0278
0279
0280
0281 #if defined(BSP_KBD_IOBASE)
0282 err = kbdreset();
0283 if (err) select_console(CONSOLE_SERIAL);
0284 #else
0285 err = 1;
0286 select_console(CONSOLE_SERIAL);
0287 #endif
0288
0289 printk("\nModel: %s\nSerial: %s\n"
0290 "Processor/Bus frequencies (Hz): %ld/%ld\n"
0291 "Time Base Divisor: %ld\n"
0292 "Memory Size: %lx\n"
0293 "Residual: %lx (length %lu)\n",
0294 vpd.PrintableModel,
0295 vpd.Serial,
0296 vpd.ProcessorHz,
0297 vpd.ProcessorBusHz,
0298 (vpd.TimeBaseDivisor ? vpd.TimeBaseDivisor : 4000),
0299 res->TotalMemory,
0300 (unsigned long)res,
0301 res->ResidualLength);
0302
0303
0304 pci_init();
0305
0306
0307 if ( vpd.FirmwareSupplier == 0x10000 ) {
0308 int memsize;
0309 memsize = find_max_mem(bd->pci_devices);
0310 if ( memsize != res->TotalMemory ) {
0311 printk("Changed Memory size from %lx to %x\n",
0312 res->TotalMemory, memsize);
0313 res->TotalMemory = memsize;
0314 res->GoodMemory = memsize;
0315 }
0316 }
0317 #define ENABLE_VGA_USAGE
0318 #undef ENABLE_VGA_USAGE
0319 #ifdef ENABLE_VGA_USAGE
0320
0321
0322
0323
0324 for (p = bd->pci_devices; p; p = p->next) {
0325 u_short cmd;
0326 if (p->class != PCI_CLASS_NOT_DEFINED_VGA &&
0327 ((p->class) >> 16 != PCI_BASE_CLASS_DISPLAY))
0328 continue;
0329 if (p->bus->number != 0) {
0330 printk("VGA device not on bus 0 not initialized!\n");
0331 continue;
0332 }
0333
0334
0335
0336 pci_bootloader_read_config_word(p, PCI_COMMAND, &cmd);
0337 if(cmd & PCI_COMMAND_IO || !default_vga) {
0338 default_vga=p;
0339 default_vga_cmd=cmd;
0340 }
0341 }
0342
0343
0344 if (default_vga)
0345 pci_bootloader_write_config_word(default_vga, PCI_COMMAND,
0346 default_vga_cmd&
0347 ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
0348 init_v86();
0349
0350 for (p = bd->pci_devices; p; p = p->next) {
0351 u_short cmd;
0352 if (p->class != PCI_CLASS_NOT_DEFINED_VGA &&
0353 ((p->class) >> 16 != PCI_BASE_CLASS_DISPLAY))
0354 continue;
0355 if (p->bus->number != 0) continue;
0356 pci_bootloader_read_config_word(p, PCI_COMMAND, &cmd);
0357 pci_bootloader_write_config_word(p, PCI_COMMAND,
0358 cmd|PCI_COMMAND_IO|PCI_COMMAND_MEMORY);
0359 printk("Calling the emulator.\n");
0360 em86_main(p);
0361 pci_bootloader_write_config_word(p, PCI_COMMAND, cmd);
0362 }
0363
0364 cleanup_v86_mess();
0365 #endif
0366
0367 if (default_vga) {
0368 pci_bootloader_write_config_word(default_vga, PCI_COMMAND,
0369 default_vga_cmd|
0370 (PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
0371 if (err) {
0372 printk("Keyboard error %d, using serial console!\n",
0373 err);
0374 } else {
0375 select_console(CONSOLE_VGA);
0376 }
0377 } else if (!err) {
0378 select_console(CONSOLE_SERIAL);
0379 if (bd->cmd_line[0] == '\0') {
0380 strcat(&bd->cmd_line[0], CONSOLE_ON_SERIAL);
0381 }
0382 else {
0383 int s = strlen (bd->cmd_line);
0384 bd->cmd_line[s + 1] = ' ';
0385 bd->cmd_line[s + 2] = '\0';
0386 strcat(&bd->cmd_line[0], CONSOLE_ON_SERIAL);
0387 }
0388 }
0389 #if 0
0390
0391
0392
0393 nvram=residual_find_device(~0UL, NULL, SystemPeripheral, NVRAM,
0394 ~0UL, 0);
0395 if (nvram) {
0396 PnP_TAG_PACKET * pkt;
0397 switch (nvram->DevId.Interface) {
0398 case IndirectNVRAM:
0399 pkt=PnP_find_packet(res->DevicePnpHeap
0400 +nvram->AllocatedOffset,
0401 )
0402 }
0403 }
0404 #endif
0405
0406 printk("\nRTEMS " RTEMS_VERSION "/PPC load: ");
0407 timer = 0;
0408 cp = bd->cmd_line+strlen(bd->cmd_line);
0409 while (timer++ < 5*1000) {
0410 if (debug_tstc()) {
0411 while ((ch = debug_getc()) != '\n' && ch != '\r') {
0412 if (ch == '\b' || ch == 0177) {
0413 if (cp != bd->cmd_line) {
0414 cp--;
0415 printk("\b \b");
0416 }
0417 } else {
0418 *cp++ = ch;
0419 debug_putc(ch);
0420 }
0421 }
0422 break;
0423 }
0424 boot_udelay(1000);
0425 }
0426 *cp = 0;
0427 }
0428
0429
0430 static int same_DevID(unsigned short vendor,
0431 unsigned short Number,
0432 unsigned char * str)
0433 {
0434 static unsigned const char hexdigit[]="0123456789ABCDEF";
0435 if (strlen((char*)str)!=7) return 0;
0436 if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0]) &&
0437 ( ((vendor>>5)&0x1f)+'A'-1 == str[1]) &&
0438 ( (vendor&0x1f)+'A'-1 == str[2]) &&
0439 (hexdigit[(Number>>12)&0x0f] == str[3]) &&
0440 (hexdigit[(Number>>8)&0x0f] == str[4]) &&
0441 (hexdigit[(Number>>4)&0x0f] == str[5]) &&
0442 (hexdigit[Number&0x0f] == str[6]) ) return 1;
0443 return 0;
0444 }
0445
0446 PPC_DEVICE *residual_find_device(unsigned long BusMask,
0447 unsigned char * DevID,
0448 int BaseType,
0449 int SubType,
0450 int Interface,
0451 int n)
0452 {
0453 int i;
0454 RESIDUAL *res = bd->residual;
0455 if ( !res || !res->ResidualLength ) return NULL;
0456 for (i=0; i<res->ActualNumDevices; i++) {
0457 #define Dev res->Devices[i].DeviceId
0458 if ( (Dev.BusId&BusMask) &&
0459 (BaseType==-1 || Dev.BaseType==BaseType) &&
0460 (SubType==-1 || Dev.SubType==SubType) &&
0461 (Interface==-1 || Dev.Interface==Interface) &&
0462 (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff,
0463 Dev.DevId&0xffff, DevID)) &&
0464 !(n--) ) return res->Devices+i;
0465 #undef Dev
0466 }
0467 return 0;
0468 }
0469
0470 PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
0471 unsigned packet_tag,
0472 int n)
0473 {
0474 unsigned mask, masked_tag, size;
0475 if(!p) return 0;
0476 if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
0477 masked_tag = packet_tag&mask;
0478 for(; *p != END_TAG; p+=size) {
0479 if ((*p & mask) == masked_tag && !(n--))
0480 return (PnP_TAG_PACKET *) p;
0481 if (tag_type(*p))
0482 size=ld_le16((unsigned short *)(p+1))+3;
0483 else
0484 size=tag_small_count(*p)+1;
0485 }
0486 return 0;
0487 }
0488
0489 PnP_TAG_PACKET *PnP_find_small_vendor_packet(unsigned char *p,
0490 unsigned packet_type,
0491 int n)
0492 {
0493 int next=0;
0494 while (p) {
0495 p = (unsigned char *) PnP_find_packet(p, 0x70, next);
0496 if (p && p[1]==packet_type && !(n--))
0497 return (PnP_TAG_PACKET *) p;
0498 next = 1;
0499 };
0500 return 0;
0501 }
0502
0503 PnP_TAG_PACKET *PnP_find_large_vendor_packet(unsigned char *p,
0504 unsigned packet_type,
0505 int n)
0506 {
0507 int next=0;
0508 while (p) {
0509 p = (unsigned char *) PnP_find_packet(p, 0x84, next);
0510 if (p && p[3]==packet_type && !(n--))
0511 return (PnP_TAG_PACKET *) p;
0512 next = 1;
0513 };
0514 return 0;
0515 }
0516
0517
0518
0519
0520 int
0521 find_max_mem( struct pci_dev *dev )
0522 {
0523 u_char banks,tmp;
0524 int i, top, max;
0525
0526 max = 0;
0527 for ( ; dev; dev = dev->next) {
0528 if ( ((dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
0529 (dev->device == PCI_DEVICE_ID_MOTOROLA_MPC105)) ||
0530 ((dev->vendor == PCI_VENDOR_ID_IBM) &&
0531 (dev->device == 0x0037)) ) {
0532 pci_bootloader_read_config_byte(dev, 0xa0, &banks);
0533 for (i = 0; i < 8; i++) {
0534 if ( banks & (1<<i) ) {
0535 pci_bootloader_read_config_byte(dev, 0x90+i, &tmp);
0536 top = tmp;
0537 pci_bootloader_read_config_byte(dev, 0x98+i, &tmp);
0538 top |= (tmp&3)<<8;
0539 if ( top > max ) max = top;
0540 }
0541 }
0542 if ( max ) return ((max+1)<<20);
0543 else return(0);
0544 }
0545 }
0546 return(0);
0547 }