/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ * */ #include #include /* For isync */ #include #include #include #include #include #include #include #include #include static int dbdma_alloc_index = 0; dbdma_command_t *dbdma_alloc_commands = NULL; void dbdma_start(dbdma_regmap_t *dmap, dbdma_command_t *commands) { unsigned long addr = kvtophys((vm_offset_t) commands); if (addr & 0xf) panic("dbdma_start command structure not 16-byte aligned"); dmap->d_intselect = 0xff; /* Endian magic - clear out interrupts */ DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_CLEAR_CNTRL( (DBDMA_CNTRL_ACTIVE | DBDMA_CNTRL_DEAD | DBDMA_CNTRL_WAKE | DBDMA_CNTRL_FLUSH | DBDMA_CNTRL_PAUSE | DBDMA_CNTRL_RUN ))); eieio(); while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE) eieio(); dmap->d_cmdptrhi = 0; eieio();/* 64-bit not yet */ DBDMA_ST4_ENDIAN(&dmap->d_cmdptrlo, addr); eieio(); DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN)); eieio(); } void dbdma_stop(dbdma_regmap_t *dmap) { DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_RUN) | DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH)); eieio(); while (DBDMA_LD4_ENDIAN(&dmap->d_status) & (DBDMA_CNTRL_ACTIVE|DBDMA_CNTRL_FLUSH)) eieio(); } void dbdma_flush(dbdma_regmap_t *dmap) { DBDMA_ST4_ENDIAN(&dmap->d_control,DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH)); eieio(); while (DBDMA_LD4_ENDIAN(&dmap->d_status) & (DBDMA_CNTRL_FLUSH)) eieio(); } void dbdma_reset(dbdma_regmap_t *dmap) { DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_CLEAR_CNTRL( (DBDMA_CNTRL_ACTIVE | DBDMA_CNTRL_DEAD | DBDMA_CNTRL_WAKE | DBDMA_CNTRL_FLUSH | DBDMA_CNTRL_PAUSE | DBDMA_CNTRL_RUN ))); eieio(); while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_RUN) eieio(); } void dbdma_continue(dbdma_regmap_t *dmap) { DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN|DBDMA_CNTRL_WAKE) | DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_PAUSE|DBDMA_CNTRL_DEAD)); eieio(); } void dbdma_pause(dbdma_regmap_t *dmap) { DBDMA_ST4_ENDIAN(&dmap->d_control,DBDMA_SET_CNTRL(DBDMA_CNTRL_PAUSE)); eieio(); while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE) eieio(); } dbdma_command_t * dbdma_alloc(int count) { dbdma_command_t *dbdmap; /* * For now, we assume that dbdma_alloc() is called only when * the system is bootstrapping, i.e. before the other CPUs * are activated... * If that's not the case, we need to protect the global * variables here. */ assert(cpu_number() == master_cpu); if (dbdma_alloc_index == 0) dbdma_alloc_commands = (dbdma_command_t *) io_map(0, PAGE_SIZE); if ((dbdma_alloc_index+count) >= PAGE_SIZE / sizeof(dbdma_command_t)) panic("Too many dbdma command structures!"); dbdmap = &dbdma_alloc_commands[dbdma_alloc_index]; dbdma_alloc_index += count; return dbdmap; }