www.pudn.com > vxworks0108.rar > romInit.s
/* romInit.s - SBS Technologies VG4 ROM initialization module */
/*
DESCRIPTION
This module contains the entry code for the VxWorks bootrom.
The entry point romInit, is the first code executed on power-up.
It sets the BOOT_COLD parameter to be passed to the generic
romStart() routine.
The routine sysToMonitor() jumps to the location 4 bytes
past the beginning of romInit, to perform a "warm boot".
This entry point allows a parameter to be passed to romStart().
This code is intended to be generic across PowerPC 603/604 boards.
Hardware that requires special register setting or memory
mapping to be done immediately, may do so here.
*/
#define _ASMLANGUAGE
#include "config.h"
#include "reg.h"
#include "ppc750.h"
#include "vg4.h"
#include "mpc107.h"
#define SDRAM_SIZE 512 /* valid values : 64, 128, 256, 512 */
#define LOADREG(reg,const32) \
addis reg,r0,HI(const32); ori reg,reg,LO(const32)
/*
* Use this macro to prevent reordering by as/ld and processor
*/
#define IORDER eieio; sync
/*
* I2C Registers.
*/
#define MPC107_I2C_ADR (I2C_BASE_ADRS)
#define MPC107_I2C_FDR (I2C_BASE_ADRS + 0x0004)
#define MPC107_I2C_CCR (I2C_BASE_ADRS + 0x0008)
#define MPC107_I2C_CSR (I2C_BASE_ADRS + 0x000c)
#define MPC107_I2C_CDR (I2C_BASE_ADRS + 0x0010)
#define I2C_CCR_TXAK 0x08 /* Transfer ack */
#define I2C_CSR_MCF 0x80 /* Transfer complete */
#define I2C_CSR_MBB 0x20 /* Bus busy */
#define I2C_CSR_MIF 0x02 /* Interrupt */
#define I2C_CSR_RXAK 0x01 /* No receive ack */
#define I2C_READ 1
#define I2C_WRITE 0
/* Exported internal functions */
.type _romInit,@function
.type romInit,@function
.type _romInitWarm,@function
.type romInitWarm,@function
.type _romInitPmon,@function
.type romInitPmon,@function
.globl _romInit /* start of system code */
.globl romInit /* start of system code */
.globl _romInitWarm /* warm boot entry point */
.globl romInitWarm /* warm boot entry point */
.globl _romInitPmon
.globl romInitPmon
.globl romPuts
.globl board_led_on
#if defined (ROM_DEBUG)
.globl romPuts
#endif /* if defined (ROM_DEBUG)*/
/* externals */
.extern romStart /* system initialization routine */
.text
.align 2
/*
* After reset, the processor fetches from ROM_BASE_ADRS + 0x100.
* We offset the _romInit entry by 0x100 bytes to compensate.
* In other WRS PPC BSP's, this offset was accounted for in the
* elfHex stage of building the rom image by setting HEX_FLAGS
* to "-a 100". Explictly adding the space here seems more
* straitforward, and it also helps when not using elfToHex
* such as in a flash programmed binary image. Therefore
* the VG4 BSP Makefile uses HEX_FLAGS of "-a 0".
* This also means that ROM_TEXT_ADRS must be defined
* equivalent to ROM_BASE_ADRS + 0x100 in config.h and Makefile.
*/
.ascii "SBS_JMP""\0" /* Boot Description Header ID */
.long 0x00010000 /* Boot Description Header V1.0 */
.long ROM_TEXT_ADRS
.long 0x00000000 /* Boot Description Header dummy size */
.long 0x00000000 /* Boot Description Header dummy crc */
.space (0xe8)
/******************************************************************************
*
* romInit - entry point for VxWorks in ROM
*
* romInit
* (
* int startType /@ only used by 2nd entry point @/
* )
*/
_romInit:
romInit:
bl cold
nop
/*
* This warm boot entry point is defined as ROM_WARM_ADRS in config.h.
* It is defined as an offset from ROM_TEXT_ADRS. Please make sure
* that the offset from _romInit to romInitWarm matches that specified
* in config.h. Since WRS is standardizing this offset to 8 bytes,
* we insert a nop to ensure romInitWarm is a 8 byte offset from
* ROM_TEXT_ADRS.
*/
_romInitWarm:
romInitWarm:
nop
nop
/*
* This boot entry point is used by sysToPmon(). It's treated like
* a vxWorks warm reboot.
*/
_romInitPmon:
romInitPmon:
bl warm
/* copyright notice appears at beginning of ROM (in TEXT segment) */
.align 2
.ascii "Copyright 1984-1999 Wind River Systems, Inc. "
.ascii "\0"__DATE__"\0"
.ascii "\0"__TIME__"\0"
#if defined (ADRS_MAP_PREP)
.ascii "MPC107 MAP A"
#else
.ascii "MPC107 MAP B"
#endif /* #if defined (ADRS_MAP_PREP) */
.align 2
cold:
li r12, 1
bl start /* skip over next instruction */
warm:
or r12, r3, r3 /* startType to r12 */
start:
/* Zero-out registers: r0 & SPRGs */
xor r0, r0, r0
mtspr 272, r0
mtspr 273, r0
mtspr 274, r0
mtspr 275, r0
/*
* Set HID0 to a known state
* Enable machine check input pin (EMCP) for DRAM ECC detection.
* Don't touch hard reset bit.
*/
mfspr r3, HID0
isync
rlwinm r4, r3, 0, 15, 15 /* r4 has NHR bit cleared */
addis r4, r4, 0x8000
sync
isync
mtspr HID0, r4 /* HID0 = r4 */
isync
/*
* Set MPU/MSR to a known state
* Turn on FP
*/
andi. r3, r3, 0
ori r3, r3, 0x2000
sync
mtmsr r3
isync
/* Init the floating point control/status register */
mtfsfi 7,0x0
mtfsfi 6,0x0
mtfsfi 5,0x0
mtfsfi 4,0x0
mtfsfi 3,0x0
mtfsfi 2,0x0
mtfsfi 1,0x0
mtfsfi 0,0x0
isync
/* Initialize the floating point data regsiters to a known state */
bl ifpdr_value
.long 0x3f800000 /* 1.0 */
ifpdr_value:
mfspr r3,8
lfs f0,0(r3)
lfs f1,0(r3)
lfs f2,0(r3)
lfs f3,0(r3)
lfs f4,0(r3)
lfs f5,0(r3)
lfs f6,0(r3)
lfs f7,0(r3)
lfs f8,0(r3)
lfs f9,0(r3)
lfs f10,0(r3)
lfs f11,0(r3)
lfs f12,0(r3)
lfs f13,0(r3)
lfs f14,0(r3)
lfs f15,0(r3)
lfs f16,0(r3)
lfs f17,0(r3)
lfs f18,0(r3)
lfs f19,0(r3)
lfs f20,0(r3)
lfs f21,0(r3)
lfs f22,0(r3)
lfs f23,0(r3)
lfs f24,0(r3)
lfs f25,0(r3)
lfs f26,0(r3)
lfs f27,0(r3)
lfs f28,0(r3)
lfs f29,0(r3)
lfs f30,0(r3)
lfs f31,0(r3)
sync
/*
* Set MPU/MSR to a known state
* Turn off FP
*/
andi. r3, r3, 0
sync
mtmsr r3
isync
/* Get cpu type */
mfspr r28, PVR
rlwinm r27, r28, 0, 16, 31
rlwinm r28, r28, 16, 16, 31
/* Init the Segment registers */
andi. r3, r3, 0
isync
mtsr 0,r3
isync
mtsr 1,r3
isync
mtsr 2,r3
isync
mtsr 3,r3
isync
mtsr 4,r3
isync
mtsr 5,r3
isync
mtsr 6,r3
isync
mtsr 7,r3
isync
mtsr 8,r3
isync
mtsr 9,r3
isync
mtsr 10,r3
isync
mtsr 11,r3
isync
mtsr 12,r3
isync
mtsr 13,r3
isync
mtsr 14,r3
isync
mtsr 15,r3
isync
/* Invalidate all BAT entries by setting upper BAT registers to zero */
mtspr IBAT0U, r3
isync
mtspr IBAT1U, r3
isync
mtspr IBAT2U, r3
isync
mtspr IBAT3U, r3
isync
mtspr DBAT0U, r3
isync
mtspr DBAT1U, r3
isync
mtspr DBAT2U, r3
isync
mtspr DBAT3U, r3
isync
/* Check CPU type resp. revision */
cmplwi r28, CPU_TYPE_750
bne INVAL_L1
cmplwi r27, CPU_REV_750_IBM
bnl INVAL_L1
cmpli cr0, r27, CPU_REV_755
blt INVAL_L1
/* Disable additional BATs for 755 processor */
mtspr IBAT4U, r3
isync
mtspr IBAT5U, r3
isync
mtspr IBAT6U, r3
isync
mtspr IBAT7U, r3
isync
mtspr DBAT4U, r3
isync
mtspr DBAT5U, r3
isync
mtspr DBAT6U, r3
isync
mtspr DBAT7U, r3
isync
/* Set HID2 to known state (755 processors) */
andi. r3, r3, 0
mtspr HID2, r3
/* invalidate the MPU's data/instruction caches */
INVAL_L1:
mfspr r3,HID0
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0xCC00 /* Setup bit pattern for ICE/ICFI/DCE/DCFI */
or r3,r4,r3
isync
mtspr HID0,r3 /* set ICE/ICFI/DCE/DCFI */
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x0C00 /* Setup bit pattern for ICFI/DCFI */
andc r3,r3,r4
isync
mtspr HID0,r3 /* clear ICFI/DCFI (bit 16/17) */
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x3000 /* Setup bit pattern for ILOCK/DLOCK */
andc r3,r3,r4
isync
mtspr HID0,r3 /* clear ILOCK/DLOCK (bit 18/19) */
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x4000 /* Setup bit pattern for DCE */
andc r3,r3,r4
isync
mtspr HID0,r3 /* disable data cache by clearing DCE (bit 17), */
/* instruction cache is already enabled */
sync
/*
* Enable branch history table and branch target instruction cache.
*/
#ifndef USER_BHT_DISABLE
ori r3, r3, 0x0004 /* Set BHTE (bit 29) */
#endif
#ifndef USER_BTIC_DISABLE
ori r3, r3, 0x0020 /* Set BTIC (bit 26) */
#endif
isync /* setting of ICE bit must be preceeded by isync */
mtspr HID0,r3
sync
isync /* setting of ICE bit must be preceeded by isync */
b MPC107_INIT
MPC107_INIT:
/*
* Below we setup the MPC107 embedded memory controller.
* This procedure detects the current MPC107's address map
* configuration. Address map A conforms to the PowerPC
* reference platform specification (PReP). Map B conforms
* to the PowerPC microprocessor common hardware reference
* platform (CHRP).
* A board pull up/down resistor selects the map in hardware.
* We assume that the memory map is Map A (default on VG4),
* and attempt to read the MPC107's PCI Vendor and Device IDs.
* If the read value is ok, then use map A, else assume map B.
* Emulation mode address mapping is not suppported.
* No "compatability hole" is configured.
*/
mpc107_map_test:
lis r1, HI(MPC107_CFG_ADDR_PREP) /* r1 = PCI config address register */
ori r1, r1, LO(MPC107_CFG_ADDR_PREP)
lis r2, HI(MPC107_CFG_DATA_PREP) /* r2 = PCI config data register */
ori r2, r2, LO(MPC107_CFG_DATA_PREP)
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_VEND_ID /* processor configuration register 1 (0xa8) */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
lwbrx r3, 0, r2 /* read chaparral device id */
isync
lis r4, HI(PCI_ID_CHAPARRAL)
ori r4, r4, LO(PCI_ID_CHAPARRAL)
cmpl 0, 0, r3, r4
bne detected_chrp
b detected_prep
detected_prep:
/* Load PReP settings */
lis r1, HI(MPC107_CFG_ADDR_PREP) /* r1 = PCI config address register */
ori r1, r1, LO(MPC107_CFG_ADDR_PREP)
lis r2, HI(MPC107_CFG_DATA_PREP) /* r2 = PCI config data register */
ori r2, r2, LO(MPC107_CFG_DATA_PREP)
#if defined (ADRS_MAP_PREP)
/* Do nothing, PReP settings already loaded */
#else
/* Set PCI address map B (CHRP) */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_PRC1 /* processor configuration register 1 (0xa8) */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
rlwinm r4, r4, 0, 16, 14 /* adress map B: bit 16 (ADDRESS_MAP) = 0 */
stwbrx r4, 0, r2
sync
/* Reload CHRP settings */
lis r1, HI(MPC107_CFG_ADDR_CHRP) /* r1 = PCI config address register */
ori r1, r1, LO(MPC107_CFG_ADDR_CHRP)
lis r2, HI(MPC107_CFG_DATA_CHRP) /* r2 = PCI config data register */
ori r2, r2, LO(MPC107_CFG_DATA_CHRP)
/* Configure Address Map B Options Register */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_AMBOR /* register number 0xe0 */
stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
isync
li r4, 0x80 /* CPU_FD_ALIAS_EN = 1, PCI_FD_ALIAS_EN = 0*/
stb r4, 0(r2) /* Store data */
sync
#endif /* #if defined (ADRS_MAP_PREP) */
b mpc107_ambor
detected_chrp:
/* Load CHRP settings */
lis r1, HI(MPC107_CFG_ADDR_CHRP) /* r1 = PCI config address register */
ori r1, r1, LO(MPC107_CFG_ADDR_CHRP)
lis r2, HI(MPC107_CFG_DATA_CHRP) /* r2 = PCI config data register */
ori r2, r2, LO(MPC107_CFG_DATA_CHRP)
#if defined (ADRS_MAP_PREP)
/* Set PCI address map B (CHRP) */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_PRC1 /* processor configuration register 1 (0xa8) */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
oris r4, r4, 0x0001 /* adress map B: bit 16 (ADDRESS_MAP) = 1 */
stwbrx r4, 0, r2
sync
/* Reload PReP settings */
lis r1, HI(MPC107_CFG_ADDR_PREP) /* r1 = PCI config address register */
ori r1, r1, LO(MPC107_CFG_ADDR_PREP)
lis r2, HI(MPC107_CFG_DATA_PREP) /* r2 = PCI config data register */
ori r2, r2, LO(MPC107_CFG_DATA_PREP)
#endif /* #if defined (ADRS_MAP_PREP) */
b mpc107_ambor
mpc107_ambor:
#if !defined (ADRS_MAP_PREP)
/* Configure Address Map B Options Register */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_AMBOR /* register number 0xe0 */
stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
isync
li r4, 0x80 /* CPU_FD_ALIAS_EN = 1, PCI_FD_ALIAS_EN = 0*/
stb r4, 0(r2) /* Store data */
sync
#endif /* #if !defined (ADRS_MAP_PREP) */
/*
* Switch off watchdog
*/
bl wd_off
/*
* Embedded utilities memory block base address
*
* EUMBBAR defines a local address for the I2C, I2O, DMA, EPIC, ATU
* and other registers.
* PCSRBAR defines the PCI address for the EUMB
*
* Remember that this area must be enabled in a BAT to be accessible.
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_EUMBBAR /* register number 0x78 */
stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
isync
lis r4, HI(CPU_EUMB_ADRS) /* Local base address for EUMB */
stwbrx r4, r0, r2 /* write modified data to CONFIG_DATA */
sync
/*
* Store memory bus speed into Timer Frequency Reporting Register (TFFR) of MPC107.
* The value of the memory bus speed has been determined before the SDRAM
* initialization and is still in r25.
*/
lis r3, ((EPIC_ADDR (EPIC_TIMER_FREQ_REG)) >> 16)
ori r3, r3, ((EPIC_ADDR (EPIC_TIMER_FREQ_REG)) & 0xffff)
lis r4, ((MEMORY_BUS_SPEED) >> 16)
ori r4, r4, ((MEMORY_BUS_SPEED) & 0xffff)
stwbrx r4, r0, r3 /* store r4 into TFFR */
/*
* Make sure we're disabling RAM interface logic
* by clearing MEMGO bit. Needed for warm boots
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR1 /* register number 0xf0 */
stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0xfff7 /* MEMGO=0 */
ori r0, r0, 0xffff
and r4, r4, r0 /* Clear MEMGO bit */
stwbrx r4, r0, r2 /* write modified data to CONFIG_DATA */
/*
* This section of code inits the MPC107's PCI Interface Registers
*/
INIT_PCI:
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_PCI_CMD /* register number 0x0004 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lhbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0x0000
ori r0, r0, 0xfca0
and r4, r4, r0 /* Preserve reserve bits */
lis r0, 0x0000
ori r0, r0, 0x0106 /* Enable bus master function and memory space access */
or r4, r4, r0 /* sets the desired bits */
sthbrx r4, 0, r2 /* write modfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_PCI_STAT /* register number 0x0006 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
li r3, 0x0002
lhbrx r4, r3, r2 /* load r4 from CONFIG_DATA */
ori r4, r4, 0xff80 /* ones clears all bits in PCI_STAT */
sthbrx r4, r3, r2 /* write mdfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_PRC1 /* processor configuration register 1 (0xa8) */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0xff39
ori r0, r0, 0x0300
and r4, r4, r0 /* Preserve reserved bits (includes memory map bit) */
lis r0, 0x0004 /* 603e, 7xx, 74xx processor type */
#ifdef PREFETCH_ENABLE
ori r0, r0, 0x1294
/* prefetch reads (speculative PCI reads) */
/* snoop looping enabled */
/* Flash write enabled */
#else
ori r0, r0, 0x1290
/* no prefetch reads, */
/* snoop looping enabled */
/* Flash write enabled */
#endif
or r4, r4, r0
stwbrx r4, 0, r2
/* Make sure we disable reporting of parity errors until */
/* memory has been scrubed. Enabling of reporting occurs */
/* in sysHwInit(). */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_EER1 /* register number 0xc0 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lbz r4, 0(r2) /* Load data */
andi. r4, r4, 0xFB /* Disable single-bit ECC error trigger exceeded reporting */
/* ori r4, r4, 0x04 */ /* Enable single-bit ECC error trigger exceeded reporting */
stb r4, 0(r2) /* Store data */
/* Disable multibit ECC erorrs for SDRAM */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_EER2 /* register number 0xc4 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lbz r4, 0(r2) /* Load data */
andi. r4, r4, 0xF7 /* Disable multibit ECC error (must be disabled for SDRAM) */
stb r4, 0(r2) /* Store data */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3,MPC107_MCCR1 /* register number 0xf0 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
/* REDUCE WAIT STATES FOR ROM ACCESSES */
#ifdef MPC107_66 /* 66 MHz */
lis r0, 0x0480 /* ROMNAL: 0 , ROMFAL: 9*/
#else /* 100 MHz */
lis r0, 0x0780 /* ROMNAL: 0 , ROMFAL: 15*/
#endif
/* oris r0, r0, 0x0004 */ /* Self-refresh enable */
/* oris r0, r0, 0x0001 */ /* Parity check */
#if SDRAM_SIZE == 512
ori r0, r0, 0x000a /* 2 banks with 13 row bits (SDRAM) */
#elif SDRAM_SIZE == 256
ori r0, r0, 0x0002 /* 1 bank with 13 row bits (SDRAM) */
#else/* 64, 128 MB */
ori r0, r0, 0x0000 /* 1 bank with 12 row bits (SDRAM) */
#endif
and r4, r4, r0 /* clears the desired bits */
or r4, r4, r0 /* sets the desired bits */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new register number */
ori r3, r3, MPC107_MCCR2 /* register number 0xf4 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lis r4, 0x0000
#ifdef MPC107_66 /* 66 MHz */
oris r4, r4, 0x6000 /* TS_WAIT_TIMER = 4 clocks (for 55 ns) */
#else /* 100 MHz */
oris r4, r4, 0xa000 /* TS_WAIT_TIMER = 6 clocks (for 55 ns) */
#endif
oris r4, r4, 0x0008 /* SDRAM inline writes */
oris r4, r4, 0x0004 /* SDRAM inline reads */
#ifdef MPC107_66 /* 66 MHz */
ori r4, r4, 0x0920 /* Refresh: 66 MHz mem bus */
#else /* 100 MHz */ /* 649 - 65 (10% security) = 584 */
ori r4, r4, 0x0f30 /* Refresh: 100 MHz mem bus */
#endif /* 1080 - 108 (10% security) = 972 */
/* ori r4, r4, 0x0002 */ /* Reserve a page */
ori r4, r4, 0x0001 /* RWM parity */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR3 /* register number 0xf8 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0x000f /* Bits 31 .. 20 used for SDRAM */
ori r0, r0, 0xffff
and r4, r4, r0
lis r0, 0x7000 /* BSTOPRE_M = 7 (see A/N) */
#ifdef MPC107_66 /* 66 MHz */
oris r0, r0, 0x0540 /* REFREC = 5 clocks */
/* RDLAT = 4 clocks (CAS latency + 1 for registered buffer mode) */
/* (CAS latency + 2 for in-line buffer mode) */
#else /* 100 MHz */
oris r0, r0, 0x0750 /* REFREC = 7 clocks */
/* RDLAT = 5 clocks (CAS latency + 1 for registered buffer mode) */
/* (CAS latency + 2 for in-line buffer mode) */
#endif
or r4, r4, r0 /* sets the desired bits */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR4 /* register number 0xfc */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0x0083
and r4, r4, r0
#ifdef MPC107_66 /* 66 MHz */
lis r0, 0x2000 /* PRETOACT = 2 clocks */
oris r0, r0, 0x0462 /* ACTOPRE = 4 clocks */
/* Enable Inline ECC/Parity */
/* Enable Extended ROM (RCS2/RCS3) */
/* BSTOPRE_U = 0 (see A/N) */
/* RCS1 is 8-bits */
ori r0, r0, 0x2239 /* CAS Latency (CL=2) (see RDLAT) */
/* Sequential wrap/4-beat burst */
/* ACTORW = 3 clocks */
/* BSTOPRE_L = 9 (see A/N) */
#else /* 100 MHz */
lis r0, 0x2000 /* PRETOACT = 2 clocks */
oris r0, r0, 0x0562 /* ACTOPRE = 5 clocks */
/* Enable Inline ECC/Parity */
/* Enable Extended ROM (RCS2/RCS3) */
/* BSTOPRE_U = 0 (see A/N) */
/* RCS1 is 8-bits */
ori r0, r0, 0x3239 /* CAS Latency (CL=3) (see RDLAT) */
/* Sequential wrap/4-beat burst */
/* ACTORW = 3 clocks */
/* BSTOPRE_L = 9 (see A/N) */
#endif
or r4, r4, r0 /* sets the desired bits */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
/* Disable all memory banks first */
li r0, 0x0000 /* Disable all 8 banks of DRAM */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MBEN /* register number 0xa0 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
stb r0, 0(r2) /* write mdfd data to CONFIG_DATA */
/* Set starting address, banks 0-3 */
xor r4, r4, r4
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MSAR1 /* register number 0x80 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0x8000
ori r4, r4, 0x0000
#elif SDRAM_SIZE == 128
addis r4, r0, 0x8000
ori r4, r4, 0x8000
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0xc080
ori r4, r4, 0x4000
#endif
stwbrx r4, 0, r2
/* Set starting address, banks 4-7 */
xor r4, r4, r4
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MSAR2 /* register number 0x84 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0xc080
ori r4, r4, 0x4000
#elif SDRAM_SIZE == 128
addis r4, r0, 0x8000
ori r4, r4, 0x8000
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0x0000
ori r4, r4, 0x8000
#endif
stwbrx r4, 0, r2
/* Set extended starting address, banks 0-3 */
lis r3, CHAPARRAL_REG /* Starting address of extended memory is 0 */
ori r3, r3, MPC107_EMSAR1 /* register number 0x88 */
stwbrx r3, 0, r1
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0x0202
ori r4, r4, 0x0100
#elif SDRAM_SIZE == 128
addis r4, r0, 0x0101
ori r4, r4, 0x0000
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0x0000
ori r4, r4, 0x0000
#endif
stwbrx r4, 0, r2
/* Set extended starting address, banks 4-7 */
lis r3, CHAPARRAL_REG /* Starting address of extended memory is 0 */
ori r3, r3, MPC107_EMSAR2 /* register number 0x8c */
stwbrx r3, 0, r1
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0x0303
ori r4, r4, 0x0303
#elif SDRAM_SIZE == 128
addis r4, r0, 0x0303
ori r4, r4, 0x0202
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0x0302
ori r4, r4, 0x0101
#endif
stwbrx r4, 0, r2
/* Set ending address, banks 0-3 */
lis r4, 0
ori r4, r4, 0x003f /* 64 MB */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MEAR1 /* register number 0x90 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0xff7f
ori r4, r4, 0xffff
#elif SDRAM_SIZE == 128
addis r4, r0, 0xff7f
ori r4, r4, 0xff7f
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0xffbf
ori r4, r4, 0x7f3f
#endif
stwbrx r4, 0, r2
/* Set ending address, banks 4-7 */
xor r4, r4, r4
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MEAR2 /* register number 0x94 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0xffbf
ori r4, r4, 0x7f3f
#elif SDRAM_SIZE == 128
addis r4, r0, 0xff7f
ori r4, r4, 0xff7f
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0xffff
ori r4, r4, 0xff7f
#endif
stwbrx r4, 0, r2
/* Set extended ending address, banks 0-3 */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_EMEAR1 /* register number 98 */
stwbrx r3, 0, r1
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0x0202
ori r4, r4, 0x0100
#elif SDRAM_SIZE == 128
addis r4, r0, 0x0101
ori r4, r4, 0x0000
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0x0000
ori r4, r4, 0x0000
#endif
stwbrx r4, 0, r2
/* Set extended ending address, banks 4-7 */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_EMEAR2 /* register number 9c */
stwbrx r3, 0, r1
isync
#if SDRAM_SIZE >= 256
addis r4, r0, 0x0303
ori r4, r4, 0x0303
#elif SDRAM_SIZE == 128
addis r4, r0, 0x0303
ori r4, r4, 0x0202
#else /* default: SDRAM_SIZE == 64 */
addis r4, r0, 0x0302
ori r4, r4, 0x0101
#endif
stwbrx r4, 0, r2
/* Set memory bank enable */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MBEN /* register number 0xa0 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
li r4, 0x01 /* Enable bank 0 */
#if SDRAM_SIZE >= 512
ori r4, r4, 0x02 /* Enable bank 1 */
#endif
stb r4, 0(r2) /* Enable bank(s) of memory */
/* Set memory page mode */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, REG_BASE(MPC107_MPMR) /* register number 0xa3 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
#ifdef MPC107_66 /* 66 MHz */
li r4, 0x55 /* ( 6600 - 1112 - 2) / 64 = 85 = 0x55 */
#else /* 100 MHz */
li r4, 0x8A /* (10000 - 1112 - 2) / 64 = 138 = 0x8A */
#endif
stb r4, REG_OFF(MPC107_MPMR)(r2) /* Set Memory Page Mode */
/*
* Output driver control register
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, REG_BASE(MPC107_ODCR) /* register number 73 */
stwbrx r3, 0, r1
isync
li r0, 0
ori r0, r0, 0x80 /* PCI I/O: 50 ohms (else 25ohm) */
ori r0, r0, 0x40 /* CPU I/O: 40 ohms (else 20ohm) */
/* ori r0, r0, 0x30 */ /* Mem I/O: 8 ohms */
ori r0, r0, 0x20 /* Mem I/O: 13 ohms */
/* ori r0, r0, 0x10 */ /* Mem I/O: 20 ohms */
/* ori r0, r0, 0x00 */ /* Mem I/O: 40 ohms */
/* ori r0, r0, 0x0c */ /* PCIClk: 8 ohms */
ori r0, r0, 0x08 /* PCIClk: 13 ohms */
/* ori r0, r0, 0x04 */ /* PCIClk: 20 ohms */
/* ori r0, r0, 0x00 */ /* PCIClk: 40 ohms */
/* ori r0, r0, 0x03 */ /* MemClk: 8 ohms */
ori r0, r0, 0x02 /* MemClk: 13 ohms */
/* ori r0, r0, 0x01 */ /* MemClk: 20 ohms */
/* ori r0, r0, 0x00 */ /* MemClk: 40 ohms */
stb r0, REG_OFF(MPC107_ODCR)(r2) /* New settings. */
sync
isync
/*
* Clock driver control register
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, REG_BASE(MPC107_CDCR) /* register number 0x74 */
stwbrx r3, 0, r1
isync
lis r0, 0
/* ori r0, r0, 0x8000 */ /* PCI_SYNC_OUT: disabled */
/* ori r0, r0, 0x7c00 */ /* PCI_CLK(0:4): disabled */
/* ori r0, r0, 0x0300 */ /* CPU_CLK(0:1): 8 ohms */
ori r0, r0, 0x0200 /* CPU_CLK(0:1): 13 ohms */
/* ori r0, r0, 0x0100 */ /* CPU_CLK(0:1): 20 ohms */
/* ori r0, r0, 0x0000 */ /* CPU_CLK(0:1): 40 ohms */
/* ori r0, r0, 0x0080 */ /* SDRAM_SYNC_OUT: disabled */
/* ori r0, r0, 0x0078 */ /* SDRAM_CLK(0:3): disabled */
/* ori r0, r0, 0x0004 */ /* CPU_CLK0: disabled */
ori r0, r0, 0x0002 /* CPU_CLK1: disabled */
ori r0, r0, 0x0001 /* CPU_CLK2: disabled */
sthbrx r0, REG_OFF(MPC107_CDCR),(r2) /* New settings. */
sync
/*
* Miscellaneeous driver control register
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MDCR /* register number 0x76 */
stwbrx r3, 0, r1
isync
lbz r4, 2(r2) /* load r4 from CONFIG_DATA */
li r0, 0x001f /* bit 4-0 reserved */
and r4, r4, r0
/* ori r4, r4, 0x80 */ /* MCP: 1=open-drain, 0=output */
/* ori r4, r4, 0x40 */ /* SRESET: 1=open-drain, 0=output */
/* ori r4, r4, 0x20 */ /* QACK: 1=high-Z, 0=output */
stb r4, 2(r2) /* New settings. */
sync
/*
DRAM SHOULD NOW BE CONFIGURED AND ENABLED -
MUST WAIT BEFORE ACCESSING
*/
memgo:
li r0, 0x2000
mtctr r0
wait1:
bdnz wait1
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR1 /* register number 0xf0 */
stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0x0008 /* MEMGO=1 */
ori r0, r0, 0x0000
or r4, r4, r0 /* set the MEMGO bit */
stwbrx r4, r0, r2 /* write mdfd data to CONFIG_DATA */
li r0, 0x2000 /* approx decimal 8000 */
mtctr r0
wait2:
bdnz wait2
/*
* Determine and set up final memory configuration.
* VG4 has up to two memory banks.
*/
spd_init:
bl i2c_init
/* get module bank density */
li 3, 0x1f
bl i2c_read
ori r4, r3, 0
cmpwi r4, 255
bne get_banks
xor r19, r19, r19
ori r19, r19, 64
b use_default
get_banks:
/* get number of module banks */
cmpwi r4, 128 /* bug in SPD EEPROM for 512MB */
beq no_bank
li 3, 0x05
bl i2c_read
mullw. r4,r4,r3
no_bank:
mulli r19,r4,4
/* r19 now holds the memory size in MB */
bl memInit2
use_default:
/*
* M1543C southbridge initialization
*/
INIT_M1543C:
/*
* Address definition for programmable chip select (1553, Z8536, Z85230)
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, (PCI_DEV_NO_M1543C << 11)
ori r3, r3, REG_BASE(M1543C_PCSAD) /* register number 0x55 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
li r4, 0x03 /* value 0x00 to register 0x55 */
stb r4, 1(r2) /* write mdfd data to CONFIG_DATA */
li r4, 0x01 /* value 0x01 to register 0x56 */
stb r4, 2(r2) /* write mdfd data to CONFIG_DATA */
li r4, 0x00 /* value 0x00 to register 0x57 */
stb r4, 3(r2) /* write mdfd data to CONFIG_DATA */
/*
* General Purpose Input Definitions
*/
/* Select address of register GPIS (0x59) in M1543C */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, (PCI_DEV_NO_M1543C << 11)
ori r3, r3, REG_BASE(M1543C_GPIS) /* register number 0x59 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lbz r4, REG_OFF(M1543C_GPIS)(r2) /* read data from CONFIG_DATA */
ori r4, r4, 0x09 /* set bits 0 and 3 in register 0x59 */
andi. r4, r4, 0xfb /* reset bit 2 in register 0x59 */
stb r4, REG_OFF(M1543C_GPIS)(r2) /* write mdfd data to CONFIG_DATA */
/*
* General Purpose Output Configuration
*/
/* Select address of register SMIRB (0xC6) in PMU M7101 */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, (PCI_DEV_NO_M1543C_PMU << 11)
ori r3, r3, REG_BASE(M1543C_PMU_SMIRB) /* register number 0xC6 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
/* Select GPO[22] on pin OFF_PWR1/GPO[22] */
/* Select GPO[23] on pin OFF_PWR2/GPO[23] */
lbz r4, REG_OFF(M1543C_PMU_SMIRB)(r2) /* read from CONFIG_DATA */
ori r4, r4, 0x06 /* set bits to select GPO in register 0xC6 */
stb r4, REG_OFF(M1543C_PMU_SMIRB)(r2) /* write mdfd data to CONFIG_DATA */
/*
* Disable write access for extended flash rom and SPD eeprom
*/
/* Select address of register DOGPOII (0xC3) in PMU M7101 */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, (PCI_DEV_NO_M1543C_PMU << 11)
ori r3, r3, REG_BASE(M1543C_PMU_DOGPOII) /* register number 0xC3 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
/* Flash protection GPO[22]: 1 - write protected, 0 - write enabled */
/* SPD eeprom protection GPO[23]: 1 - write protected, 0 - write enabled */
lbz r4, REG_OFF(M1543C_PMU_DOGPOII)(r2) /* read from CONFIG_DATA */
ori r4, r4, 0x06 /* set bits 2 and 3 of DOGPOII*/
stb r4, REG_OFF(M1543C_PMU_DOGPOII)(r2) /* write mdfd data to CONFIG_DATA */
/*
* Set ISA clock frequency
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, (PCI_DEV_NO_M1543C << 11)
ori r3, r3, REG_BASE(M1543C_ISAC1) /* register number 0x42 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lbz r4, REG_OFF(M1543C_ISAC1)(r2) /* read from CONFIG_DATA */
andi. r4, r4, 0x0007 /* clear ISA Clock SYSCLK Frequency Select (bit 0-2) */
ori r4, r4, 0x0001 /* set clock to PCICLK/2 */
stb r4, REG_OFF(M1543C_ISAC1)(r2) /* write mdfd data to CONFIG_DATA */
#ifndef STANDANLONE_FIRMWARE
/* disable external interrupts (redundant MSR initialization) */
mfmsr r3 /* load msr to parm0 */
INT_MASK(r3, r4) /* mask EE bit */
mtmsr r4 /* LOCK INTERRUPT */
#else
/* Disable address and data translation in MSR */
mfmsr r3
lis r4, 0xffff
ori r4, r4, 0xffcf
and r3, r3, r4
mtmsr r3
isync
/* build new BAT entries */
lis r3, 0xff00 /* block start: ff000000 */
ori r4, r3, 0x0022 /* caching inhibited, read/write */
mtspr IBAT0L, r4
isync
ori r4, r3, 0x01ff /* block length: 16 meg */
mtspr IBAT0U, r4
isync
lis r3, 0xc000 /* block start: c0000000 */
ori r4, r3, 0x0022 /* caching inhibited, read/write */
mtspr DBAT0L, r4
isync
ori r4, r3, 0x1fff /* block length: 256 meg */
mtspr DBAT0U, r4
isync
lis r3, 0x0000 /* block start: 00000000 */
ori r4, r3, 0x0012 /* memory coherence, read/write */
mtspr IBAT1L, r4
isync
mtspr DBAT1L, r4
isync
ori r4, r3, 0x0fff /* block length: 128 meg */
mtspr IBAT1U, r4
isync
mtspr DBAT1U, r4
isync
lis r3, 0x8000 /* block start: 80000000 */
ori r4, r3, 0x0022 /* caching inhibited, read/write */
mtspr IBAT2L, r4
isync
mtspr DBAT2L, r4
isync
ori r4, r3, 0x01ff /* block length: 16 meg */
mtspr IBAT2U, r4
isync
mtspr DBAT2U, r4
isync
/* enable instruction translation in MSR */
isync
mfmsr r3
ori r3, r3, 0x1012
mtmsr r3
#endif
bl sio_init
#if defined (ROM_DEBUG)
bl romDebugInit
#endif
#if defined(INCLUDE_DRBIT)
slwi r2, r19, 20 /* r19 contains sdram size in megabytes */
/* r2 contains sdram size in bytes now */
or r5, r12, r12 /* boot type for bitTestAsm */
bl bitTestAsm /* start assembly BIT module */
#else
/* Switch off board LED */
bl board_led_off
#endif /* if defined(INCLUDE_DRBIT) */
#ifdef INCLUDE_ECC
/*
* The purpose of this section is to enable the ECC of the
* DRAM. To do this, it is first necessary to initialize the
* ECC check bits. The ECC check bits are initialized by
* initializing all of DRAM.
*
* input:
* r19 = Total DRAM size (in Mbytes)
* notes:
* 1. must run as a supervisor function
* 2. interrupts must be masked
* 3. address translation (MMU) disabled
* 4. assumes ECC Control register is in a power-up state
*
* registers used:
* r3, r4. r14, r15, r16, r17
*/
.chaparral_scrub:
/* setup local variables */
addi r15, r0, 0 /* load starting addr - always zero */
slwi r16, r19, 20 /* r19 contains sdram size in megabytes */
/* r16 contains sdram size in bytes now */
#ifndef ECC_TEST
srwi r16, r16, 3 /* calculate number of doubles */
#else
srwi r16, r16, 4 /* calculate number of doubles / 2 */
#endif /* ECC_TEST */
/* Make sure FPU is enabled; it's needed for DRAM loads and stores */
mfmsr r14 /* Save current value of MSR in r14 */
addi r4, r0, 0x2000 /* FP bit definition */
or r4, r4, r14
mtmsr r4
isync
/*
* invalidate/enable the processor data cache, one of the assumptions
* is that address translation is disabled, the default caching mode
* is copy-back when address translation is disabled, copy-back mode
* is the recommended caching mode
*/
bl dCacheInval
bl dCacheOn
/*
* Loop through the entire DRAM array and initialize memory. This has
* the side effect of initializing the ECC check bits because they are
* always updated when the DRAM is written.
*
* The data path to DRAM is the size of a cache line (128-bits), this
* is why the data cache is enabled, the initialization of the ECC check
* bits are optimized when a cache line write/flush occurs
*/
#ifdef ECC_TEST
/*
* Excludes 128 KBytes from scrubbing.
* The excluded area starts at half of the memory size.
*/
chaparral_scrub_start:
addi r17, r15,-8 /* starting address - munged */
mtctr r16 /* load number of doubles in counter */
lis r18, 0x1000
chaparral_scrub_iloop:
lfdu 0, 8(r17)
stfd 0, 0(r17)
bdnz chaparral_scrub_iloop /* branch till counter == 0 */
addis r17, r17, 0x2
addi r16, r16,-16384
mtctr r16 /* load number of doubles in counter */
1:
lfdu 0, 8(r17)
stfd 0, 0(r17)
bdnz 1b
#else
chaparral_scrub_start:
addi r17, r15,-8 /* starting address - munged */
mtspr 9, r16 /* load number of doubles in counter */
chaparral_scrub_iloop:
lfdu 0, 8(r17)
stfd 0, 0(r17)
bc 16, 0, chaparral_scrub_iloop /* branch till counter == 0 */
#endif /* ECC_TEST */
eieio
sync
/*
* Flush L1 data cache so that the last segment (data cache size) of
* DRAM is initialized. This is done by flushing 2 x the data cache
* size (32K).
*/
lis r16, HI(0x10000/_CACHE_ALIGN_SIZE) /* load number of cache */
ori r16, r16, (0x10000/_CACHE_ALIGN_SIZE) /* lines in 64KB */
mtspr 9, r16 /* move to counter */
chaparral_scrub_floop:
dcbf r0, r17 /* flush line */
addi r17, r17, -(_CACHE_ALIGN_SIZE) /* next (previous) line */
bc 16, 0, chaparral_scrub_floop /* branch till counter == 0 */
eieio
sync
/* disable the data cache */
bl dCacheInval
bl dCacheOff
/* Restore original value of MSR */
mtmsr r14
isync
#endif /* INCLUDE_ECC */
/* initialize the stack pointer */
lis sp, HIADJ(STACK_ADRS)
addi sp, sp, LO(STACK_ADRS)
#if FALSE /* XXX TPR SDA not supported yet */
/* initialize r2 and r13 according to EABI standard */
lis r2, HIADJ(_SDA2_BASE_)
addi r2, r2, LO(_SDA2_BASE_)
lis r13, HIADJ(_SDA_BASE_)
addi r13, r13, LO(_SDA_BASE_)
#endif /* FALSE */
/* go to C entry point */
or r3, r12, r12 /* boot type for romStart() */
addi sp, sp, -FRAMEBASESZ /* get frame stack */
lis r6, HIADJ(romStart)
addi r6, r6, LO(romStart)
lis r7, HIADJ(romInit)
addi r7, r7, LO(romInit)
lis r8, HIADJ(ROM_TEXT_ADRS)
addi r8, r8, LO(ROM_TEXT_ADRS)
sub r6, r6, r7
add r6, r6, r8
mtlr r6
blr
/*
routine: pciReadConfig
this function reads a register from a PCI device via configuration cycle
call:
pciConfigRead
return:
register value in r3
*/
pciConfigRead:
/* Prepare bus number */
rlwinm r3, r3, 16, 8, 15
/* Prepare device number */
rlwinm r4, r4, 11, 16, 20
/* Prepare function number */
rlwinm r5, r5, 8, 21, 23
/* Prepare register number */
rlwinm r10, r6, 0, 24, 29
/* Build configuration address in r9 */
lis r9, CHAPARRAL_REG /* r0 = 0x8000 0000 BASE_ADDRESS */
or r9, r9, r3 /* bus number in bit 8-15 */
or r9, r9, r4 /* device number in bit 16-20 */
or r9, r9, r5 /* function number in bit 21-23 */
or r9, r9, r10 /* register number in bit 24-29 */
stwbrx r9, r0, r1 /* write this value to CONFIG_ADDR */
isync
/* Register offset in r6 */
andi. r6, r6, 0x0003 /* valid register offset: 0, 1, 2, 3 */
/* Evaluate data size in r7 */
andi. r7, r7, 0x0007 /* valid data sizes: 1, 2, 4 */
cmpli 0, 0, r7, 0x0001 /* test for byte access */
beq pci_read_byte
cmpli 0, 0, r7, 0x0002 /* test for half word (16 bit) access */
beq pci_read_hword
cmpli 0, 0, r7, 0x0004 /* test for word (32 bit) access */
beq pci_read_word
addis r3, r0, 0xffff
ori r3, r0, 0xffff
b pci_read_end
pci_read_byte:
lbzx r3, r6, r2
b pci_read_end
pci_read_hword:
lhbrx r3, r6, r2
b pci_read_end
pci_read_word:
lwbrx r3, r6, r2
b pci_read_end
pci_read_end:
bclr 20,0 /* return to caller */
pciConfigWrite:
/* Prepare bus number */
rlwinm r3, r3, 16, 8, 15
/* Prepare device number */
rlwinm r4, r4, 11, 16, 20
/* Prepare function number */
rlwinm r5, r5, 8, 21, 23
/* Prepare register number */
rlwinm r10, r6, 0, 24, 29
/* Prepare data size */
andi. r7, r7, 0x007
/* Build configuration address in r9 */
lis r9, CHAPARRAL_REG /* r0 = 0x8000 0000 BASE_ADDRESS */
or r9, r9, r3 /* bus number in bit 8-15 */
or r9, r9, r4 /* device number in bit 16-20 */
or r9, r9, r5 /* function number in bit 21-23 */
or r9, r9, r10 /* register number in bit 24-29 */
stwbrx r9, r0, r1 /* write this value to CONFIG_ADDR */
isync
/* Register offset in r6 */
andi. r6, r6, 0x0003 /* valid register offset: 0, 1, 2, 3 */
/* Evaluate data size in r7 */
andi. r7, r7, 0x0007 /* valid data sizes: 1, 2, 4 */
cmpli 0, 0, r7, 0x0001 /* test for byte access */
beq pci_write_byte
cmpli 0, 0, r7, 0x0002 /* test for half word (16 bit) access */
beq pci_write_hword
cmpli 0, 0, r7, 0x0004 /* test for word (32 bit) access */
beq pci_write_word
b pci_write_end
pci_write_byte:
stbx r8, r6, r2
b pci_write_end
pci_write_hword:
sthbrx r8, r6, r2
b pci_write_end
pci_write_word:
stwbrx r8, r6, r2
b pci_write_end
pci_write_end:
bclr 20,0 /* return to caller */
board_led_off:
/* Switch off card fail LED */
lis r9, HI(VG4_PORT_LOCKR)
ori r9, r9, LO(VG4_PORT_LOCKR)
li r11, LOCKR_UNLOCK
stb r11, 0(r9) /* Unlock extended register set on VG4 */
lis r10, HI(VG4_PORT_LEDCR)
ori r10, r10,LO(VG4_PORT_LEDCR)
li r11, LEDCR_LED_OFF
stb r11, 0(r10) /* Switch LED off (register 0x168) */
li r11, LOCKR_LOCK
stb r11, 0(r9) /* Lock extended register set on VG4 */
blr
board_led_on:
/* Switch on card fail LED */
lis r9, HI(VG4_PORT_LOCKR)
ori r9, r9, LO(VG4_PORT_LOCKR)
li r11, LOCKR_UNLOCK
stb r11, 0(r9) /* Unlock extended register set on VG4 */
lis r10, HI(VG4_PORT_LEDCR)
ori r10, r10,LO(VG4_PORT_LEDCR)
li r11, LEDCR_LED_ON
stb r11, 0(r10) /* Switch LED on (register 0x168) */
li r11, LOCKR_LOCK
stb r11, 0(r9) /* Lock extended register set on VG4 */
blr
wd_off:
/* Switch off watchdog */
lis r9, HI(VG4_PORT_LOCKR)
ori r9, r9, LO(VG4_PORT_LOCKR)
li r11, LOCKR_UNLOCK
stb r11, 0(r9) /* Unlock extended register set on VG4 */
lis r10, HI(VG4_PORT_WCR)
ori r10, r10,LO(VG4_PORT_WCR)
li r11, WCR_WD_OFF
stb r11, 0(r10) /* Switch watchdog off (register 0x160) */
li r11, LOCKR_LOCK
stb r11, 0(r9) /* Lock extended register set on VG4 again */
blr
wd_on:
/* Switch on watchdog */
lis r9, HI(VG4_PORT_LOCKR)
ori r9, r9, LO(VG4_PORT_LOCKR)
li r11, LOCKR_UNLOCK
stb r11, 0(r9) /* Unlock extended register set on VG4 */
lis r10, HI(VG4_PORT_WCR)
ori r10, r10,LO(VG4_PORT_WCR)
li r11, WCR_WD_ON
stb r11, 0(r10) /* Switch watchdog on (register 0x160) */
li r11, LOCKR_LOCK
stb r11, 0(r9) /* Lock extended register set on VG4 again */
blr
/*
;
; This function initializes the superio chip to a functional
; state.
;
; Upon completion, SIO resource registers are mapped as follows:
; Resource Enabled Address
; FDC Yes PRI 3F0-3F7
; IDE No
; UART1 Yes COM1 3F8-3FF
; UART2 Yes COM2 2F8-2FF
; ||PORT Yes LPT1 3BC-3BE
; KBC Yes 060, 064
;
;
*/
sio_init:
mflr r13 /* save link register */
/*
* Get base addr of ISA I/O space
*/
lis r6, HI(CPU_PCI_ISA_IO_ADRS)
ori r6, r6,LO(CPU_PCI_ISA_IO_ADRS)
addi r6, r6, M1543C_SIO_CNF_PORT /* add offset to base */
or r3, r6, r6 /* make a copy */
/*
* Enter configuration mode
*/
addi r4, r0, 0x51
stb r4, 0(r3) /* write config port with configuration key */
isync
addi r4, r0, 0x23
stb r4, 0(r3) /* write config port with configuration key */
isync
bl check_config_mode
/*
* Disable all Super I/O Devices
*/
/*
* FDC (LUN 0x0)
*/
addi r4, r0, M1543C_SIO_LUN_FDC /* select FDC LUN */
bl sio_disable
/*
* LPT (LUN 0x3)
*/
addi r4, r0, M1543C_SIO_LUN_LPT /* select LPT LUN */
bl sio_disable
/*
* COM1 (LUN 0x4)
*/
addi r4, r0, M1543C_SIO_LUN_COM1 /* select COM1 LUN */
bl sio_disable
/*
* COM2 (LUN 0x5)
*/
addi r4, r0, M1543C_SIO_LUN_COM2 /* select COM2 LUN */
bl sio_disable
/*
* KBC (LUN 0x7)
*/
addi r4, r0, M1543C_SIO_LUN_KBC /* select keyboard LUN */
bl sio_disable
/*
* UART3 (LUN 0xb)
*/
addi r4, r0, M1543C_SIO_LUN_UART3 /* select UART3 LUN */
bl sio_disable
/*
* HOTKEY (LUN 0xb)
*/
addi r4, r0, M1543C_SIO_LUN_HOTK /* select HOTKEY LUN */
bl sio_disable
b sio_dev_init
sio_soft_reset:
/*
* Soft reset of the configuration registers
*/
addi r4, r0, M1543C_SIO_RESET /* reset super i/o */
addi r5, r0, 0x01
bl sio_bw
li r0, 0x4000
mtctr r0
wait_sio:
bdnz wait_sio
sio_dev_init:
/*
* Configure the desired Super I/O Devices
*/
/*
* FDC (LUN 0x0)
*/
addi r4, r0, M1543C_SIO_LUN_IDX /* select FDC LUN */
addi r5, r0, M1543C_SIO_LUN_FDC
bl sio_bw
addi r4, r0, M1543C_SIO_HIAR /* initialize FDC address */
addi r5, r0, HI_ADR(M1543C_FDC_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_LOAR
addi r5, r0, LO_ADR(M1543C_FDC_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_IRQR /* initialize FDC (irq 5) */
addi r5, r0, M1543C_FDC_IRQ
bl sio_bw
addi r4, r0, M1543C_SIO_DMAR /* initialize FDC DMA (channel 2) */
addi r5, r0, M1543C_FDC_DMA
bl sio_bw
addi r4, r0, M1543C_SIO_CNFR /* initialize FDC configuration: PS2 mode */
addi r5, r0, 0x88
bl sio_bw
addi r4, r0, M1543C_SIO_ENR /* enable FDC */
addi r5, r0, M1543C_SIO_LUN_ENABLE
bl sio_bw
/*
* LPT (LUN 0x3)
*/
addi r4, r0, M1543C_SIO_LUN_IDX /* select LPT LUN */
addi r5, r0, M1543C_SIO_LUN_LPT
bl sio_bw
addi r4, r0, M1543C_SIO_HIAR /* initialize LPT address (0x3bc) */
addi r5, r0, HI_ADR(M1543C_LPT_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_LOAR
addi r5, r0, LO_ADR(M1543C_LPT_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_IRQR /* initialize LPT irq (7) */
addi r5, r0, M1543C_LPT_IRQ
bl sio_bw
addi r4, r0, M1543C_SIO_DMAR /* initialize LPT DMA channel 3 */
addi r5, r0, M1543C_LPT_DMA
bl sio_bw
addi r4, r0, M1543C_SIO_CNFR /* initialize LPT default configuration: IRQ active low, ECP fifi treshold 0001, SPP mode*/
addi r5, r0, 0x8C
bl sio_bw
addi r4, r0, M1543C_SIO_CNF2R /* initialize LPT default configuration: ext mode, 12MHz clock, no EPP timeout interrupt, burtst mode DMAin ECP */
addi r5, r0, 0x85
bl sio_bw
addi r4, r0, M1543C_SIO_ENR /* enable LPT */
addi r5, r0, M1543C_SIO_LUN_ENABLE
bl sio_bw
/*
* COM1 (LUN 0x4)
*/
addi r4, r0, M1543C_SIO_LUN_IDX /* select COM1 LUN */
addi r5, r0, M1543C_SIO_LUN_COM1
bl sio_bw
addi r4, r0, M1543C_SIO_HIAR /* initialize COM1 address (0x3f8) */
addi r5, r0, HI_ADR(M1543C_COM1_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_LOAR
addi r5, r0, LO_ADR(M1543C_COM1_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_IRQR /* initialize COM1 irq (4) */
addi r5, r0, M1543C_COM1_IRQ
bl sio_bw
addi r4, r0, M1543C_SIO_CNFR /* initialize COM1 default configuration: normal clock source, high speed mode disabled, midi disabled */
addi r5, r0, 0x00
bl sio_bw
addi r4, r0, M1543C_SIO_ENR /* enable COM1 */
addi r5, r0, M1543C_SIO_LUN_ENABLE
bl sio_bw
/*
* COM2 (LUN 0x5)
*/
addi r4, r0, M1543C_SIO_LUN_IDX /* select COM2 LUN */
addi r5, r0, M1543C_SIO_LUN_COM2
bl sio_bw
addi r4, r0, M1543C_SIO_HIAR /* initialize COM2 address (0x2f8) */
addi r5, r0, HI_ADR(M1543C_COM2_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_LOAR
addi r5, r0, LO_ADR(M1543C_COM2_IO_ADRS)
bl sio_bw
addi r4, r0, M1543C_SIO_IRQR /* initialize COM1 irq (3) */
addi r5, r0, M1543C_COM2_IRQ
bl sio_bw
addi r4, r0, M1543C_SIO_ENR /* enable COM2 */
addi r5, r0, M1543C_SIO_LUN_ENABLE
bl sio_bw
/*
* KBC (LUN 0x7)
*/
addi r4, r0, M1543C_SIO_LUN_IDX /* select keyboard LUN */
addi r5, r0, M1543C_SIO_LUN_KBC
bl sio_bw
addi r4, r0, M1543C_SIO_IRQR /* initialize keyboard irq (1) */
addi r5, r0, M1543C_KBC_IRQ
bl sio_bw
addi r4, r0, M1543C_SIO_ENR /* enable keyboard */
addi r5, r0, M1543C_SIO_LUN_ENABLE
bl sio_bw
/*
* Enable all desired Super I/O Devices
*/
/*
* FDC (LUN 0x0)
*/
addi r4, r0, M1543C_SIO_LUN_FDC /* select FDC LUN */
bl sio_enable
/*
* LPT (LUN 0x3)
*/
addi r4, r0, M1543C_SIO_LUN_LPT /* select LPT LUN */
bl sio_enable
/*
* COM1 (LUN 0x4)
*/
addi r4, r0, M1543C_SIO_LUN_COM1 /* select COM1 LUN */
bl sio_enable
/*
* COM2 (LUN 0x5)
*/
addi r4, r0, M1543C_SIO_LUN_COM2 /* select COM2 LUN */
bl sio_enable
/*
* KBC (LUN 0x7)
*/
addi r4, r0, M1543C_SIO_LUN_KBC /* select keyboard LUN */
bl sio_enable
/*
* Exit configuration mode
*/
addi r4, r0, 0xbb
stb r4, 0(r3) /* write config port with exit key */
isync
mtlr r13 /* restore link register */
blr
/*
; routine: sio_enable
; this function enables one device of the SIO chip
; call:
; sio_enable(r3=sioaddr, r4=device LUN)
; return:
; none
*/
sio_enable:
mflr r14 /* save link register */
or r5, r4, r4 /* copy device LUN from r4 to r5 */
addi r4, r0, M1543C_SIO_LUN_IDX /* select index register */
bl sio_bw
addi r4, r0, M1543C_SIO_ENR /* enable device */
addi r5, r0, M1543C_SIO_LUN_ENABLE
bl sio_bw
mtlr r14 /* restore link register */
blr
/*
; routine: sio_disable
; this function disables one device of the SIO chip
; call:
; sio_disable(r3=sioaddr, r4=device LUN)
; return:
; none
*/
sio_disable:
mflr r14 /* save link register */
or r5, r4, r4 /* copy device LUN from r4 to r5 */
addi r4, r0, M1543C_SIO_LUN_IDX /* select index register */
bl sio_bw
addi r4, r0, M1543C_SIO_ENR /* disable device */
addi r5, r0, M1543C_SIO_LUN_DISABLE
bl sio_bw
mtlr r14 /* restore link register */
blr
/*
; routine: sio_bw
; this function writes a register to the SIO chip
; call:
; sio_bw(sioaddr, regnum, value)
; return:
; none
*/
sio_bw:
stb r4, 0(r3) /* write register offset to index port */
eieio
isync
stb r5, 1(r3) /* write value to data port */
eieio
isync
bclr 20,0 /* return to caller */
/*
; routine: sio_br
; this function reads a register from the SIO chip
; call:
; sioInit(sioaddr, regnum)
; return:
; register value
*/
sio_br:
stb r4, 0(r3) /* write index register with register offset */
eieio
isync
lbz r3, 1(r3) /* retrieve specified reg offset contents */
eieio
isync
bclr 20, 0 /* return to caller */
check_config_mode:
mflr r14 /* save link register */
mr r3, r6 /* r6 contains config port fo super i/o */
addi r4, r0, 0x20 /* read device identification registers 0x20 */
bl sio_br
cmpli 0, 0, r3, 0x43 /* compare with ALI defined value */
bne error_loop
mr r3, r6 /* r6 contains config port fo super i/o */
addi r4, r0, 0x21 /* read device identification registers 0x21 */
bl sio_br
cmpli 0, 0, r3, 0x15 /* compare with ALI defined value */
bne error_loop
mr r3, r6 /* r6 contains config port fo super i/o */
mtlr r14 /* restore link register */
blr /* return to calling function */
error_loop:
bl board_led_on
lis r0, 0x400
mtctr r0
bdnz .
bl board_led_off
mtctr r0
bdnz .
b error_loop
/*
* I2C code for reading out the contents of the SPD eeprom.
* Very rudimentary and not intended to be general purpose!
* Reads one byte at specified offset.
*/
.globl i2c_init
i2c_init:
lis 9, HIADJ(MPC107_I2C_ADR)
addi 10, 9, LO(MPC107_I2C_CCR)
lwbrx 3, 0, 10
andi. 3, 3, ~I2C_CCR_MEN & 0xffff /* Disable */
stwbrx 3, 0, 10
addi 10, 9, LO(MPC107_I2C_FDR)
lwbrx 3, 0, 10
lis 0, 0xffff
ori 0, 0, 0xffc0
and 3, 3, 0
ori 3, 3, 0x31 /* Frequency divider */
stwbrx 3, 0, 10
addi 10, 9, LO(MPC107_I2C_ADR)
lwbrx 3, 0, 10
lis 0, 0xffff
ori 0, 0, 0xffc0
and 3, 3, 0
ori 3, 3, 0x02 /* Set slave address */
stwbrx 3, 0, 10
addi 10, 9, LO(MPC107_I2C_CCR)
lwbrx 3, 0, 10
ori 3, 3, 0x80 /* Master enable */
stwbrx 3, 0, 10
blr
/**/
/* 3 = offs */
.globl i2c_read
i2c_read:
lis 9, HIADJ(MPC107_I2C_ADR)
addi 10, 9, LO(MPC107_I2C_CSR)
li 0, 0x0
stwbrx 0, 0, 10 /* Clear status */
IORDER
addi 10, 9, LO(MPC107_I2C_CCR)
li 0, I2C_CCR_MEN|I2C_CCR_MSTA|I2C_CCR_MTX
stwbrx 0, 0, 10 /* Startup! */
IORDER
addi 10, 9, LO(MPC107_I2C_CDR)
li 0, 0xa0 /* Write access + slave addr 0x50 */
stwbrx 0, 0, 10
IORDER
1:
addi 10, 9, LO(MPC107_I2C_CSR)
lwbrx 0, 0, 10 /* Read status */
andi. 0, 0, I2C_CSR_MIF /* Check interrupt MSTA */
beq 1b /* 0 == Nothing yet */
li 0, 0x0
stwbrx 0, 0, 10 /* Clear status */
IORDER
addi 10, 9, LO(MPC107_I2C_CDR)
stwbrx 3, 0, 10 /* Output offset */
IORDER
2:
addi 10, 9, LO(MPC107_I2C_CSR)
lwbrx 0, 0, 10 /* Read status */
andi. 3, 0, I2C_CSR_MIF /* Check interrupt MSTA */
beq 2b /* 0 == Nothing yet */
li 0, 0x0
stwbrx 0, 0, 10 /* Clear status */
IORDER
addi 10, 9, LO(MPC107_I2C_CCR)
lwbrx 0, 0, 10
ori 0, 0, I2C_CCR_RSTA
stwbrx 0, 0, 10 /* Restart */
IORDER
addi 10, 9, LO(MPC107_I2C_CDR)
li 0, 0xa1 /* Read access + slave addr 0x50 */
stwbrx 0, 0, 10
IORDER
3:
addi 10, 9, LO(MPC107_I2C_CSR)
lwbrx 0, 0, 10 /* Read status */
andi. 0, 0, I2C_CSR_MIF /* Check interrupt MSTA */
beq 3b /* 0 == Nothing yet */
li 0, 0x0
stwbrx 0, 0, 10 /* Clear status */
IORDER
addi 10, 9, LO(MPC107_I2C_CCR)
lwbrx 0, 0, 10
andi. 0, 0, ~(I2C_CCR_MTX|I2C_CCR_RSTA) & 0xffff
ori 0, 0, I2C_CCR_TXAK
stwbrx 0, 0, 10
IORDER
addi 10, 9, LO(MPC107_I2C_CDR)
lwbrx 0, 0, 10
IORDER
4:
addi 10, 9, LO(MPC107_I2C_CSR)
lwbrx 0, 0, 10 /* Read status */
andi. 0, 0, I2C_CSR_MIF /* Check interrupt MSTA */
beq 4b /* 0 == Nothing yet */
addi 10, 9, LO(MPC107_I2C_CCR)
lwbrx 0, 0, 10
andi. 0, 0, ~I2C_CCR_MSTA & 0xffff
stwbrx 0, 0, 10
IORDER
addi 10, 9, LO(MPC107_I2C_CDR)
lwbrx 3, 0, 10
lis 0, 16
mtctr 0
1:
bdnz 1b /* Delay to settle */
blr
/*
* MemInit2
*/
memInit2:
#if defined (ADRS_MAP_PREP)
/* reload r1 and r2 for PReP PCI configuration access */
lis r1, HI(MPC107_CFG_ADDR_PREP) /* r1 = PCI config address register */
ori r1, r1, LO(MPC107_CFG_ADDR_PREP)
lis r2, HI(MPC107_CFG_DATA_PREP) /* r2 = PCI config data register */
ori r2, r2, LO(MPC107_CFG_DATA_PREP)
#else
/* reload r1 and r2 for CHRP PCI configuration access */
lis r1, HI(MPC107_CFG_ADDR_CHRP) /* r1 = PCI config address register */
ori r1, r1, LO(MPC107_CFG_ADDR_CHRP)
lis r2, HI(MPC107_CFG_DATA_CHRP) /* r2 = PCI config data register */
ori r2, r2, LO(MPC107_CFG_DATA_CHRP)
#endif /* defined (ADRS_MAP_PREP) */
/*
* Make sure we're disabling RAM interface logic
* by clearing MEMGO bit. Needed for warm boots
*/
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR1 /* register number 0xf0 */
stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0xfff7 /* MEMGO=0 */
ori r0, r0, 0xffff
and r4, r4, r0 /* Clear MEMGO bit */
stwbrx r4, r0, r2 /* write modified data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3,MPC107_MCCR1 /* register number 0xf0 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
/* REDUCE WAIT STATES FOR ROM ACCESSES */
#ifdef MPC107_66 /* 66 MHz */
lis r0, 0x0480 /* ROMNAL: 0 , ROMFAL: 9*/
#else /* 100 MHz */
lis r0, 0x0780 /* ROMNAL: 0 , ROMFAL: 15*/
#endif
cmpwi r19,512
bne m1_256
ori r0, r0, 0x000a /* 2 banks with 13 row bits (SDRAM) */
b m1_done
m1_256:
cmpwi r19,256
bne m1_128
ori r0, r0, 0x0002 /* 1 bank with 13 row bits (SDRAM) */
b m1_done
/* 64, 128 MB */
m1_128:
ori r0, r0, 0x0000 /* 1 bank with 12 row bits (SDRAM) */
m1_done:
and r4, r4, r0 /* clears the desired bits */
or r4, r4, r0 /* sets the desired bits */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new register number */
ori r3, r3, MPC107_MCCR2 /* register number 0xf4 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lis r4, 0x0000
#ifdef MPC107_66 /* 66 MHz */
oris r4, r4, 0x6000 /* TS_WAIT_TIMER = 4 clocks (for 55 ns) */
#else /* 100 MHz */
oris r4, r4, 0xa000 /* TS_WAIT_TIMER = 6 clocks (for 55 ns) */
#endif
oris r4, r4, 0x0008 /* SDRAM inline writes */
oris r4, r4, 0x0004 /* SDRAM inline reads */
#ifdef MPC107_66 /* 66 MHz */
ori r4, r4, 0x0920 /* Refresh: 66 MHz mem bus */
#else /* 100 MHz */ /* 649 - 65 (10% security) = 584 */
ori r4, r4, 0x0f30 /* Refresh: 100 MHz mem bus */
#endif /* 1080 - 108 (10% security) = 972 */
/* ori r4, r4, 0x0002 */ /* Reserve a page */
ori r4, r4, 0x0001 /* RWM parity */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR3 /* register number 0xf8 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0x000f /* Bits 31 .. 20 used for SDRAM */
ori r0, r0, 0xffff
and r4, r4, r0
lis r0, 0x7000 /* BSTOPRE_M = 7 (see A/N) */
#ifdef MPC107_66 /* 66 MHz */
oris r0, r0, 0x0540 /* REFREC = 5 clocks */
/* RDLAT = 4 clocks (CAS latency + 1 for registered buffer mode) */
/* (CAS latency + 2 for in-line buffer mode) */
#else /* 100 MHz */
oris r0, r0, 0x0750 /* REFREC = 7 clocks */
/* RDLAT = 5 clocks (CAS latency + 1 for registered buffer mode) */
/* (CAS latency + 2 for in-line buffer mode) */
#endif
or r4, r4, r0 /* sets the desired bits */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR4 /* register number 0xfc */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, 0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0x0083
and r4, r4, r0
#ifdef MPC107_66 /* 66 MHz */
lis r0, 0x2000 /* PRETOACT = 2 clocks */
oris r0, r0, 0x0462 /* ACTOPRE = 4 clocks */
/* Enable Inline ECC/Parity */
/* Enable Extended ROM (RCS2/RCS3) */
/* BSTOPRE_U = 0 (see A/N) */
/* RCS1 is 8-bits */
ori r0, r0, 0x2239 /* CAS Latency (CL=2) (see RDLAT) */
/* Sequential wrap/4-beat burst */
/* ACTORW = 3 clocks */
/* BSTOPRE_L = 9 (see A/N) */
#else /* 100 MHz */
lis r0, 0x2000 /* PRETOACT = 2 clocks */
oris r0, r0, 0x0562 /* ACTOPRE = 5 clocks */
/* Enable Inline ECC/Parity */
/* Enable Extended ROM (RCS2/RCS3) */
/* BSTOPRE_U = 0 (see A/N) */
/* RCS1 is 8-bits */
ori r0, r0, 0x3239 /* CAS Latency (CL=3) (see RDLAT) */
/* Sequential wrap/4-beat burst */
/* ACTORW = 3 clocks */
/* BSTOPRE_L = 9 (see A/N) */
#endif
or r4, r4, r0 /* sets the desired bits */
stwbrx r4, 0, r2 /* write mdfd data to CONFIG_DATA */
/* Disable all memory banks first */
li r0, 0x0000 /* Disable all 8 banks of DRAM */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MBEN /* register number 0xa0 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
stb r0, 0(r2) /* write mdfd data to CONFIG_DATA */
/* Set starting address, banks 0-3 */
xor r4, r4, r4
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MSAR1 /* register number 0x80 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
/* if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m2_128
addis r4, r0, 0x8000
ori r4, r4, 0x0000
b m2_done
/* if SDRAM_SIZE == 128 */
m2_128:
cmpwi r19,128
bne m2_64
addis r4, r0, 0x8000
ori r4, r4, 0x8000
b m2_done
/* default: SDRAM_SIZE == 64 */
m2_64:
addis r4, r0, 0xc080
ori r4, r4, 0x4000
m2_done:
stwbrx r4, 0, r2
/* Set starting address, banks 4-7 */
xor r4, r4, r4
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MSAR2 /* register number 0x84 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
/* if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m3_128
addis r4, r0, 0xc080
ori r4, r4, 0x4000
b m3_done
/* elif SDRAM_SIZE == 128 */
m3_128:
cmpwi r19,128
bne m3_64
addis r4, r0, 0x8000
ori r4, r4, 0x8000
b m3_done
/* default: SDRAM_SIZE == 64 */
m3_64:
addis r4, r0, 0x0000
ori r4, r4, 0x8000
m3_done:
stwbrx r4, 0, r2
/* Set extended starting address, banks 0-3 */
lis r3, CHAPARRAL_REG /* Starting address of extended memory is 0 */
ori r3, r3, MPC107_EMSAR1 /* register number 0x88 */
stwbrx r3, 0, r1
isync
/* if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m4_128
addis r4, r0, 0x0202
ori r4, r4, 0x0100
b m4_done
/* elif SDRAM_SIZE == 128 */
m4_128:
cmpwi r19,128
bne m4_64
addis r4, r0, 0x0101
ori r4, r4, 0x0000
b m4_done
/* default: SDRAM_SIZE == 64 */
m4_64:
addis r4, r0, 0x0000
ori r4, r4, 0x0000
m4_done:
stwbrx r4, 0, r2
/* Set extended starting address, banks 4-7 */
lis r3, CHAPARRAL_REG /* Starting address of extended memory is 0 */
ori r3, r3, MPC107_EMSAR2 /* register number 0x8c */
stwbrx r3, 0, r1
isync
/* if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m5_128
addis r4, r0, 0x0303
ori r4, r4, 0x0303
b m5_done
/* elif SDRAM_SIZE == 128 */
m5_128:
cmpwi r19,128
bne m5_64
addis r4, r0, 0x0303
ori r4, r4, 0x0202
b m5_done
/* default: SDRAM_SIZE == 64 */
m5_64:
addis r4, r0, 0x0302
ori r4, r4, 0x0101
m5_done:
stwbrx r4, 0, r2
/* Set ending address, banks 0-3 */
lis r4, 0
ori r4, r4, 0x003f /* 64 MB */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MEAR1 /* register number 0x90 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
/* if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m6_128
addis r4, r0, 0xff7f
ori r4, r4, 0xffff
b m6_done
/* elif SDRAM_SIZE == 128 */
m6_128:
cmpwi r19,128
bne m6_64
addis r4, r0, 0xff7f
ori r4, r4, 0xff7f
b m6_done
/* default: SDRAM_SIZE == 64 */
m6_64:
addis r4, r0, 0xffbf
ori r4, r4, 0x7f3f
m6_done:
stwbrx r4, 0, r2
/* Set ending address, banks 4-7 */
xor r4, r4, r4
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MEAR2 /* register number 0x94 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
/*if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m7_128
addis r4, r0, 0xffbf
ori r4, r4, 0x7f3f
b m7_done
/* elif SDRAM_SIZE == 128 */
m7_128:
cmpwi r19,128
bne m7_64
addis r4, r0, 0xff7f
ori r4, r4, 0xff7f
b m7_done
/* default: SDRAM_SIZE == 64 */
m7_64:
addis r4, r0, 0xffff
ori r4, r4, 0xff7f
m7_done:
stwbrx r4, 0, r2
/* Set extended ending address, banks 0-3 */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_EMEAR1 /* register number 98 */
stwbrx r3, 0, r1
isync
/* if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m8_128
addis r4, r0, 0x0202
ori r4, r4, 0x0100
b m8_done
/* elif SDRAM_SIZE == 128 */
m8_128:
cmpwi r19, 128
bne m8_64
addis r4, r0, 0x0101
ori r4, r4, 0x0000
b m8_done
/* default: SDRAM_SIZE == 64 */
m8_64:
addis r4, r0, 0x0000
ori r4, r4, 0x0000
m8_done:
stwbrx r4, 0, r2
/* Set extended ending address, banks 4-7 */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_EMEAR2 /* register number 9c */
stwbrx r3, 0, r1
isync
/* if SDRAM_SIZE >= 256 */
cmpwi r19,256
blt m9_128
addis r4, r0, 0x0303
ori r4, r4, 0x0303
b m9_end
/* elif SDRAM_SIZE == 128 */
m9_128:
cmpwi r19, 128
bne m9_64
addis r4, r0, 0x0303
ori r4, r4, 0x0202
b m9_end
/* default: SDRAM_SIZE == 64 */
m9_64:
addis r4, r0, 0x0302
ori r4, r4, 0x0101
m9_end:
stwbrx r4, 0, r2
/* Set memory bank enable */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MBEN /* register number 0xa0 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
li r4, 0x01 /* Enable bank 0 */
/* if SDRAM_SIZE >= 512 */
cmpwi r19,512
blt m10_1
ori r4, r4, 0x02 /* Enable bank 1 */
m10_1:
stb r4, 0(r2) /* Enable bank(s) of memory */
/* Set memory page mode */
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, REG_BASE(MPC107_MPMR) /* register number 0xa3 */
stwbrx r3, 0, r1 /* write this value to CONFIG_ADDR */
isync
#ifdef MPC107_66 /* 66 MHz */
li r4, 0x55 /* ( 6600 - 1112 - 2) / 64 = 85 = 0x55 */
#else /* 100 MHz */
li r4, 0x8A /* (10000 - 1112 - 2) / 64 = 138 = 0x8A */
#endif
stb r4, REG_OFF(MPC107_MPMR)(r2) /* Set Memory Page Mode */
/*
DRAM SHOULD NOW BE CONFIGURED AND ENABLED -
MUST WAIT BEFORE ACCESSING
*/
memgo2:
li r0, 0x2000
mtctr r0
wait3:
bdnz wait3
lis r3, CHAPARRAL_REG /* start building new reg number */
ori r3, r3, MPC107_MCCR1 /* register number 0xf0 */
stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
isync
lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
lis r0, 0x0008 /* MEMGO=1 */
ori r0, r0, 0x0000
or r4, r4, r0 /* set the MEMGO bit */
stwbrx r4, r0, r2 /* write mdfd data to CONFIG_DATA */
li r0, 0x2000 /* approx decimal 8000 */
mtctr r0
wait4:
bdnz wait4
blr
/******************************************************************************
*
* dCacheOn - Turn Data Cache On
*
* void dCacheOn (void)
*/
_dCacheOn:
dCacheOn:
/* Get cpu type */
mfspr r3, PVR
rlwinm r3, r3, 16, 16, 31
cmpli 0, 0, r3, CPU_TYPE_750
bc 12, 2, ccdataon
cmpli 0, 0, r3, CPU_TYPE_7400
bc 12, 2, ccdataon
cmpli 0, 0, r3, CPU_TYPE_7410
bc 12, 2, ccdataon
bclr 0x14, 0x0 /* invalid cpu type */
ccdataon:
mfspr r4, HID0 /* Modify HID0 to enable D cache (DCE) */
ori r4, r4, _PPC_HID0_DCE
sync /* required before changing DCE */
mtspr HID0, r4
bclr 0x14, 0x0 /* return to caller */
/******************************************************************************
*
* dCacheOff - Turn Data Cache Off
*
* void dCacheOff (void)
*/
_dCacheOff:
dCacheOff:
/* Get cpu type */
mfspr r3, PVR
rlwinm r3, r3, 16, 16, 31
cmpli 0, 0, r3, CPU_TYPE_750
bc 12, 2, ccDataOff
cmpli 0, 0, r3, CPU_TYPE_7400
bc 12, 2, ccDataOff
cmpli 0, 0, r3, CPU_TYPE_7410
bc 12, 2, ccDataOff
bclr 0x14, 0x0 /* invalid cpu type */
ccDataOff:
mfspr r4, HID0 /* Modify HID0 to disable D cache (DCE) */
rlwinm r4, r4, 0, _PPC_HID0_BIT_DCE+1, _PPC_HID0_BIT_DCE-1 /* clear DCE */
sync /* required before changing DCE */
mtspr HID0, r4
bclr 0x14, 0x0 /* return to caller */
/******************************************************************************
*
* dCacheInval - Invalidate Data Cache
*
* void dCacheInval (void)
*/
_dCacheInval:
dCacheInval:
/* Get cpu type */
mfspr r3, PVR
rlwinm r3, r3, 16, 16, 31
cmpli 0, 0, r3, CPU_TYPE_750
bc 12, 2, ccDataInvl
cmpli 0, 0, r3, CPU_TYPE_7400
bc 12, 2, ccDataInvl
cmpli 0, 0, r3, CPU_TYPE_7410
bc 12, 2, ccDataInvl
bclr 0x14, 0x0 /* invalid cpu type */
/*
* To invalidate the Data Cache on a 750, it's necessary
* to set the DCFI bit while the Data Cache is enabled (DCE).
*/
ccDataInvl:
addis r3, r0, 0x0000 /* Setup bit pattern for DCFI + DCE */
ori r3, r3, (_PPC_HID0_DCE | _PPC_HID0_DCFI)
mfspr r4, HID0 /* Modify HID0 to SET DCFI + DCE bits */
or r4, r4, r3
sync /* required before changing DCE */
mtspr HID0, r4
andc r4, r4, r3 /* Modify HID0 to CLEAR DCFI + DCE bits */
sync /* required before changing DCE */
mtspr HID0, r4
bclr 0x14, 0x0 /* return to caller */
#if defined(ROM_DEBUG)
#include "rom_debug.s"
#endif