Author: mcayland Date: Sun Feb 16 17:26:19 2014 New Revision: 1261 URL: http://tracker.coreboot.org/trac/openbios/changeset/1261
Log: SPARC32: properly handle SS-5, SS-10 and SS-20 timers/interrupts
SparcStation 5 has 1 timer and 1 per-cpu interrupt controller. SparcStation 10/20 has 4 timers and 4 per-cpu interrupt controllers, independently from the number of CPUs installed.
Timer and interrupt controller properties are set accordingly. This is what Sun's OpenBOOT does and having only 1 timer/interrupt declared on SS5 is necessary for NextSTEP.
Signed-off-by: Olivier Danet odanet@caramail.com Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
Modified: trunk/openbios-devel/arch/sparc32/openbios.c trunk/openbios-devel/drivers/obio.c trunk/openbios-devel/include/drivers/drivers.h
Modified: trunk/openbios-devel/arch/sparc32/openbios.c ============================================================================== --- trunk/openbios-devel/arch/sparc32/openbios.c Fri Feb 7 19:12:41 2014 (r1260) +++ trunk/openbios-devel/arch/sparc32/openbios.c Sun Feb 16 17:26:19 2014 (r1261) @@ -41,6 +41,7 @@ unsigned long aux1_offset, aux2_offset; uint64_t dma_base, esp_base, le_base; uint64_t tcx_base; + int intr_ncpu; int mid_offset; int machine_id_low, machine_id_high; }; @@ -57,6 +58,7 @@ .fd_offset = 0x00400000, .counter_offset = 0x00d00000, .intr_offset = 0x00e00000, + .intr_ncpu = 1, .aux1_offset = 0x00900000, .aux2_offset = 0x00910000, .dma_base = 0x78400000, @@ -66,7 +68,7 @@ .machine_id_low = 32, .machine_id_high = 63, }, - /* SS-10 */ + /* SS-10, SS-20 */ { .iommu_base = 0xfe0000000ULL, .tcx_base = 0xe20000000ULL, @@ -77,6 +79,7 @@ .fd_offset = 0x00700000, // 0xff1700000ULL, .counter_offset = 0x00300000, // 0xff1300000ULL, .intr_offset = 0x00400000, // 0xff1400000ULL, + .intr_ncpu = 4, .aux1_offset = 0x00800000, // 0xff1800000ULL, .aux2_offset = 0x00a01000, // 0xff1a01000ULL, .dma_base = 0xef0400000ULL, @@ -97,6 +100,7 @@ .fd_offset = -1, .counter_offset = 0x00300000, // 0xff1300000ULL, .intr_offset = 0x00400000, // 0xff1400000ULL, + .intr_ncpu = 4, .aux1_offset = 0x00800000, // 0xff1800000ULL, .aux2_offset = 0x00a01000, // 0xff1a01000ULL, XXX should not exist .dma_base = 0xef0081000ULL, @@ -837,7 +841,7 @@ #ifdef CONFIG_DRIVER_OBIO mem_size = fw_cfg_read_i32(FW_CFG_RAM_SIZE); ob_obio_init(hwdef->slavio_base, hwdef->fd_offset, - hwdef->counter_offset, hwdef->intr_offset, + hwdef->counter_offset, hwdef->intr_offset, hwdef->intr_ncpu, hwdef->aux1_offset, hwdef->aux2_offset, mem_size);
Modified: trunk/openbios-devel/drivers/obio.c ============================================================================== --- trunk/openbios-devel/drivers/obio.c Fri Feb 7 19:12:41 2014 (r1260) +++ trunk/openbios-devel/drivers/obio.c Sun Feb 16 17:26:19 2014 (r1261) @@ -26,14 +26,6 @@ #define PROMDEV_SCREEN 0 /* output to screen */ #define PROMDEV_TTYA 1 /* in/out to ttya */
-/* "NCPU" is an historical name that's now a bit of a misnomer. The sun4m - * architecture registers NCPU CPU-specific interrupts along with one - * system-wide interrupt, regardless of the number of actual CPUs installed. - * See the comment on "NCPU" at <http://stuff.mit.edu/afs/athena/astaff/ - * project/opssrc/sys.sunos/sun4m/devaddr.h>. - */ -#define SUN4M_NCPU 4 - /* DECLARE data structures for the nodes. */ DECLARE_UNNAMED_NODE( ob_obio, INSTALL_OPEN, sizeof(int) );
@@ -262,13 +254,13 @@ volatile struct sun4m_timer_regs *counter_regs;
static void -ob_counter_init(uint64_t base, unsigned long offset) +ob_counter_init(uint64_t base, unsigned long offset, int ncpu) { int i;
ob_new_obio_device("counter", NULL);
- for (i = 0; i < SUN4M_NCPU; i++) { + for (i = 0; i < ncpu; i++) { PUSH(0); fword("encode-int"); if (i != 0) fword("encode+"); @@ -300,7 +292,7 @@ counter_regs->cpu_timers[0].l14_timer_limit = 0x9c4000; /* see comment in obio.h */ counter_regs->cpu_timers[0].cntrl = 1;
- for (i = 0; i < SUN4M_NCPU; i++) { + for (i = 0; i < ncpu; i++) { PUSH((unsigned long)&counter_regs->cpu_timers[i]); fword("encode-int"); if (i != 0) @@ -318,13 +310,13 @@ static volatile struct sun4m_intregs *intregs;
static void -ob_interrupt_init(uint64_t base, unsigned long offset) +ob_interrupt_init(uint64_t base, unsigned long offset, int ncpu) { int i;
ob_new_obio_device("interrupt", NULL);
- for (i = 0; i < SUN4M_NCPU; i++) { + for (i = 0; i < ncpu; i++) { PUSH(0); fword("encode-int"); if (i != 0) fword("encode+"); @@ -353,7 +345,7 @@ intregs->clear = ~SUN4M_INT_MASKALL; intregs->cpu_intregs[0].clear = ~0x17fff;
- for (i = 0; i < SUN4M_NCPU; i++) { + for (i = 0; i < ncpu; i++) { PUSH((unsigned long)&intregs->cpu_intregs[i]); fword("encode-int"); if (i != 0) @@ -491,7 +483,7 @@ int ob_obio_init(uint64_t slavio_base, unsigned long fd_offset, unsigned long counter_offset, unsigned long intr_offset, - unsigned long aux1_offset, unsigned long aux2_offset, + int intr_ncpu, unsigned long aux1_offset, unsigned long aux2_offset, unsigned long mem_size) {
@@ -523,9 +515,9 @@ if (aux2_offset != (unsigned long) -1) ob_aux2_reset_init(slavio_base, aux2_offset, AUXIO2_INTR);
- ob_counter_init(slavio_base, counter_offset); + ob_counter_init(slavio_base, counter_offset, intr_ncpu);
- ob_interrupt_init(slavio_base, intr_offset); + ob_interrupt_init(slavio_base, intr_offset, intr_ncpu);
ob_smp_init(mem_size);
Modified: trunk/openbios-devel/include/drivers/drivers.h ============================================================================== --- trunk/openbios-devel/include/drivers/drivers.h Fri Feb 7 19:12:41 2014 (r1260) +++ trunk/openbios-devel/include/drivers/drivers.h Sun Feb 16 17:26:19 2014 (r1261) @@ -63,7 +63,7 @@ /* drivers/obio.c */ int ob_obio_init(uint64_t slavio_base, unsigned long fd_offset, unsigned long counter_offset, unsigned long intr_offset, - unsigned long aux1_offset, unsigned long aux2_offset, + int intr_ncpu, unsigned long aux1_offset, unsigned long aux2_offset, unsigned long mem_size); int start_cpu(unsigned int pc, unsigned int context_ptr, unsigned int context, int cpu);