Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:54

0001 /* A fake 'bios' which does nothing but move a kernel image 
0002  * to RAM address zero and then starts that...
0003  */
0004 
0005 #include <bsp/residual.h>
0006 
0007 #define LD_CACHE_LINE_SIZE  5
0008 #define INIT_STACK (0x100 - 16) /* 16-byte/svr4 aligned */
0009 
0010 /* These offsets must correspond to declaration in qemu_fakeres.c */
0011 #define DAT_LEN    0
0012 #define RES_OFF    4
0013 #define CMD_OFF    8
0014 #define CMD_LEN   12
0015 #define IMG_ADR   16
0016 
0017 /* Non-volatile registers */
0018 #define OBASE     30
0019 #define PCID      25
0020 #define PCIA      26
0021 
0022 #define PCI_MAX_DEV 32
0023 
0024 #define BA_OPCODE(tgt)  ((18<<(31-5)) | 2 | ((tgt) & 0x03fffffc))
0025 
0026     .global fake_data
0027     .global res_set_memsz
0028 
0029     .global _start
0030 _start:
0031     lis    1,  INIT_STACK@h
0032     ori    1,1,INIT_STACK@l
0033 
0034         /* qemu 0.14.1 has the wrong exception prefix for 74xx CPUs
0035          * (bug 811683). Work around this by putting a stub at 0x00000X00
0036          * which simply jumps to high memory. We only need the SC exception
0037          * for now.
0038          */
0039     lis  3,    BA_OPCODE(0xfff00000)@h
0040     ori  3, 3, BA_OPCODE(0xfff00000)@l
0041     li   4, 0x0c00
0042     add  3, 3, 4
0043     stw  3, 0(4)
0044     dcbf 0, 4
0045     icbi 0, 4
0046 
0047     bl     pci_irq_set
0048         /* copy residual to RAM and fix up; 
0049          * this routine returns a pointer to
0050          * a 'fake_data' struct. If reading
0051          * NVRAM failed then the return value
0052          * points to a fall-back version in
0053          * ROM...
0054          */
0055     bl     res_copy
0056         /* fake_data pointer to R29 */
0057     mr     29, 3
0058 
0059         /* Load up R3..R5 with PreP mandated 
0060          * values (R3: residual, R4: kernel image,
0061          * R5: OpenFirmware PTR (or NULL).
0062          */
0063 
0064         /* load R3 with residual pointer  */
0065     lwz    3, RES_OFF(29)
0066     add    3, 3, 29
0067 
0068         /* load R4 with image address     */
0069     lwz    4, IMG_ADR(29)
0070 
0071         /* load R5 with zero (OFW = NULL) */
0072     li     5, 0
0073         /* EXTENSION: R6 = cmdline start  */
0074     lwz    6, CMD_OFF(29)
0075     add    6, 6, 29
0076         /* EXTENSION: R7 = cmdline end    */
0077     lwz    7, CMD_LEN(29)
0078     add    7, 7, 6
0079 
0080         /* jump to image address          */
0081     mtctr  4
0082     bctr
0083 
0084     .org 0x100
0085     b    _start
0086 
0087     .org 0x110
0088 template:
0089     mfsrr0 30
0090     mfsrr1 31
0091 1:  b      1b
0092 template_end:
0093 
0094     .org 0xc00
0095     b    monitor
0096     
0097 
0098     .org 0x4000
0099 codemove: /* src/dst are cache-aligned */
0100     addi   5,5,(1<<LD_CACHE_LINE_SIZE)-1
0101     srwi   5,5,LD_CACHE_LINE_SIZE
0102     addi   3,3,-4
0103     addi   4,4,-4
0104 1:
0105     li     0,  (1<<LD_CACHE_LINE_SIZE)
0106     mtctr  0
0107 2:
0108     lwzu   0,  4(3)
0109     stwu   0,  4(4)
0110     bdnz   2b
0111     dcbf   0,4
0112     icbi   0,4
0113     addic. 5,5,-1
0114     bne  1b
0115     blr
0116 
0117 cpexc:
0118     lis    3,template@h
0119     ori    3,3,template@l
0120     li     5,template_end-template
0121     b      codemove
0122 
0123 monitor:
0124     stwu   1,-16(1)
0125     stw    OBASE, 8(1)
0126     lis    OBASE, 0x80000000@h
0127     cmplwi 10,0x63 /* enter_monitor -> RESET */
0128     bne    10f
0129 hwreset:
0130     li   3,1
0131     stb  3,0x92(OBASE)
0132 1:  b 1b
0133 10: cmplwi 10,0x1d /* .NETCTRL -> ignore */
0134     bne    10f
0135     b      ret_from_mon
0136 10: b hwreset      /* unknown -> RESET */ 
0137 
0138 ret_from_mon:
0139     lwz    OBASE,8(1)
0140     lwz    1,0(1)
0141     rfi
0142 
0143 rcb:
0144     stwbrx 3, 0, PCIA
0145     lbzx   3, 0, PCID
0146     blr
0147 
0148 wcb:
0149     stwbrx 3, 0, PCIA
0150     stbx   4, 0, PCID
0151     blr
0152 
0153 rcd:
0154     stwbrx 3, 0, PCIA
0155     lwbrx  3, 0, PCID
0156     blr
0157 
0158 /* fixup pci interrupt line register according to what
0159  * qemu does: line = ((pin-1) +  slot_no) & 1 ? 11 : 9;
0160  */
0161 pci_irq_set:
0162         /* set up stack frame */
0163     stwu    1, -32(1)
0164     mflr    0
0165     stw     0,  32+4(1)
0166         /* load counter with # of PCI devs */   
0167     li      0, PCI_MAX_DEV
0168     mtctr   0
0169         /* save non-volatile registers we use
0170          * in stack frame
0171          */
0172     stw    20,               8(1)
0173     stw  PCIA,              12(1)
0174     stw  PCID,              16(1)
0175         /* load non-volatile registers with
0176          * intended values.
0177          */
0178     lis  20,         0x80000000@h /* key for slot # 0             */
0179     lis  PCIA,       0x80000cf8@h /* PCI config space address reg */
0180     ori  PCIA, PCIA, 0x80000cf8@l 
0181     addi PCID, PCIA, 4            /* PCI config space data    reg */
0182 
0183         /* loop over all slots and fix up PCI IRQ LINE */
0184 1:
0185     mr   3, 20
0186     bl   rcd
0187     addi 3, 3, 1
0188     cmplwi 3, 0      /* slot empty (= -1 + 1 = 0) ? */
0189     beq  2f
0190     addi 3, 20, 0x3d
0191     bl   rcb
0192     cmplwi 3, 0
0193     beq  2f
0194     slwi  4, 3, 11
0195     addi  3, 20, 0x3c
0196     xor   4, 4, 3    /* bit 11 = slot # + irq_num [zero-based] + 1 */
0197     andi. 4, 4, 0x0800
0198     li   4, 11
0199     beq  3f
0200     li   4,  9
0201 3:
0202     bl   wcb
0203 2:
0204     addi 20, 20, 0x0800 /* next slot */
0205     bdnz 1b
0206 
0207         /* restore and return */
0208     lwz 20,  32+4(1)
0209     mtlr 20
0210     lwz PCID, 16(1)
0211     lwz PCIA, 12(1)
0212     lwz 20,    8(1)
0213     lwz 1,     0(1)
0214     blr
0215 
0216     .section .romentry, "ax"
0217     b     _start