1/*
2 * BeOS Driver for Intel ICH AC'97 Link interface
3 *
4 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
5 *
6 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without modification,
8 * are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 *   this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 *   this list of conditions and the following disclaimer in the documentation
14 *   and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28#include <Errors.h>
29#include <OS.h>
30#include <string.h>
31
32//#define DEBUG 2
33
34#include "debug.h"
35#include "util.h"
36
37spinlock slock = B_SPINLOCK_INITIALIZER;
38
39uint32 round_to_pagesize(uint32 size);
40
41
42cpu_status
43lock(void)
44{
45	cpu_status status = disable_interrupts();
46	acquire_spinlock(&slock);
47	return status;
48}
49
50
51void
52unlock(cpu_status status)
53{
54	release_spinlock(&slock);
55	restore_interrupts(status);
56}
57
58
59uint32
60round_to_pagesize(uint32 size)
61{
62	return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
63}
64
65
66area_id
67alloc_mem(void **phy, void **log, size_t size, const char *name)
68{
69// TODO: phy should be phys_addr_t*!
70	physical_entry pe;
71	void * logadr;
72	area_id areaid;
73	status_t rv;
74
75	LOG(("allocating %d bytes for %s\n",size,name));
76
77	size = round_to_pagesize(size);
78	areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size,
79		B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
80		// TODO: The rest of the code doesn't deal correctly with physical
81		// addresses > 4 GB, so we have to force 32 bit addresses here.
82	if (areaid < B_OK) {
83		PRINT(("couldn't allocate area %s\n",name));
84		return B_ERROR;
85	}
86	rv = get_memory_map(logadr,size,&pe,1);
87	if (rv < B_OK) {
88		delete_area(areaid);
89		PRINT(("couldn't map %s\n",name));
90		return B_ERROR;
91	}
92	memset(logadr,0,size);
93	if (log)
94		*log = logadr;
95	if (phy)
96		*phy = (void*)(addr_t)pe.address;
97	LOG(("area = %d, size = %d, log = %#08X, phy = %#08X\n",areaid,size,logadr,pe.address));
98	return areaid;
99}
100
101