📄 mv64360.c
字号:
/* * $QNXLicenseC: * Copyright 2007, QNX Software Systems. * * Licensed under the Apache License, Version 2.0 (the "License"). You * may not reproduce, modify or distribute this software except in * compliance with the License. You may obtain a copy of the License * at: http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * * This file may contain contributions from others, either as * contributors under the License or as licensors under other terms. * Please review this entire file for other proprietary rights or license * notices, as well as the QNX Development Suite License Guide at * http://licensing.qnx.com/license-guide/ for other information. * $ */#include "startup.h"#include "mv64360.h"#define MV64360_INTR_CLASS_64260 _NTO_INTR_CLASS_EXTERNAL#define MV64360_NUM_INTR_64260 64#define MV64360_INTR_CLASS_GPP (_NTO_INTR_CLASS_64260+MV64360_NUM_INTR_64260)#define MV64360_NUM_INTR_GPP 32/* * GPP interrupts are 56, 57, 58 and 59 (24-27 of Cause high register) */#define MV64360_INTR_GPP_VEC 56paddr_t mv64360_base = MV64360_BASE_DEFAULT;voidmv64360_set_base_paddr(paddr_t base) { mv64360_base = base;}voidmv64360_config() { uintptr_t mv; mv = startup_io_map(0x1000, mv64360_base); /* * Set up the GPP pins and GPP mask register * MPP27 is for serial port A, MPP 28 is for PCI 0 INT A */ out32(mv+MV64360_GPP_LEVEL, ENDIAN_LE32((1<<27) | (1<<28)) | in32(mv+MV64360_GPP_LEVEL)); out32(mv+MV64360_GPP_CAUSE, 0); /* * Set up the main CPU mask register -- all masked except for GPP's * and doorbell interrupts * CPU 0 gets all interrups, CPU 1 get its dorbell */ out32(mv+MV64360_CPUMASK0_LO, ENDIAN_LE32(0)); out32(mv+MV64360_CPUMASK0_HI, ENDIAN_LE32(1<<28|1<<24|1<<25|1<<26|1<<27)); out32(mv+MV64360_CPUMASK1_LO, ENDIAN_LE32(1<<28)); //out32(mv+MV64360_CPUMASK1_HI, ENDIAN_LE32(1<<28)); /* clear any pending doorbell interrupts, and unmask doorbell interrupt 0 * for each CPU at the source */ out32(mv+MV64360_CPU0_DOORBELL_CLEAR, ENDIAN_LE32(0xff)); out32(mv+MV64360_CPU1_DOORBELL_CLEAR, ENDIAN_LE32(0xff)); out32(mv+MV64360_CPU0_DOORBELL_MASK, ENDIAN_LE32(0x01)); out32(mv+MV64360_CPU1_DOORBELL_MASK, ENDIAN_LE32(0x01)); startup_io_unmap(mv);}#define BAR_ENABLE 0x0278#define PCI0_ACCESS_CONTROL_BASE0_LOW 0x1e00#define PCI0_ACCESS_CONTROL_BASE0_HIGH 0x1e04#define PCI0_ACCESS_CONTROL_SIZE0 0x1e08#define PCI1_ACCESS_CONTROL_BASE0_LOW 0x1e80#define PCI1_ACCESS_CONTROL_BASE0_HIGH 0x1e84#define PCI1_ACCESS_CONTROL_SIZE0 0x1e88#define ACCESS_CONTROL_ENABLE 0x00000001#define ACCESS_CONTROL_SNOOP_WB_REGION 0x00000008#define ACCESS_CONTROL_NO_SWAP 0x00000040#define MEMORY_BASE_ADDRESS 0voidmv64360_init_raminfo() { unsigned size; unsigned disabled; unsigned i; paddr_t base; paddr_t lo = ~(paddr_t)0; paddr_t hi = 0; paddr_t end; uintptr_t mv; //unsigned lo_val; //unsigned hi_val; static const uint16_t scs_off[] = {0x0008, 0x0208, 0x0018, 0x218}; mv = startup_io_map(0x2000, mv64360_base); // on GT64260, we could tell that a window was disabled if the // HI register was greater than the BASE register. On GT64360, // there's a SIZE register instead of a HI register, so this method // no longer applies. Instead, we'll examine the Base Address Enable // register, to see which banks are enabled. Once we have a native // IPL, we can zero the size register for any banks which aren't // enabled, when we do the memory detection. // bits 0 - 3 ==> bank 0 - 3, 0 == enabled, 1 == disabled disabled = inle32(mv + BAR_ENABLE); for(i = 0; i < 4; ++i, disabled >>= 1) { if(!(disabled & 1)) { base = (paddr_t)(inle32(mv + scs_off[i]) & 0xfffff) << 16; size = ((inle32(mv + scs_off[i] + 8) & 0xffff) + 1) << 16; add_ram(base, size); end = base + size - 1; if(base < lo) lo = base; if(end > hi) hi = end; } } size = (unsigned)(hi - lo) & 0xfffff000;/* // hardware snooping across PCI is broken, leave this out for now // set up PCI snoop region across DRAM lo_val = ((unsigned)lo & 0xfffff000) | \ (ACCESS_CONTROL_ENABLE|ACCESS_CONTROL_SNOOP_WB_REGION|ACCESS_CONTROL_NO_SWAP);#if _PADDR_BITS == 64 hi_val = lo >> 32;#else hi_val = 0;#endif lo_val = ENDIAN_LE32(lo_val); hi_val = ENDIAN_LE32(hi_val); size = ENDIAN_LE32(size); out32(mv + PCI0_ACCESS_CONTROL_BASE0_LOW, lo_val); out32(mv + PCI0_ACCESS_CONTROL_BASE0_HIGH, hi_val); out32(mv + PCI0_ACCESS_CONTROL_SIZE0, size); out32(mv + PCI1_ACCESS_CONTROL_BASE0_LOW, lo_val); out32(mv + PCI1_ACCESS_CONTROL_BASE0_HIGH, hi_val); out32(mv + PCI1_ACCESS_CONTROL_SIZE0, size);*/ startup_io_unmap(mv);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -