util.c revision 106c88e9
1af9bf370Sbeveloper/*
2af9bf370Sbeveloper * BeOS Driver for Intel ICH AC'97 Link interface
3af9bf370Sbeveloper *
4af9bf370Sbeveloper * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
5af9bf370Sbeveloper *
6af9bf370Sbeveloper * All rights reserved.
7af9bf370Sbeveloper * Redistribution and use in source and binary forms, with or without modification,
8af9bf370Sbeveloper * are permitted provided that the following conditions are met:
9af9bf370Sbeveloper *
10af9bf370Sbeveloper * - Redistributions of source code must retain the above copyright notice,
11af9bf370Sbeveloper *   this list of conditions and the following disclaimer.
12af9bf370Sbeveloper * - Redistributions in binary form must reproduce the above copyright notice,
13af9bf370Sbeveloper *   this list of conditions and the following disclaimer in the documentation
14af9bf370Sbeveloper *   and/or other materials provided with the distribution.
15af9bf370Sbeveloper *
16af9bf370Sbeveloper * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17af9bf370Sbeveloper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18af9bf370Sbeveloper * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19af9bf370Sbeveloper * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20af9bf370Sbeveloper * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21af9bf370Sbeveloper * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22af9bf370Sbeveloper * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23af9bf370Sbeveloper * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24af9bf370Sbeveloper * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25af9bf370Sbeveloper * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26af9bf370Sbeveloper *
27af9bf370Sbeveloper */
28af9bf370Sbeveloper#include <Errors.h>
29af9bf370Sbeveloper#include <OS.h>
30af9bf370Sbeveloper#include <string.h>
31af9bf370Sbeveloper
32af9bf370Sbeveloper//#define DEBUG 2
33af9bf370Sbeveloper
34af9bf370Sbeveloper#include "debug.h"
35af9bf370Sbeveloper#include "util.h"
36af9bf370Sbeveloper
37af9bf370Sbeveloperspinlock slock = 0;
38af9bf370Sbeveloper
39dc03e28fSbeveloperuint32 round_to_pagesize(uint32 size);
40dc03e28fSbeveloper
41dc03e28fSbevelopercpu_status lock(void)
42af9bf370Sbeveloper{
43af9bf370Sbeveloper	cpu_status status = disable_interrupts();
44af9bf370Sbeveloper	acquire_spinlock(&slock);
45af9bf370Sbeveloper	return status;
46af9bf370Sbeveloper}
47af9bf370Sbeveloper
48af9bf370Sbevelopervoid unlock(cpu_status status)
49af9bf370Sbeveloper{
50af9bf370Sbeveloper	release_spinlock(&slock);
51af9bf370Sbeveloper	restore_interrupts(status);
52af9bf370Sbeveloper}
53af9bf370Sbeveloper
54af9bf370Sbeveloperuint32 round_to_pagesize(uint32 size)
55af9bf370Sbeveloper{
56af9bf370Sbeveloper	return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
57af9bf370Sbeveloper}
58af9bf370Sbeveloper
59106c88e9Sbeveloperarea_id alloc_mem(void **log, void **phy, size_t size, const char *name)
60af9bf370Sbeveloper{
61af9bf370Sbeveloper	physical_entry pe;
62af9bf370Sbeveloper	void * logadr;
63af9bf370Sbeveloper	area_id areaid;
64af9bf370Sbeveloper	status_t rv;
65af9bf370Sbeveloper
6615ea765dSbeveloper	LOG(("allocating %d bytes for %s\n",size,name));
67af9bf370Sbeveloper
68af9bf370Sbeveloper	size = round_to_pagesize(size);
69af9bf370Sbeveloper	areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS,size,B_FULL_LOCK | B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
70af9bf370Sbeveloper	if (areaid < B_OK) {
7115ea765dSbeveloper		PRINT(("couldn't allocate area %s\n",name));
72af9bf370Sbeveloper		return B_ERROR;
73af9bf370Sbeveloper	}
74af9bf370Sbeveloper	rv = get_memory_map(logadr,size,&pe,1);
75af9bf370Sbeveloper	if (rv < B_OK) {
76af9bf370Sbeveloper		delete_area(areaid);
7715ea765dSbeveloper		PRINT(("couldn't map %s\n",name));
78af9bf370Sbeveloper		return B_ERROR;
79af9bf370Sbeveloper	}
80af9bf370Sbeveloper	memset(logadr,0,size);
81af9bf370Sbeveloper	if (log)
82af9bf370Sbeveloper		*log = logadr;
83af9bf370Sbeveloper	if (phy)
84af9bf370Sbeveloper		*phy = pe.address;
8515ea765dSbeveloper	LOG(("area = %d, size = %d, log = %#08X, phy = %#08X\n",areaid,size,logadr,pe.address));
86af9bf370Sbeveloper	return areaid;
87af9bf370Sbeveloper}
88af9bf370Sbeveloper
89106c88e9Sbeveloper/* This is not the most advanced method to map physical memory for io access.
90106c88e9Sbeveloper * Perhaps using B_ANY_KERNEL_ADDRESS instead of B_ANY_KERNEL_BLOCK_ADDRESS
91106c88e9Sbeveloper * makes the whole offset calculation and relocation obsolete. But the code
92106c88e9Sbeveloper * below does work, and I can't test if using B_ANY_KERNEL_ADDRESS also works.
93106c88e9Sbeveloper */
94106c88e9Sbeveloperarea_id map_mem(void **log, void *phy, size_t size, const char *name)
95106c88e9Sbeveloper{
96106c88e9Sbeveloper	uint32 offset;
97106c88e9Sbeveloper	void *phyadr;
98106c88e9Sbeveloper	void *mapadr;
99106c88e9Sbeveloper	area_id area;
100106c88e9Sbeveloper
101106c88e9Sbeveloper	LOG(("mapping physical address %p with %#x bytes for %s\n",phy,size,name));
102106c88e9Sbeveloper
103106c88e9Sbeveloper	offset = (uint32)phy & (B_PAGE_SIZE - 1);
104106c88e9Sbeveloper	phyadr = phy - offset;
105106c88e9Sbeveloper	size = round_to_pagesize(size + offset);
106106c88e9Sbeveloper	area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA | B_WRITE_AREA, &mapadr);
107106c88e9Sbeveloper	*log = mapadr + offset;
108106c88e9Sbeveloper
109106c88e9Sbeveloper	LOG(("physical = %p, logical = %p, offset = %#x, phyadr = %p, mapadr = %p, size = %#x, area = %#x\n",
110106c88e9Sbeveloper		phy, *log, offset, phyadr, mapadr, size, area));
111106c88e9Sbeveloper
112106c88e9Sbeveloper	return area;
113106c88e9Sbeveloper}
114